Bug 1440421 part 2. Mirror https://github.com/mozilla/activity-stream repository layout in browser/extensions/activity-stream. r=k88hudson draft
authorEd Lee <edilee@mozilla.com>
Wed, 06 Jun 2018 10:44:53 -0700
changeset 805285 b11c6bd342c11696de8cdbbbe24ef3034df251a5
parent 805284 baf7e6db4c5bb245960b2c3d2ab2542520e1347c
push id112620
push userbmo:edilee@mozilla.com
push dateThu, 07 Jun 2018 16:24:33 +0000
reviewersk88hudson
bugs1440421
milestone62.0a1
Bug 1440421 part 2. Mirror https://github.com/mozilla/activity-stream repository layout in browser/extensions/activity-stream. r=k88hudson MozReview-Commit-ID: HyAUvAgOVEV
browser/extensions/activity-stream/.eslintignore
browser/extensions/activity-stream/.eslintrc.js
browser/extensions/activity-stream/.mcignore
browser/extensions/activity-stream/.nvmrc
browser/extensions/activity-stream/.sass-lint.yml
browser/extensions/activity-stream/.travis.yml
browser/extensions/activity-stream/CODEOWNERS
browser/extensions/activity-stream/LICENSE
browser/extensions/activity-stream/README.md
browser/extensions/activity-stream/bin/download-firefox-artifact
browser/extensions/activity-stream/bin/download-firefox-travis.sh
browser/extensions/activity-stream/bin/prepare-mochitests-dev
browser/extensions/activity-stream/bin/process-system-addon-for-package.js
browser/extensions/activity-stream/bin/render-activity-stream-html.js
browser/extensions/activity-stream/bin/strings-import.js
browser/extensions/activity-stream/bin/test-merges.js
browser/extensions/activity-stream/bin/update-version.js
browser/extensions/activity-stream/content-src/.eslintrc.js
browser/extensions/activity-stream/content-src/activity-stream-prerender.jsx
browser/extensions/activity-stream/content-src/activity-stream.jsx
browser/extensions/activity-stream/content-src/asrouter/asrouter-content.jsx
browser/extensions/activity-stream/content-src/asrouter/components/Button/Button.jsx
browser/extensions/activity-stream/content-src/asrouter/components/Button/_Button.scss
browser/extensions/activity-stream/content-src/asrouter/components/ImpressionsWrapper/ImpressionsWrapper.jsx
browser/extensions/activity-stream/content-src/asrouter/components/ModalOverlay/ModalOverlay.jsx
browser/extensions/activity-stream/content-src/asrouter/components/ModalOverlay/_ModalOverlay.scss
browser/extensions/activity-stream/content-src/asrouter/components/SnippetBase/SnippetBase.jsx
browser/extensions/activity-stream/content-src/asrouter/components/SnippetBase/_SnippetBase.scss
browser/extensions/activity-stream/content-src/asrouter/schemas/message-format.md
browser/extensions/activity-stream/content-src/asrouter/schemas/provider-response.schema.json
browser/extensions/activity-stream/content-src/asrouter/template-utils.js
browser/extensions/activity-stream/content-src/asrouter/templates/OnboardingMessage/OnboardingMessage.jsx
browser/extensions/activity-stream/content-src/asrouter/templates/OnboardingMessage/_OnboardingMessage.scss
browser/extensions/activity-stream/content-src/asrouter/templates/SimpleSnippet/SimpleSnippet.jsx
browser/extensions/activity-stream/content-src/asrouter/templates/SimpleSnippet/SimpleSnippet.schema.json
browser/extensions/activity-stream/content-src/asrouter/templates/SimpleSnippet/_SimpleSnippet.scss
browser/extensions/activity-stream/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx
browser/extensions/activity-stream/content-src/components/ASRouterAdmin/ASRouterAdmin.scss
browser/extensions/activity-stream/content-src/components/Base/Base.jsx
browser/extensions/activity-stream/content-src/components/Base/_Base.scss
browser/extensions/activity-stream/content-src/components/Card/Card.jsx
browser/extensions/activity-stream/content-src/components/Card/_Card.scss
browser/extensions/activity-stream/content-src/components/Card/types.js
browser/extensions/activity-stream/content-src/components/CollapsibleSection/CollapsibleSection.jsx
browser/extensions/activity-stream/content-src/components/CollapsibleSection/_CollapsibleSection.scss
browser/extensions/activity-stream/content-src/components/ComponentPerfTimer/ComponentPerfTimer.jsx
browser/extensions/activity-stream/content-src/components/ConfirmDialog/ConfirmDialog.jsx
browser/extensions/activity-stream/content-src/components/ConfirmDialog/_ConfirmDialog.scss
browser/extensions/activity-stream/content-src/components/ContextMenu/ContextMenu.jsx
browser/extensions/activity-stream/content-src/components/ContextMenu/_ContextMenu.scss
browser/extensions/activity-stream/content-src/components/ErrorBoundary/ErrorBoundary.jsx
browser/extensions/activity-stream/content-src/components/ErrorBoundary/_ErrorBoundary.scss
browser/extensions/activity-stream/content-src/components/LinkMenu/LinkMenu.jsx
browser/extensions/activity-stream/content-src/components/ManualMigration/ManualMigration.jsx
browser/extensions/activity-stream/content-src/components/ManualMigration/_ManualMigration.scss
browser/extensions/activity-stream/content-src/components/Search/Search.jsx
browser/extensions/activity-stream/content-src/components/Search/_Search.scss
browser/extensions/activity-stream/content-src/components/SectionMenu/SectionMenu.jsx
browser/extensions/activity-stream/content-src/components/Sections/Sections.jsx
browser/extensions/activity-stream/content-src/components/Sections/_Sections.scss
browser/extensions/activity-stream/content-src/components/StartupOverlay/StartupOverlay.jsx
browser/extensions/activity-stream/content-src/components/StartupOverlay/_StartupOverlay.scss
browser/extensions/activity-stream/content-src/components/TopSites/TopSite.jsx
browser/extensions/activity-stream/content-src/components/TopSites/TopSiteForm.jsx
browser/extensions/activity-stream/content-src/components/TopSites/TopSiteFormInput.jsx
browser/extensions/activity-stream/content-src/components/TopSites/TopSites.jsx
browser/extensions/activity-stream/content-src/components/TopSites/TopSitesConstants.js
browser/extensions/activity-stream/content-src/components/TopSites/_TopSites.scss
browser/extensions/activity-stream/content-src/components/Topics/Topics.jsx
browser/extensions/activity-stream/content-src/components/Topics/_Topics.scss
browser/extensions/activity-stream/content-src/lib/constants.js
browser/extensions/activity-stream/content-src/lib/detect-user-session-start.js
browser/extensions/activity-stream/content-src/lib/init-store.js
browser/extensions/activity-stream/content-src/lib/link-menu-options.js
browser/extensions/activity-stream/content-src/lib/section-menu-options.js
browser/extensions/activity-stream/content-src/lib/snippets.js
browser/extensions/activity-stream/content-src/styles/_activity-stream.scss
browser/extensions/activity-stream/content-src/styles/_icons.scss
browser/extensions/activity-stream/content-src/styles/_normalize.scss
browser/extensions/activity-stream/content-src/styles/_theme.scss
browser/extensions/activity-stream/content-src/styles/_variables.scss
browser/extensions/activity-stream/content-src/styles/activity-stream-linux.scss
browser/extensions/activity-stream/content-src/styles/activity-stream-mac.scss
browser/extensions/activity-stream/content-src/styles/activity-stream-windows.scss
browser/extensions/activity-stream/contributing.md
browser/extensions/activity-stream/data/content/activity-stream.bundle.js
browser/extensions/activity-stream/data/content/activity-stream.bundle.js.map
browser/extensions/activity-stream/docs/ISSUE_TEMPLATE.md
browser/extensions/activity-stream/docs/v2-system-addon/1.GETTING_STARTED.md
browser/extensions/activity-stream/docs/v2-system-addon/data_dictionary.md
browser/extensions/activity-stream/docs/v2-system-addon/data_events.md
browser/extensions/activity-stream/docs/v2-system-addon/mochitests.md
browser/extensions/activity-stream/docs/v2-system-addon/preferences.md
browser/extensions/activity-stream/docs/v2-system-addon/sections.md
browser/extensions/activity-stream/docs/v2-system-addon/snippets.md
browser/extensions/activity-stream/docs/v2-system-addon/telemetry.md
browser/extensions/activity-stream/docs/v2-system-addon/test-merges.md
browser/extensions/activity-stream/docs/v2-system-addon/unit_testing_guide.md
browser/extensions/activity-stream/install.rdf.in
browser/extensions/activity-stream/karma.mc.config.js
browser/extensions/activity-stream/loaders/inject-loader.js
browser/extensions/activity-stream/locales/ach/strings.properties
browser/extensions/activity-stream/locales/an/strings.properties
browser/extensions/activity-stream/locales/ar/strings.properties
browser/extensions/activity-stream/locales/ast/strings.properties
browser/extensions/activity-stream/locales/az/strings.properties
browser/extensions/activity-stream/locales/be/strings.properties
browser/extensions/activity-stream/locales/bg/strings.properties
browser/extensions/activity-stream/locales/bn-BD/strings.properties
browser/extensions/activity-stream/locales/bn-IN/strings.properties
browser/extensions/activity-stream/locales/br/strings.properties
browser/extensions/activity-stream/locales/bs/strings.properties
browser/extensions/activity-stream/locales/ca/strings.properties
browser/extensions/activity-stream/locales/cak/strings.properties
browser/extensions/activity-stream/locales/crh/strings.properties
browser/extensions/activity-stream/locales/cs/strings.properties
browser/extensions/activity-stream/locales/cy/strings.properties
browser/extensions/activity-stream/locales/da/strings.properties
browser/extensions/activity-stream/locales/de/strings.properties
browser/extensions/activity-stream/locales/dsb/strings.properties
browser/extensions/activity-stream/locales/el/strings.properties
browser/extensions/activity-stream/locales/en-CA/strings.properties
browser/extensions/activity-stream/locales/en-GB/strings.properties
browser/extensions/activity-stream/locales/en-US/strings.properties
browser/extensions/activity-stream/locales/eo/strings.properties
browser/extensions/activity-stream/locales/es-AR/strings.properties
browser/extensions/activity-stream/locales/es-CL/strings.properties
browser/extensions/activity-stream/locales/es-ES/strings.properties
browser/extensions/activity-stream/locales/es-MX/strings.properties
browser/extensions/activity-stream/locales/et/strings.properties
browser/extensions/activity-stream/locales/eu/strings.properties
browser/extensions/activity-stream/locales/fa/strings.properties
browser/extensions/activity-stream/locales/ff/strings.properties
browser/extensions/activity-stream/locales/fi/strings.properties
browser/extensions/activity-stream/locales/fr/strings.properties
browser/extensions/activity-stream/locales/fy-NL/strings.properties
browser/extensions/activity-stream/locales/ga-IE/strings.properties
browser/extensions/activity-stream/locales/gd/strings.properties
browser/extensions/activity-stream/locales/gl/strings.properties
browser/extensions/activity-stream/locales/gn/strings.properties
browser/extensions/activity-stream/locales/gu-IN/strings.properties
browser/extensions/activity-stream/locales/he/strings.properties
browser/extensions/activity-stream/locales/hi-IN/strings.properties
browser/extensions/activity-stream/locales/hr/strings.properties
browser/extensions/activity-stream/locales/hsb/strings.properties
browser/extensions/activity-stream/locales/hu/strings.properties
browser/extensions/activity-stream/locales/hy-AM/strings.properties
browser/extensions/activity-stream/locales/ia/strings.properties
browser/extensions/activity-stream/locales/id/strings.properties
browser/extensions/activity-stream/locales/it/strings.properties
browser/extensions/activity-stream/locales/ja/strings.properties
browser/extensions/activity-stream/locales/ka/strings.properties
browser/extensions/activity-stream/locales/kab/strings.properties
browser/extensions/activity-stream/locales/kk/strings.properties
browser/extensions/activity-stream/locales/km/strings.properties
browser/extensions/activity-stream/locales/kn/strings.properties
browser/extensions/activity-stream/locales/ko/strings.properties
browser/extensions/activity-stream/locales/lij/strings.properties
browser/extensions/activity-stream/locales/lo/strings.properties
browser/extensions/activity-stream/locales/lt/strings.properties
browser/extensions/activity-stream/locales/ltg/strings.properties
browser/extensions/activity-stream/locales/lv/strings.properties
browser/extensions/activity-stream/locales/mai/strings.properties
browser/extensions/activity-stream/locales/mk/strings.properties
browser/extensions/activity-stream/locales/ml/strings.properties
browser/extensions/activity-stream/locales/mr/strings.properties
browser/extensions/activity-stream/locales/ms/strings.properties
browser/extensions/activity-stream/locales/my/strings.properties
browser/extensions/activity-stream/locales/nb-NO/strings.properties
browser/extensions/activity-stream/locales/ne-NP/strings.properties
browser/extensions/activity-stream/locales/nl/strings.properties
browser/extensions/activity-stream/locales/nn-NO/strings.properties
browser/extensions/activity-stream/locales/oc/strings.properties
browser/extensions/activity-stream/locales/pa-IN/strings.properties
browser/extensions/activity-stream/locales/pl/strings.properties
browser/extensions/activity-stream/locales/pt-BR/strings.properties
browser/extensions/activity-stream/locales/pt-PT/strings.properties
browser/extensions/activity-stream/locales/rm/strings.properties
browser/extensions/activity-stream/locales/ro/strings.properties
browser/extensions/activity-stream/locales/ru/strings.properties
browser/extensions/activity-stream/locales/si/strings.properties
browser/extensions/activity-stream/locales/sk/strings.properties
browser/extensions/activity-stream/locales/sl/strings.properties
browser/extensions/activity-stream/locales/sq/strings.properties
browser/extensions/activity-stream/locales/sr/strings.properties
browser/extensions/activity-stream/locales/sv-SE/strings.properties
browser/extensions/activity-stream/locales/ta/strings.properties
browser/extensions/activity-stream/locales/te/strings.properties
browser/extensions/activity-stream/locales/th/strings.properties
browser/extensions/activity-stream/locales/tl/strings.properties
browser/extensions/activity-stream/locales/tr/strings.properties
browser/extensions/activity-stream/locales/uk/strings.properties
browser/extensions/activity-stream/locales/ur/strings.properties
browser/extensions/activity-stream/locales/uz/strings.properties
browser/extensions/activity-stream/locales/vi/strings.properties
browser/extensions/activity-stream/locales/zh-CN/strings.properties
browser/extensions/activity-stream/locales/zh-TW/strings.properties
browser/extensions/activity-stream/package-lock.json
browser/extensions/activity-stream/package.json
browser/extensions/activity-stream/test/unit/content-src/components/Base.test.jsx
browser/extensions/activity-stream/test/unit/content-src/components/Card.test.jsx
browser/extensions/activity-stream/test/unit/content-src/components/CollapsibleSection.test.jsx
browser/extensions/activity-stream/test/unit/content-src/components/ComponentPerfTimer.test.jsx
browser/extensions/activity-stream/test/unit/content-src/components/ConfirmDialog.test.jsx
browser/extensions/activity-stream/test/unit/content-src/components/ContextMenu.test.jsx
browser/extensions/activity-stream/test/unit/content-src/components/ErrorBoundary.test.jsx
browser/extensions/activity-stream/test/unit/content-src/components/LinkMenu.test.jsx
browser/extensions/activity-stream/test/unit/content-src/components/ManualMigration.test.jsx
browser/extensions/activity-stream/test/unit/content-src/components/Search.test.jsx
browser/extensions/activity-stream/test/unit/content-src/components/SectionMenu.test.jsx
browser/extensions/activity-stream/test/unit/content-src/components/Sections.test.jsx
browser/extensions/activity-stream/test/unit/content-src/components/StartupOverlay.test.jsx
browser/extensions/activity-stream/test/unit/content-src/components/TopSites.test.jsx
browser/extensions/activity-stream/test/unit/content-src/components/Topics.test.jsx
browser/extensions/activity-stream/test/unit/content-src/lib/detect-user-session-start.test.js
browser/extensions/activity-stream/test/unit/content-src/lib/snippets.test.js
browser/extensions/activity-stream/webpack.prerender.config.js
browser/extensions/activity-stream/webpack.system-addon.config.js
browser/extensions/activity-stream/yamscripts.yml
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/.eslintignore
@@ -0,0 +1,10 @@
+activity-streams-env/
+dist/
+firefox/
+logs/
+stats.json
+prerendered/
+vendor/
+data/
+bin/prerender.js
+bin/prerender.js.map
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/.eslintrc.js
@@ -0,0 +1,231 @@
+module.exports = {
+  // When adding items to this file please check for effects on sub-directories.
+  "parserOptions": {
+    "ecmaFeatures": {
+      "jsx": true
+    },
+    "sourceType": "module"
+  },
+  "env": {
+    "node": true
+  },
+  "plugins": [
+    "import", // require("eslint-plugin-import")
+    "json", // require("eslint-plugin-json")
+    "promise", // require("eslint-plugin-promise")
+    "react" // require("eslint-plugin-react")
+  ],
+  "extends": [
+    "eslint:recommended",
+    "plugin:mozilla/recommended" // require("eslint-plugin-mozilla")
+  ],
+  "overrides": [{
+    // Use a configuration that's more appropriate for JSMs
+    "files": "**/*.jsm",
+    "parserOptions": {
+      "sourceType": "script"
+    },
+    "env": {
+      "node": false
+    },
+    "rules": {
+      "no-implicit-globals": 0
+    }
+  }],
+  "rules": {
+    "promise/catch-or-return": 2,
+    "promise/param-names": 2,
+
+    "react/jsx-boolean-value": [2, "always"],
+    "react/jsx-closing-bracket-location": [2, "after-props"],
+    "react/jsx-curly-spacing": [2, "never"],
+    "react/jsx-equals-spacing": [2, "never"],
+    "react/jsx-key": 2,
+    "react/jsx-no-bind": 2,
+    "react/jsx-no-comment-textnodes": 2,
+    "react/jsx-no-duplicate-props": 2,
+    "react/jsx-no-target-blank": 2,
+    "react/jsx-no-undef": 2,
+    "react/jsx-pascal-case": 2,
+    "react/jsx-space-before-closing": [2, "always"],
+    "react/jsx-uses-react": 2,
+    "react/jsx-uses-vars": 2,
+    "react/jsx-wrap-multilines": 2,
+    "react/no-access-state-in-setstate": 2,
+    "react/no-danger": 2,
+    "react/no-deprecated": 2,
+    "react/no-did-mount-set-state": 2,
+    "react/no-did-update-set-state": 2,
+    "react/no-direct-mutation-state": 2,
+    "react/no-is-mounted": 2,
+    "react/no-unknown-property": 2,
+    "react/require-render-return": 2,
+    "react/self-closing-comp": 2,
+
+    "accessor-pairs": [2, {"setWithoutGet": true, "getWithoutSet": false}],
+    "array-bracket-newline": [2, "consistent"],
+    "array-bracket-spacing": [2, "never"],
+    "array-callback-return": 2,
+    "array-element-newline": 0,
+    "arrow-body-style": [2, "as-needed"],
+    "arrow-parens": [2, "as-needed"],
+    "block-scoped-var": 2,
+    "callback-return": 0,
+    "camelcase": 0,
+    "capitalized-comments": 0,
+    "class-methods-use-this": 0,
+    "comma-dangle": [2, "never"],
+    "consistent-this": [2, "use-bind"],
+    "curly": [2, "all"],
+    "default-case": 0,
+    "dot-location": [2, "property"],
+    "eqeqeq": 2,
+    "for-direction": 2,
+    "func-name-matching": 2,
+    "func-names": 0,
+    "func-style": 0,
+    "function-paren-newline": 0,
+    "getter-return": 2,
+    "global-require": 0,
+    "guard-for-in": 2,
+    "handle-callback-err": 2,
+    "id-blacklist": 0,
+    "id-length": 0,
+    "id-match": 0,
+    "implicit-arrow-linebreak": 0,
+    // XXX Switch back to indent once mozilla-central has decided what it is using.
+    "indent": 0,
+    "indent-legacy": ["error", 2, {"SwitchCase": 1}],
+    "init-declarations": 0,
+    "jsx-quotes": [2, "prefer-double"],
+    "line-comment-position": 0,
+    "lines-around-comment": ["error", {
+      "allowClassStart": true,
+      "allowObjectStart": true,
+      "beforeBlockComment": true
+    }],
+    "lines-between-class-members": 2,
+    "max-depth": [2, 4],
+    "max-len": 0,
+    "max-lines": 0,
+    "max-nested-callbacks": [2, 4],
+    "max-params": [2, 6],
+    "max-statements": [2, 50],
+    "max-statements-per-line": [2, {"max": 2}],
+    "multiline-comment-style": 0,
+    "multiline-ternary": 0,
+    "new-cap": [2, {"newIsCap": true, "capIsNew": false}],
+    "new-parens": 2,
+    "newline-after-var": 0,
+    "newline-before-return": 0,
+    "newline-per-chained-call": [2, {"ignoreChainWithDepth": 3}],
+    "no-alert": 2,
+    "no-await-in-loop": 0,
+    "no-bitwise": 0,
+    "no-buffer-constructor": 2,
+    "no-catch-shadow": 2,
+    "no-confusing-arrow": [2, {"allowParens": true}],
+    "no-console": 1,
+    "no-continue": 0,
+    "no-div-regex": 2,
+    "no-duplicate-imports": 2,
+    "no-empty-function": 0,
+    "no-eq-null": 2,
+    "no-extend-native": 2,
+    "no-extra-label": 2,
+    "no-extra-parens": 0,
+    "no-floating-decimal": 2,
+    "no-implicit-coercion": [2, {"allow": ["!!"]}],
+    "no-implicit-globals": 2,
+    "no-inline-comments": 0,
+    "no-invalid-this": 0,
+    "no-label-var": 2,
+    "no-loop-func": 2,
+    "no-magic-numbers": 0,
+    "no-mixed-operators": [2, {"allowSamePrecedence": true, "groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["==", "!=", "===", "!==", ">", ">=", "<", "<="], ["&&", "||"], ["in", "instanceof"]]}],
+    "no-mixed-requires": 2,
+    "no-multi-assign": 2,
+    "no-multi-str": 2,
+    "no-multiple-empty-lines": [2, {"max": 1, "maxBOF": 0, "maxEOF": 0}],
+    "no-negated-condition": 0,
+    "no-negated-in-lhs": 2,
+    "no-new": 2,
+    "no-new-func": 2,
+    "no-new-require": 2,
+    "no-octal-escape": 2,
+    "no-param-reassign": 2,
+    "no-path-concat": 2,
+    "no-plusplus": 0,
+    "no-process-env": 0,
+    "no-process-exit": 2,
+    "no-proto": 2,
+    "no-prototype-builtins": 2,
+    "no-restricted-globals": 0,
+    "no-restricted-imports": 0,
+    "no-restricted-modules": 0,
+    "no-restricted-properties": 0,
+    "no-restricted-syntax": 0,
+    "no-return-assign": [2, "except-parens"],
+    "no-script-url": 2,
+    "no-sequences": 2,
+    "no-shadow": 2,
+    "no-spaced-func": 2,
+    "no-sync": 0,
+    "no-template-curly-in-string": 2,
+    "no-ternary": 0,
+    "no-throw-literal": 2,
+    "no-undef-init": 2,
+    "no-undefined": 0,
+    "no-underscore-dangle": 0,
+    "no-unmodified-loop-condition": 2,
+    "no-unused-expressions": 2,
+    "no-use-before-define": 2,
+    "no-useless-computed-key": 2,
+    "no-useless-constructor": 2,
+    "no-useless-rename": 2,
+    "no-var": 2,
+    "no-void": 2,
+    "no-warning-comments": 0, // TODO: Change to `1`?
+    "nonblock-statement-body-position": 2,
+    "object-curly-newline": [2, {"multiline": true}],
+    "object-curly-spacing": [2, "never"],
+    "object-property-newline": [2, {"allowMultiplePropertiesPerLine": true}],
+    "one-var": [2, "never"],
+    "one-var-declaration-per-line": [2, "initializations"],
+    "operator-assignment": [2, "always"],
+    "operator-linebreak": [2, "after"],
+    "padded-blocks": [2, "never"],
+    "padding-line-between-statements": 0,
+    "prefer-arrow-callback": ["error", {"allowNamedFunctions": true}],
+    "prefer-const": 0, // TODO: Change to `1`?
+    "prefer-destructuring": [2, {"AssignmentExpression": {"array": true}, "VariableDeclarator": {"array": true, "object": true}}],
+    "prefer-numeric-literals": 2,
+    "prefer-promise-reject-errors": 2,
+    "prefer-reflect": 0,
+    "prefer-rest-params": 2,
+    "prefer-spread": 2,
+    "prefer-template": 2,
+    "quote-props": [2, "consistent"],
+    "radix": [2, "always"],
+    "require-await": 2,
+    "require-jsdoc": 0,
+    "semi-spacing": [2, {"before": false, "after": true}],
+    "semi-style": 2,
+    "sort-imports": [2, {"ignoreCase": true}],
+    "sort-keys": 0,
+    "sort-vars": 2,
+    "space-in-parens": [2, "never"],
+    "strict": 0,
+    "switch-colon-spacing": 2,
+    "symbol-description": 2,
+    "template-curly-spacing": [2, "never"],
+    "template-tag-spacing": 2,
+    "unicode-bom": [2, "never"],
+    "valid-jsdoc": [0, {"requireReturn": false, "requireParamDescription": false, "requireReturnDescription": false}],
+    "vars-on-top": 2,
+    "wrap-iife": [2, "inside"],
+    "wrap-regex": 0,
+    "yield-star-spacing": [2, "after"],
+    "yoda": [2, "never"]
+  }
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/.mcignore
@@ -0,0 +1,18 @@
+npm-debug.log
+.DS_Store
+*.sw[po]
+*.xpi
+*.pyc
+*.update.rdf
+.gitignore
+
+/.git/
+/bin/prerender.js
+/bin/prerender.js.map
+/data/locales.json
+/dist/
+/logs/
+/node_modules/
+
+# also ignores ping centre tests
+ping-centre/
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/.nvmrc
@@ -0,0 +1,1 @@
+7.*
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/.sass-lint.yml
@@ -0,0 +1,25 @@
+options:
+  merge-default-rules: true
+
+files:
+  include: 'content-src/**/*.scss'
+
+rules:
+  class-name-format: [{convention: ["hyphenatedlowercase", "camelcase"]}]
+  extends-before-declarations: 2
+  extends-before-mixins: 2
+  force-element-nesting: 0
+  force-pseudo-nesting: 0
+  hex-notation: [2, {style: uppercase}]
+  indentation: [2, {size: 2}]
+  leading-zero: [2, {include: true}]
+  mixins-before-declarations: [2, {exclude: [breakpoint, mq]}]
+  nesting-depth: [2, {max-depth: 4}]
+  no-debug: 1
+  no-duplicate-properties: 2
+  no-misspelled-properties: [2, {extra-properties: [-moz-context-properties]}]
+  no-url-domains: 0
+  no-vendor-prefixes: 0
+  no-warn: 1
+  placeholder-in-extend: 2
+  property-sort-order: 0
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/.travis.yml
@@ -0,0 +1,33 @@
+language: node_js
+
+node_js:
+  # when changing this, be sure to edit .nvrmc and package.json too
+  - 7
+
+python:
+  - "2.7"
+
+cache:
+  directories:
+    - node_modules
+
+before_install:
+  # see https://docs.travis-ci.com/user/gui-and-headless-browsers/#Using-xvfb-to-Run-Tests-That-Require-a-GUI
+  - "export DISPLAY=:99.0"
+  - "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16 -extension RANDR"
+  - export PATH="$PATH:$HOME/.rvm/bin"
+  - sleep 3
+
+install:
+  - npm config set spin false
+  - npm install
+
+before_script:
+  - bash bin/download-firefox-travis.sh release-linux64-add-on-devel
+  - export FIREFOX_BIN=./firefox/firefox
+
+script:
+  - npm test
+
+notifications:
+  email: false
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/CODEOWNERS
@@ -0,0 +1,2 @@
+# flod as main contact for string changes
+locales/en-US/strings.properties @flodolo
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/LICENSE
@@ -0,0 +1,374 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+    means each individual or legal entity that creates, contributes to
+    the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+    means the combination of the Contributions of others (if any) used
+    by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+    means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+    means Source Code Form to which the initial Contributor has attached
+    the notice in Exhibit A, the Executable Form of such Source Code
+    Form, and Modifications of such Source Code Form, in each case
+    including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+    means
+
+    (a) that the initial Contributor has attached the notice described
+        in Exhibit B to the Covered Software; or
+
+    (b) that the Covered Software was made available under the terms of
+        version 1.1 or earlier of the License, but not also under the
+        terms of a Secondary License.
+
+1.6. "Executable Form"
+    means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+    means a work that combines Covered Software with other material, in 
+    a separate file or files, that is not Covered Software.
+
+1.8. "License"
+    means this document.
+
+1.9. "Licensable"
+    means having the right to grant, to the maximum extent possible,
+    whether at the time of the initial grant or subsequently, any and
+    all of the rights conveyed by this License.
+
+1.10. "Modifications"
+    means any of the following:
+
+    (a) any file in Source Code Form that results from an addition to,
+        deletion from, or modification of the contents of Covered
+        Software; or
+
+    (b) any new file in Source Code Form that contains any Covered
+        Software.
+
+1.11. "Patent Claims" of a Contributor
+    means any patent claim(s), including without limitation, method,
+    process, and apparatus claims, in any patent Licensable by such
+    Contributor that would be infringed, but for the grant of the
+    License, by the making, using, selling, offering for sale, having
+    made, import, or transfer of either its Contributions or its
+    Contributor Version.
+
+1.12. "Secondary License"
+    means either the GNU General Public License, Version 2.0, the GNU
+    Lesser General Public License, Version 2.1, the GNU Affero General
+    Public License, Version 3.0, or any later versions of those
+    licenses.
+
+1.13. "Source Code Form"
+    means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+    means an individual or a legal entity exercising rights under this
+    License. For legal entities, "You" includes any entity that
+    controls, is controlled by, or is under common control with You. For
+    purposes of this definition, "control" means (a) the power, direct
+    or indirect, to cause the direction or management of such entity,
+    whether by contract or otherwise, or (b) ownership of more than
+    fifty percent (50%) of the outstanding shares or beneficial
+    ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+    Licensable by such Contributor to use, reproduce, make available,
+    modify, display, perform, distribute, and otherwise exploit its
+    Contributions, either on an unmodified basis, with Modifications, or
+    as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+    for sale, have made, import, and otherwise transfer either its
+    Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+    or
+
+(b) for infringements caused by: (i) Your and any other third party's
+    modifications of Covered Software, or (ii) the combination of its
+    Contributions with other software (except as part of its Contributor
+    Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+    its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+    Form, as described in Section 3.1, and You must inform recipients of
+    the Executable Form how they can obtain a copy of such Source Code
+    Form by reasonable means in a timely manner, at a charge no more
+    than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+    License, or sublicense it under different terms, provided that the
+    license for the Executable Form does not attempt to limit or alter
+    the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+*                                                                      *
+*  6. Disclaimer of Warranty                                           *
+*  -------------------------                                           *
+*                                                                      *
+*  Covered Software is provided under this License on an "as is"       *
+*  basis, without warranty of any kind, either expressed, implied, or  *
+*  statutory, including, without limitation, warranties that the       *
+*  Covered Software is free of defects, merchantable, fit for a        *
+*  particular purpose or non-infringing. The entire risk as to the     *
+*  quality and performance of the Covered Software is with You.        *
+*  Should any Covered Software prove defective in any respect, You     *
+*  (not any Contributor) assume the cost of any necessary servicing,   *
+*  repair, or correction. This disclaimer of warranty constitutes an   *
+*  essential part of this License. No use of any Covered Software is   *
+*  authorized under this License except under this disclaimer.         *
+*                                                                      *
+************************************************************************
+
+************************************************************************
+*                                                                      *
+*  7. Limitation of Liability                                          *
+*  --------------------------                                          *
+*                                                                      *
+*  Under no circumstances and under no legal theory, whether tort      *
+*  (including negligence), contract, or otherwise, shall any           *
+*  Contributor, or anyone who distributes Covered Software as          *
+*  permitted above, be liable to You for any direct, indirect,         *
+*  special, incidental, or consequential damages of any character      *
+*  including, without limitation, damages for lost profits, loss of    *
+*  goodwill, work stoppage, computer failure or malfunction, or any    *
+*  and all other commercial damages or losses, even if such party      *
+*  shall have been informed of the possibility of such damages. This   *
+*  limitation of liability shall not apply to liability for death or   *
+*  personal injury resulting from such party's negligence to the       *
+*  extent applicable law prohibits such limitation. Some               *
+*  jurisdictions do not allow the exclusion or limitation of           *
+*  incidental or consequential damages, so this exclusion and          *
+*  limitation may not apply to You.                                    *
+*                                                                      *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+  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/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+  This Source Code Form is "Incompatible With Secondary Licenses", as
+  defined by the Mozilla Public License, v. 2.0.
+
--- a/browser/extensions/activity-stream/README.md
+++ b/browser/extensions/activity-stream/README.md
@@ -2,8 +2,21 @@
 
 This system add-on replaces the new tab page in Firefox with a new design and
 functionality as part of the Activity Stream project.
 
 The files in this directory, including vendor dependencies, are imported from the
 system-addon directory in https://github.com/mozilla/activity-stream.
 
 Read [docs/v2-system-addon](https://github.com/mozilla/activity-stream/tree/master/docs/v2-system-addon/1.GETTING_STARTED.md) for more detail.
+
+## Where should I file bugs?
+
+We regularly check the ActivityStream:NewTab component on Bugzilla.
+
+## For Developers
+
+If you are interested in contributing, take a look at [this guide](contributing.md) on where to find us and how to contribute,
+and [this guide](docs/v2-system-addon/1.GETTING_STARTED.md) for getting your development environment set up.
+
+## For Localizers
+
+Activity Stream localization is managed via [Pontoon](https://pontoon.mozilla.org/projects/activity-stream-new-tab/), not direct pull requests to the repository. If you want to fix a typo, add a new language, or simply know more about localization, please get in touch with the [existing localization team](https://pontoon.mozilla.org/teams/) for your language, or Mozilla’s [l10n-drivers](https://wiki.mozilla.org/L10n:Mozilla_Team#Mozilla_Corporation) for guidance.
new file mode 100755
--- /dev/null
+++ b/browser/extensions/activity-stream/bin/download-firefox-artifact
@@ -0,0 +1,67 @@
+#!/usr/bin/env bash -x
+
+# Forked from https://github.com/devtools-html/debugger.html/blob/master/bin/download-firefox-artifact
+#
+# This looks for a mozilla-central artifact build as a sibling of the
+# activity-stream tree.  If it's not there, it creates it.  If it is there, it
+# updates it.
+
+# If AS_GIT_BIN_REPO (the git repo from which prepare-mochitests-dev and
+# friends will be executed) isn't set in the environment, just use the repo
+#  we're running from.
+if [ -z ${AS_GIT_BIN_REPO+x} ]; then
+  ROOT=`dirname $0`
+  AS_GIT_BIN_REPO="../../../../activity-stream"
+else
+  ROOT=${AS_GIT_BIN_REPO}/bin
+fi
+
+# Compute the mozilla-central path based on whether AS_PINE_TEST_DIR is set
+# (i.e. whether this script has been called from test-merges.js)
+if [ -z ${AS_PINE_TEST_DIR+x} ]; then
+  FIREFOX_PATH="$ROOT/../../mozilla-central"
+else
+  FIREFOX_PATH=${AS_PINE_TEST_DIR}/mozilla-central
+fi
+
+# check that mercurial is installed
+if [ -z "`command -v hg`" ]; then
+  echo >&2 "mercurial is required for mochitests, use 'brew install mercurial' on MacOS";
+  exit 1;
+fi
+
+if [ -d "$FIREFOX_PATH" ]; then
+    # convert path to absolute path
+    FIREFOX_PATH=$(cd "$FIREFOX_PATH"; pwd)
+
+    # If we already have Firefox locally, just update it
+    cd "$FIREFOX_PATH";
+
+    if [ -n "`hg status`" ]; then
+        read -p "There are local changes to Firefox which will be overwritten. Are you sure? [Y/n] " -r
+        if [[ $REPLY == "n" ]]; then
+            exit 0;
+        fi
+
+        hg revert -a
+    fi
+
+    hg pull
+    hg update -C
+else
+    echo "Downloading Firefox source code, requires about 10-30min depending on connection"
+    hg clone https://hg.mozilla.org/mozilla-central/ "$FIREFOX_PATH"
+    # if somebody cancels (ctrl-c) out of the long download don't continue
+    exit_code=$?
+    if [ $exit_code -ne 0 ]; then
+      exit $exit_code
+    fi
+    cd "$FIREFOX_PATH"
+
+    # Make an artifact build so it builds much faster
+    echo "
+ac_add_options --enable-artifact-builds
+mk_add_options AUTOCLOBBER=1
+mk_add_options MOZ_OBJDIR=./objdir-frontend
+" > .mozconfig
+fi
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/bin/download-firefox-travis.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# Copied and slightly modified from https://github.com/lidel/ipfs-firefox-addon/commit/d656832eec807ebae59543982dde96932ce5bb7c
+# Licensed under Creative Commons -  CC0 1.0 Universal - https://github.com/lidel/ipfs-firefox-addon/blob/master/LICENSE
+BUILD_TYPE=${1:-$FIREFOX_RELEASE}
+echo "Looking up latest URL for $BUILD_TYPE"
+BUILD_ROOT="/pub/firefox/tinderbox-builds/mozilla-${BUILD_TYPE}/"
+ROOT="https://archive.mozilla.org"
+LATEST=$(curl -s "$ROOT$BUILD_ROOT" | grep $BUILD_TYPE | grep -Po '<a href=".+">\K[[:digit:]]+' | sort -n | tail -1)
+echo "Latest build located at $ROOT$BUILD_ROOT$LATEST"
+FILE=$(curl -s "$ROOT$BUILD_ROOT$LATEST/" | grep '.tar.' | grep -Po '<a href="\K[^"]*')
+echo "URL: $ROOT$FILE"
+wget -O "firefox-${BUILD_TYPE}.tar.bz2" "$ROOT$FILE" && tar xf "firefox-${BUILD_TYPE}.tar.bz2"
new file mode 100755
--- /dev/null
+++ b/browser/extensions/activity-stream/bin/prepare-mochitests-dev
@@ -0,0 +1,65 @@
+#!/usr/bin/env bash -x -e
+#
+# -e means "exit on error", so that we don't have to constantly
+# check exit codes
+#
+# Forked from https://github.com/devtools-html/debugger.html/blob/master/bin/prepare-mochitests-dev
+#
+# This sets up a mozilla-central build for local mochitest development with an
+# exported activity-stream tree and test directory.
+
+# If AS_GIT_BIN_REPO (the git repo from which prepare-mochitests-dev and
+# friends will be executed) isn't set in the environment, just use the repo
+#  we're running from.
+if [ -z ${AS_GIT_BIN_REPO+x} ]; then
+  ROOT=`dirname $0`
+  AS_GIT_BIN_REPO="../activity-stream" # as seen from mozilla-central
+else
+  ROOT=${AS_GIT_BIN_REPO}/bin
+fi
+
+# Compute the mozilla-central path based on whether AS_PINE_TEST_DIR is set
+# (i.e. whether this script has been called from test-merges.js)
+if [ -z ${AS_PINE_TEST_DIR+x} ]; then
+  FIREFOX_PATH="$ROOT/../../mozilla-central"
+else
+  FIREFOX_PATH=${AS_PINE_TEST_DIR}/mozilla-central
+fi
+
+MC_MODULE_PATH="$FIREFOX_PATH/browser/extensions/activity-stream"
+
+# By default, just use mozilla-central + the export.  If ENABLE_MC_AS is set to
+# 1, patch on top of mozilla-central + the export to turn on the AS pref and
+# turn on the tests.  Once AS is on by default in mozilla-central, stuff
+# related to ENABLE_MC_AS can go away entirely.
+ENABLE_MC_AS=${ENABLE_MC_AS-0}
+
+# This will either download or update the local Firefox repo
+"$ROOT/download-firefox-artifact"
+
+# blow away any old bits in order to workaround bug 1335976 for users
+# who are using the default objdir-frontend
+rm -f ${FIREFOX_PATH}/objdir-frontend/dist/bin/browser/features/@activity-streams/*
+
+# Clean, package, and copy the activity stream files.
+npm run buildmc
+
+# Patch mozilla-central (on top of the export) so that AS is preffed on, and
+# the mochitests are turned on.
+shopt -s nullglob # don't explode if there are no patches right now
+if [ $ENABLE_MC_AS ]; then
+  PATCHES=$AS_GIT_BIN_REPO/mozilla-central-patches/*.diff
+  for p in $PATCHES
+  do
+    patch --directory="$FIREFOX_PATH" -p1 --force --no-backup-if-mismatch \
+    --input=$p
+  done
+fi
+shopt -u nullglob
+
+# Be sure that we've built, and that the test glop in the objdir has been
+# created.
+#
+cd "$FIREFOX_PATH"
+./mach build
+exit $?
new file mode 100755
--- /dev/null
+++ b/browser/extensions/activity-stream/bin/process-system-addon-for-package.js
@@ -0,0 +1,21 @@
+#! /usr/bin/env node
+"use strict";
+
+const MIN_FIREFOX_VERSION = "55.0a1";
+
+/* globals cd, mv, sed */
+require("shelljs/global");
+
+cd(process.argv[2]);
+
+// Convert install.rdf.in to install.rdf without substitutions
+mv("install.rdf.in", "install.rdf");
+sed("-i", /^#filter substitution/, "", "install.rdf");
+sed("-i", /(<em:minVersion>).+(<\/em:minVersion>)/, `$1${MIN_FIREFOX_VERSION}$2`, "install.rdf");
+sed("-i", /(<em:maxVersion>).+(<\/em:maxVersion>)/, "$1*$2", "install.rdf");
+
+// Convert jar.mn to chrome.manifest with just manifest
+mv("jar.mn", "chrome.manifest");
+sed("-i", /^[^%].*$/, "", "chrome.manifest");
+sed("-i", /^% (content.*) %(.*)$/, "$1 $2", "chrome.manifest");
+sed("-i", /^% (resource.*) %.*$/, "$1 .", "chrome.manifest");
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/bin/render-activity-stream-html.js
@@ -0,0 +1,352 @@
+ /* eslint-disable no-console */
+const fs = require("fs");
+const {mkdir} = require("shelljs");
+const path = require("path");
+
+// Note: this file is generated by webpack from content-src/activity-stream-prerender.jsx
+const {prerender} = require("./prerender");
+
+const DEFAULT_LOCALE = "en-US";
+const DEFAULT_OPTIONS = {
+  addonPath: "..",
+  baseUrl: "resource://activity-stream/"
+};
+
+// This locales list is to find any similar locales that we can reuse strings
+// instead of falling back to the default, e.g., use bn-BD strings for bn-IN.
+// https://hg.mozilla.org/mozilla-central/file/tip/browser/locales/l10n.toml
+const CENTRAL_LOCALES = [
+  "ach",
+  "af",
+  "an",
+  "ar",
+  "as",
+  "ast",
+  "az",
+  "be",
+  "bg",
+  "bn-BD",
+  "bn-IN",
+  "br",
+  "bs",
+  "ca",
+  "cak",
+  "crh",
+  "cs",
+  "cy",
+  "da",
+  "de",
+  "dsb",
+  "el",
+  "en-CA",
+  "en-GB",
+  "en-ZA",
+  "eo",
+  "es-AR",
+  "es-CL",
+  "es-ES",
+  "es-MX",
+  "et",
+  "eu",
+  "fa",
+  "ff",
+  "fi",
+  "fr",
+  "fy-NL",
+  "ga-IE",
+  "gd",
+  "gl",
+  "gn",
+  "gu-IN",
+  "he",
+  "hi-IN",
+  "hr",
+  "hsb",
+  "hu",
+  "hy-AM",
+  "ia",
+  "id",
+  "is",
+  "it",
+  "ja",
+  "ja-JP-mac",
+  "ka",
+  "kab",
+  "kk",
+  "km",
+  "kn",
+  "ko",
+  "lij",
+  "lo",
+  "lt",
+  "ltg",
+  "lv",
+  "mai",
+  "mk",
+  "ml",
+  "mr",
+  "ms",
+  "my",
+  "nb-NO",
+  "ne-NP",
+  "nl",
+  "nn-NO",
+  "oc",
+  "or",
+  "pa-IN",
+  "pl",
+  "pt-BR",
+  "pt-PT",
+  "rm",
+  "ro",
+  "ru",
+  "si",
+  "sk",
+  "sl",
+  "son",
+  "sq",
+  "sr",
+  "sv-SE",
+  "ta",
+  "te",
+  "th",
+  "tl",
+  "tr",
+  "uk",
+  "ur",
+  "uz",
+  "vi",
+  "wo",
+  "xh",
+  "zh-CN",
+  "zh-TW"
+];
+
+// Locales that should be displayed RTL
+const RTL_LIST = ["ar", "he", "fa", "ur"];
+
+/**
+ * Get the language part of the locale.
+ */
+function getLanguage(locale) {
+  return locale.split("-")[0];
+}
+
+/**
+ * Get the best strings for a single provided locale using similar locales and
+ * DEFAULT_LOCALE as fallbacks.
+ */
+function getStrings(locale, allStrings) {
+  const availableLocales = Object.keys(allStrings);
+
+  const language = getLanguage(locale);
+  const similarLocales = availableLocales.filter(other =>
+    other !== locale && getLanguage(other) === language);
+
+  // Rank locales from least desired to most desired
+  const localeFallbacks = [DEFAULT_LOCALE, ...similarLocales, locale];
+
+  // Get strings from each locale replacing with those from more desired ones
+  return Object.assign({}, ...localeFallbacks.map(l => allStrings[l]));
+}
+
+/**
+ * Get the text direction of the locale.
+ */
+function getTextDirection(locale) {
+  return RTL_LIST.includes(locale.split("-")[0]) ? "rtl" : "ltr";
+}
+
+/**
+ * templateHTML - Generates HTML for activity stream, given some options and
+ * prerendered HTML if necessary.
+ *
+ * @param  {obj} options
+ *         {str} options.locale         The locale to render in lang="" attribute
+ *         {str} options.direction      The language direction to render in dir="" attribute
+ *         {str} options.baseUrl        The base URL for all local assets
+ *         {bool} options.debug         Should we use dev versions of JS libraries?
+ * @param  {str} html    The prerendered HTML created with React.renderToString (optional)
+ * @return {str}         An HTML document as a string
+ */
+function templateHTML(options, html) {
+  const isPrerendered = !!html;
+  const debugString = options.debug ? "-dev" : "";
+  const scripts = [
+    "chrome://browser/content/contentSearchUI.js",
+    `${options.baseUrl}vendor/react${debugString}.js`,
+    `${options.baseUrl}vendor/react-dom${debugString}.js`,
+    `${options.baseUrl}vendor/prop-types.js`,
+    `${options.baseUrl}vendor/react-intl.js`,
+    `${options.baseUrl}vendor/redux.js`,
+    `${options.baseUrl}vendor/react-redux.js`,
+    `${options.baseUrl}prerendered/${options.locale}/activity-stream-strings.js`,
+    `${options.baseUrl}data/content/activity-stream.bundle.js`
+  ];
+  if (isPrerendered) {
+    scripts.unshift(`${options.baseUrl}prerendered/static/activity-stream-initial-state.js`);
+  }
+  return `<!doctype html>
+<html lang="${options.locale}" dir="${options.direction}">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="Content-Security-Policy-Report-Only" content="script-src 'unsafe-inline'; img-src http: https: data: blob:; style-src 'unsafe-inline'; child-src 'none'; object-src 'none'; report-uri https://tiles.services.mozilla.com/v4/links/activity-stream/csp">
+    <title>${options.strings.newtab_page_title}</title>
+    <link rel="icon" type="image/png" href="chrome://branding/content/icon32.png"/>
+    <link rel="stylesheet" href="chrome://browser/content/contentSearchUI.css" />
+    <link rel="stylesheet" href="${options.baseUrl}css/activity-stream.css" />
+  </head>
+  <body class="activity-stream">
+    <div id="root">${isPrerendered ? html : ""}</div>
+    <div id="snippets-container">
+      <div id="snippets"></div>
+    </div>
+    <script>
+// Don't directly load the following scripts as part of html to let the page
+// finish loading to render the content sooner.
+for (const src of ${JSON.stringify(scripts, null, 2)}) {
+  // These dynamically inserted scripts by default are async, but we need them
+  // to load in the desired order (i.e., bundle last).
+  const script = document.body.appendChild(document.createElement("script"));
+  script.async = false;
+  script.src = src;
+}
+    </script>
+  </body>
+</html>
+`;
+}
+
+/**
+ * templateJs - Generates a js file that passes the initial state of the prerendered
+ * DOM to the React version. This is necessary to ensure the checksum matches when
+ * React mounts so that it can attach to the prerendered elements instead of blowing
+ * them away.
+ *
+ * Note that this may no longer be necessary in React 16 and we should review whether
+ * it is still necessary.
+ *
+ * @param  {string} name The name of the global to expose
+ * @param  {string} desc Extra description to include in a js comment
+ * @param  {obj}   state The data to expose as a window global
+ * @return {str}         The js file as a string
+ */
+function templateJs(name, desc, state) {
+  return `// Note - this is a generated ${desc} file.
+window.${name} = ${JSON.stringify(state, null, 2)};
+`;
+}
+
+/**
+ * writeFiles - Writes to the desired files the result of a template given
+ * various prerendered data and options.
+ *
+ * @param {string} name          Something to identify in the console
+ * @param {string} destPath      Path to write the files to
+ * @param {Map}    filesMap      Mapping of a string file name to templater
+ * @param {Object} prerenderData Contains the html and state
+ * @param {Object} options       Various options for the templater
+ */
+function writeFiles(name, destPath, filesMap, {html, state}, options) {
+  for (const [file, templater] of filesMap) {
+    fs.writeFileSync(path.join(destPath, file), templater({html, options, state}));
+  }
+  console.log("\x1b[32m", `✓ ${name}`, "\x1b[0m");
+}
+
+const STATIC_FILES = new Map([
+  ["activity-stream-debug.html", ({options}) => templateHTML(options)],
+  ["activity-stream-initial-state.js", ({state}) => templateJs("gActivityStreamPrerenderedState", "static", state)],
+  ["activity-stream-prerendered-debug.html", ({html, options}) => templateHTML(options, html)]
+]);
+
+const LOCALIZED_FILES = new Map([
+  ["activity-stream-prerendered.html", ({html, options}) => templateHTML(options, html)],
+  ["activity-stream-strings.js", ({options: {locale, strings}}) => templateJs("gActivityStreamStrings", locale, strings)],
+  ["activity-stream.html", ({options}) => templateHTML(options)]
+]);
+
+/**
+ * main - Parses command line arguments, generates html and js with templates,
+ *        and writes files to their specified locations.
+ */
+function main() { // eslint-disable-line max-statements
+  // This code parses command line arguments passed to this script.
+  // Note: process.argv.slice(2) is necessary because the first two items in
+  // process.argv are paths
+  const args = require("minimist")(process.argv.slice(2), {
+    alias: {
+      addonPath: "a",
+      baseUrl: "b"
+    }
+  });
+
+  const baseOptions = Object.assign({debug: false}, DEFAULT_OPTIONS, args || {});
+  const addonPath = path.resolve(__dirname, baseOptions.addonPath);
+  const allStrings = require(`${baseOptions.addonPath}/data/locales.json`);
+  const extraLocales = Object.keys(allStrings).filter(locale =>
+    locale !== DEFAULT_LOCALE && !CENTRAL_LOCALES.includes(locale));
+
+  const prerenderedPath = path.join(addonPath, "prerendered");
+  console.log(`Writing prerendered files to individual directories under ${prerenderedPath}:`);
+
+  // Save default locale's strings to compare against other locales' strings
+  let defaultStrings;
+  let langStrings;
+  const isSubset = (strings, existing) => existing &&
+    Object.keys(strings).every(key => strings[key] === existing[key]);
+
+  // Process the default locale first then all the ones from mozilla-central
+  const localizedLocales = [];
+  const skippedLocales = [];
+  for (const locale of [DEFAULT_LOCALE, ...CENTRAL_LOCALES, ...extraLocales]) {
+    // Skip the locale if it would have resulted in duplicate packaged files
+    const strings = getStrings(locale, allStrings);
+    if (isSubset(strings, defaultStrings) || isSubset(strings, langStrings)) {
+      skippedLocales.push(locale);
+      continue;
+    }
+
+    const prerenderData  = prerender(locale, strings);
+    const options = Object.assign({}, baseOptions, {
+      direction: getTextDirection(locale),
+      locale,
+      strings
+    });
+
+    // Put locale-specific files in their own directory
+    const localePath = path.join(prerenderedPath, "locales", locale);
+    mkdir("-p", localePath);
+    writeFiles(locale, localePath, LOCALIZED_FILES, prerenderData, options);
+
+    // Only write static files once for the default locale
+    if (locale === DEFAULT_LOCALE) {
+      const staticPath = path.join(prerenderedPath, "static");
+      mkdir("-p", staticPath);
+      writeFiles(`${locale} (static)`, staticPath, STATIC_FILES, prerenderData,
+        Object.assign({}, options, {debug: true}));
+
+      // Save the default strings to compare against other locales' strings
+      defaultStrings = strings;
+    }
+
+    // Save the language's strings to maybe reuse for the next similar locales
+    if (getLanguage(locale) === locale) {
+      langStrings = strings;
+    }
+
+    localizedLocales.push(locale);
+  }
+
+  if (skippedLocales.length) {
+    console.log("\x1b[33m", `Skipped the following locales because they use the same strings as ${DEFAULT_LOCALE} or its language locale: ${skippedLocales.join(", ")}`, "\x1b[0m");
+  }
+  if (extraLocales.length) {
+    console.log("\x1b[31m", `✗ These locales were not in CENTRAL_LOCALES, but probably should be: ${extraLocales.join(", ")}`, "\x1b[0m");
+  }
+
+  // Provide some help to copy/paste locales if tests are failing
+  console.log(`\nIf aboutNewTabService tests are failing for unexpected locales, make sure its list is updated:\nconst ACTIVITY_STREAM_LOCALES = "${localizedLocales.join(" ")}".split(" ");`);
+}
+
+main();
new file mode 100755
--- /dev/null
+++ b/browser/extensions/activity-stream/bin/strings-import.js
@@ -0,0 +1,75 @@
+#! /usr/bin/env node
+"use strict";
+
+/* eslint-disable no-console */
+const fetch = require("node-fetch");
+
+/* globals cd, ls, mkdir, rm, ShellString */
+require("shelljs/global");
+
+const DEFAULT_LOCALE = "en-US";
+const L10N_CENTRAL = "https://hg.mozilla.org/l10n-central";
+const PROPERTIES_PATH = "raw-file/default/browser/chrome/browser/activity-stream/newtab.properties";
+const STRINGS_FILE = "strings.properties";
+
+// Get all the locales in l10n-central
+async function getLocales() {
+  console.log(`Getting locales from ${L10N_CENTRAL}`);
+
+  // Add all non-test sub repository locales
+  const locales = [];
+  const subrepos = await (await fetch(`${L10N_CENTRAL}?style=json`)).json();
+  subrepos.entries.forEach(({name}) => {
+    if (name !== "x-testing") {
+      locales.push(name);
+    }
+  });
+
+  console.log(`Got ${locales.length} locales: ${locales}`);
+  return locales;
+}
+
+// Save the properties file to the locale's directory
+async function saveProperties(locale) {
+  // Only save a file if the repository has the file
+  const url = `${L10N_CENTRAL}/${locale}/${PROPERTIES_PATH}`;
+  const response = await fetch(url);
+  if (!response.ok) {
+    // Indicate that this locale didn't save
+    return locale;
+  }
+
+  // Save the file to the right place
+  const text = await response.text();
+  mkdir(locale);
+  cd(locale);
+  ShellString(text).to(STRINGS_FILE);
+  cd("..");
+
+  // Indicate that we were successful in saving
+  return "";
+}
+
+// Replace and update each locale's strings
+async function updateLocales() {
+  console.log("Switching to and deleting existing l10n tree under: locales");
+
+  cd("locales");
+  ls().forEach(dir => {
+    // Keep the default/source locale as it might have newer strings
+    if (dir !== DEFAULT_LOCALE) {
+      rm("-r", dir);
+    }
+  });
+
+  // Save the properties file for each locale in parallel
+  const locales = await getLocales();
+  const missing = (await Promise.all(locales.map(saveProperties))).filter(v => v);
+  console.log(`Skipped ${missing.length} locales without strings: ${missing.sort()}`);
+
+  console.log(`
+Please check the diffs, add/remove files, and then commit the result. Suggested commit message:
+chore(l10n): Update from l10n-central ${new Date()}`);
+}
+
+updateLocales().catch(console.error);
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/bin/test-merges.js
@@ -0,0 +1,344 @@
+#! /usr/bin/env node
+"use strict";
+
+/* eslint-disable no-console, mozilla/no-task */
+/* this is a node script; primary interaction is via console */
+
+const Task = require("co-task");
+const process = require("process");
+const path = require("path");
+const GitHubApi = require("@octokit/rest");
+const shelljs = require("shelljs");
+const child_process = require("child_process");
+const github = new GitHubApi();
+
+// some of our API requests need to be authenticated
+let token = process.env.AS_PINE_TOKEN;
+github.authenticate({type: "token", token});
+
+// note that this token MUST have the public_repo scope set in the github API
+
+const AS_REPO_OWNER = process.env.AS_REPO_OWNER || "mozilla";
+const AS_REPO_NAME = process.env.AS_REPO_NAME || "activity-stream";
+const AS_REPO = `${AS_REPO_OWNER}/${AS_REPO_NAME}`;
+const OLDEST_PR_DATE = "2017-03-17";
+const HG = "hg"; // mercurial
+const HG_BRANCH_NAME = "pine";
+const ALREADY_PUSHED_LABEL = "pushed-to-pine";
+const TREEHERDER_PREFIX = "https://treeherder.mozilla.org/#/jobs?repo=pine&revision=";
+
+// Path to the working directory where the export/commit operations will be
+// done.  Highly advisted to be used only for this testing purpose so you don't
+// accidently clobber real work.
+//
+// There will be two child directories:
+//
+// activity-stream - the github repo to be exported from.  MUST
+//
+// * be cloned by hand before running this script
+// * be 'npm install'ed
+// * have the ${ALREADY_PUSHED_LABEL} label created by hand
+// * have the user who has issued AS_PINE_TOKEN as a collaborator for the repo
+//   in order to be able to change labels.
+//
+// mozilla-central - the hg repo for firefox. Will be created if it doesn't
+// already exist.
+const {AS_PINE_TEST_DIR} = process.env;
+
+const TESTING_LOCAL_MC = path.join(AS_PINE_TEST_DIR, "mozilla-central");
+
+const SimpleGit = require("simple-git");
+const TESTING_LOCAL_GIT = path.join(AS_PINE_TEST_DIR, AS_REPO_NAME);
+const git = new SimpleGit(TESTING_LOCAL_GIT);
+
+// Mostly useful to specify during development of the test automation so that
+// prepare-mochitests-dev and friends from the development repo get used
+// instead of from the testing repo, which won't have had any changes checked in
+// just yet.
+const AS_GIT_BIN_REPO = process.env.AS_GIT_BIN_REPO || TESTING_LOCAL_GIT;
+
+const PREPARE_MOCHITESTS_DEV =
+  path.join(AS_GIT_BIN_REPO, "bin", "prepare-mochitests-dev");
+
+/**
+ * Find all PRs merged since ${OLDEST_PR_DATE} that don't have
+ * ${ALREADY_PUSHED_LABEL}
+ *
+ * @return {Promise} Promise that resolves with the search results or rejects
+ */
+function findNewlyMergedPRs() {
+  const searchTerms = [
+    // closed PRs in our repo
+    `repo:${AS_REPO}`, "type:pr", "state:closed", "is:merged",
+
+    // don't try and mochitest old closed stuff, we don't want to kick off a
+    // zillion test jobs
+    `merged:>=${OLDEST_PR_DATE}`,
+
+    // only look at merges to master
+    "base:master",
+
+    // if it's already been pushed to pine, don't do it again
+    `-label:${ALREADY_PUSHED_LABEL}`
+  ];
+
+  console.log(`Searching ${AS_REPO} for newly merged PRs`);
+  return github.search.issues({q: searchTerms.join("+")});
+}
+
+/**
+ * Return the commitId when the given PR was merged.  This is the one
+ * we will want to export and test.
+ *
+ * @param  {String} prNumber  The number of the PR to export.
+ * @return {String}           The commitId associated with the merge of this PR.
+ */
+function getPRMergeCommitId(prNumber) {
+  return github.issues.getEvents({
+    owner: AS_REPO_OWNER,
+    repo: AS_REPO_NAME,
+    issue_number: prNumber
+  }).then(({data}) => {
+    if (data.incomplete_results) {
+      // XXX should handle this case theoretically, but since we'll be running
+      // regularly from cron, it seems unlikely that we'll even hit 30 new
+      // merges (default GitHub page size) in a single run.
+      throw new Error("data.incomplete_results is true, aborting");
+    }
+
+    let mergeEvents = data.filter(item => item.event === "merged");
+    if (mergeEvents.length > 1) {
+      throw new Error("more than one merge event, aborting");
+    } else if (!mergeEvents.length) {
+      throw new Error(`Github returned no merge events for PR ${prNumber}, aborting.  Workaround: mark this PR as pushed-to-pine, so it gets skipped`);
+    }
+    let [mergeEvent] = mergeEvents;
+
+    if (!mergeEvent.commit_id) {
+      throw new Error("merge event has no commit id attached, aborted");
+    }
+
+    return mergeEvent.commit_id;
+  }).catch(err => { throw err; });
+}
+
+/**
+ * Checks out the given commit into ${TESTING_LOCAL_GIT}
+ *
+ * @param  {String} commitId
+ * @return {Promise<String[]|?>} Resolves with commit [id, message] on checkout, or
+ *                      rejects with error
+ */
+function checkoutGitCommit(commitId) {
+  return new Promise((resolve, reject) => {
+    console.log(`Fetching changes from github remote ${AS_REPO}...`);
+    // fetch any changes from the remote
+    git.fetch({}, (err, data) => {
+      if (err) {
+        reject(err);
+        return;
+      }
+      console.log(`Starting github checkout of ${commitId}...`);
+      git.checkout(commitId, (err2, data2) => {
+        if (err2) {
+          reject(err2);
+          return;
+        }
+
+        // Pass along the original commit message
+        git.show(["-s", "--format=%B"], (err3, data3) => {
+          if (err3) {
+            reject(err3);
+            return;
+          }
+          resolve([commitId, data3.trim()]);
+        });
+      });
+    });
+  });
+}
+
+function exportToLocalMC(commitId) {
+  return new Promise((resolve, reject) => {
+    console.log("Preparing mochitest dev environment...");
+    // Weirdly, /bin/yes causes npm-run-all bundle-static to explode, so we
+    // use echo.
+    shelljs.exec(`
+      echo yes | \
+        env AS_GIT_BIN_REPO=${AS_GIT_BIN_REPO} SYMLINK_TESTS=false \
+        ENABLE_MC_AS=1 ${PREPARE_MOCHITESTS_DEV}`,
+      {async: true, cwd: TESTING_LOCAL_GIT, silent: false}, (code, stdout, stderr) => {
+        if (code) {
+          reject(new Error(`${PREPARE_MOCHITESTS_DEV} failed, exit code: ${code}`));
+          return;
+        }
+
+        resolve(commitId);
+      });
+  });
+}
+
+function commitToHg([commitId, commitMsg]) {
+  return new Promise((resolve, reject) => {
+    // we use child_process.execFile here because shelljs.exec goes through
+    // the shell, which means that if the original commit message has shell
+    // quote characters, things can go haywire in weird ways.
+    console.log(`Committing exported ${commitId} to ${AS_REPO_NAME}...`);
+    child_process.execFile(HG,
+      [
+        "commit",
+        "--addremove",
+        "-m",
+        `${commitMsg}\n\nExport of ${commitId} from ${AS_REPO_OWNER}/${AS_REPO_NAME}`,
+        "."
+      ],
+      {cwd: TESTING_LOCAL_MC, env: process.env, timeout: 5 * 60 * 1000},
+      (code, stdout, stderr) => {
+        if (code) {
+          reject(new Error(`${HG} commit failed, output: ${stderr}`));
+          return;
+        }
+
+        resolve(code);
+      }
+    );
+  });
+}
+
+/**
+ * [pushToHgProjectBranch description]
+ *
+ * @return {Promise<String|Number>} resolves with the text written to XXXstdout, or
+ *                                  rejects with the exit code from ${HG}.
+ */
+function pushToHgProjectBranch() {
+  return new Promise((resolve, reject) => {
+    shelljs.exec(`${HG} push -f ${HG_BRANCH_NAME}`, {async: true, cwd: TESTING_LOCAL_MC},
+      (code, stdout, stderr) => {
+        if (code) {
+          reject(new Error(`${HG} failed, exit code: ${code}`));
+          return;
+        }
+
+        // Grab the last linked revision from the push output
+        const [rev] = stdout.split(/(?:\/rev\/|changeset=)/).slice(-1)[0].split("\n");
+        resolve(`[Treeherder: ${rev}](${TREEHERDER_PREFIX}${rev})`);
+      }
+    );
+  });
+}
+
+/**
+ * Remove last commit from the repo so the next artifact build will work right
+ */
+function stripTipFromHg() {
+  return new Promise((resolve, reject) => {
+    console.log("Stripping tip commit from mozilla-central so the next artifact build will work ...");
+    shelljs.exec(`${HG} strip --force --rev -1`,
+      {async: true, cwd: TESTING_LOCAL_MC},
+      (code, stdout, stderr) => {
+        if (code) {
+          reject(new Error(`${HG} strip failed, output: ${stderr}`));
+          return;
+        }
+
+        resolve(code);
+      }
+    );
+  });
+}
+
+function annotateGithubPR(prNumber, annotation) {
+  console.log(`Annotating ${prNumber} with ${annotation}...`);
+
+  // We use createComment from issues instead of pullRequests because we're
+  // not commenting on a particular commit
+  return github.issues.createComment({
+    owner: AS_REPO_OWNER,
+    repo: AS_REPO_NAME,
+    number: prNumber,
+    body: annotation
+  }).catch(reason => console.log(reason));
+}
+
+/**
+ * Labels a given github PR ${ALREADY_PUSHED_LABEL}.
+ */
+function labelGithubPR(prNumber) {
+  console.log(`Labeling PR ${prNumber} with ${ALREADY_PUSHED_LABEL}...`);
+
+  return github.issues.addLabels({
+    owner: AS_REPO_OWNER,
+    repo: AS_REPO_NAME,
+    number: prNumber,
+    labels: [ALREADY_PUSHED_LABEL]
+  }).catch(reason => console.log(reason));
+}
+
+function pushPR(pr) {
+  return getPRMergeCommitId(pr.number)
+
+    // get the merged commit to test
+    .then(checkoutGitCommit)
+
+    // use prepare-mochitest-dev to export
+    .then(exportToLocalMC)
+
+    // commit latest export to hg
+    .then(commitToHg)
+
+    // hg push
+    .then(() => pushToHgProjectBranch().catch(() => {
+      stripTipFromHg();
+      throw new Error("pushToHgProjectBranch failed; tip stripped from hg");
+    }))
+
+    // annotate PR with URL to watch
+    .then(annotation => annotateGithubPR(pr.number, annotation))
+
+    // make sure next artifact build doesn't explode
+    .then(() => stripTipFromHg())
+
+    // label with ${ALREADY_PUSHED_LABEL}
+    .then(() => labelGithubPR(pr.number))
+
+    .catch(err => {
+      console.log(err);
+      throw err;
+    });
+}
+
+function main() {
+  findNewlyMergedPRs().then(({data}) => {
+    if (data.incomplete_results) {
+      throw new Error("data.incomplete_results is true, aborting");
+    }
+
+    if (data.items.length === 0) {
+      console.log("No newly merged PRs to test");
+      return;
+    }
+
+    function* executePush() {
+      for (let pr of data.items) {
+        yield pushPR(pr);
+      }
+    }
+
+    // Serialize the execution of the export and pushing tests since each
+    // depend on exclusive access the state of the git and hg repos used to
+    // stage the tests.
+    Task.spawn(executePush).then(() => {
+      console.log("Processed all new merges.");
+    }).catch(reason => {
+      console.log("Something went wrong processing the merges:", reason);
+      process.exitCode = -1;
+    });
+  })
+  .catch(reason => {
+    console.error(reason);
+    process.exitCode = -1;
+  });
+}
+
+main();
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/bin/update-version.js
@@ -0,0 +1,62 @@
+#! /usr/bin/env node
+/* globals cd, sed */
+"use strict";
+
+/**
+ * Generate update install.rdf.in in the given directory with a version string
+ * composed of YYYY.MM.DD.${minuteOfDay}-${github_commit_hash}.
+ *
+ * @note The github hash is taken from the github repo in the current directory
+ * the script is run in.
+ *
+ * @note The minute of the day was chosen so that the version number is
+ * (more-or-less) consistently increasing (modulo clock-skew and builds that
+ * happen within a minute of each other), and although it's UTC, it won't likely
+ * be confused with something in a readers own time zone.
+ *
+ * @example generated version string: 2017.08.28.1217-ebda466c
+ */
+const process = require("process");
+require("shelljs/global");
+const simpleGit = require("simple-git")(process.cwd());
+
+const time = new Date();
+const minuteOfDay = time.getUTCHours() * 60 + time.getUTCMinutes();
+
+/**
+ * Return the given string padded with 0s out to the given width.
+ *
+ * XXX we should ditch this function in favor of using padStart once
+ * we start requiring Node 8.
+ *
+ * @param {any} s - the string to pad, will be coerced to String first
+ * @param {Number} width - what's the desired width?
+ */
+function zeroPadStart(s, width) {
+  let padded = String(s);
+  while (padded.length < width) {
+    padded = `0${padded}`;
+  }
+
+  return padded;
+}
+
+// git rev-parse --short HEAD
+simpleGit.revparse(["--short", "HEAD"], (err, gitHash) => {
+  if (err) {
+    // eslint-disable-next-line no-console
+    console.error(`SimpleGit.revparse failed: ${err}`);
+    throw new Error(`SimpleGit.revparse failed: ${err}`);
+  }
+
+  // eslint-disable-next-line prefer-template
+  let versionString = String(time.getUTCFullYear()) +
+    "." + zeroPadStart(time.getUTCMonth() + 1, 2) +
+    "." + zeroPadStart(time.getUTCDate(), 2) +
+    "." + zeroPadStart(minuteOfDay, 4) +
+    "-" + gitHash.trim();
+
+  cd(process.argv[2]);
+  sed("-i", /(<em:version>).+(<\/em:version>)$/, `$1${versionString}$2`,
+      "install.rdf.in");
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/.eslintrc.js
@@ -0,0 +1,5 @@
+module.exports = {
+  rules: {
+    "import/no-commonjs": 2
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/activity-stream-prerender.jsx
@@ -0,0 +1,45 @@
+import {INITIAL_STATE, reducers} from "common/Reducers.jsm";
+import {actionTypes as at} from "common/Actions.jsm";
+import {Base} from "content-src/components/Base/Base";
+import {initStore} from "content-src/lib/init-store";
+import {PrerenderData} from "common/PrerenderData.jsm";
+import {Provider} from "react-redux";
+import React from "react";
+import ReactDOMServer from "react-dom/server";
+
+/**
+ * prerenderStore - Generate a store with the initial state required for a prerendered page
+ *
+ * @return {obj}         A store
+ */
+export function prerenderStore() {
+  const store = initStore(reducers, INITIAL_STATE);
+  store.dispatch({type: at.PREFS_INITIAL_VALUES, data: PrerenderData.initialPrefs});
+  PrerenderData.initialSections.forEach(data => store.dispatch({type: at.SECTION_REGISTER, data}));
+  return store;
+}
+
+export function prerender(locale, strings,
+                          renderToString = ReactDOMServer.renderToString) {
+  const store = prerenderStore();
+
+  const html = renderToString(
+    <Provider store={store}>
+      <Base
+        isPrerendered={true}
+        locale={locale}
+        strings={strings} />
+    </Provider>);
+
+  // If this happens, it means pre-rendering is effectively disabled, so we
+  // need to sound the alarms:
+  if (!html || !html.length) {
+    throw new Error("no HTML returned");
+  }
+
+  return {
+    html,
+    state: store.getState(),
+    store
+  };
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/activity-stream.jsx
@@ -0,0 +1,30 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {addSnippetsSubscriber} from "content-src/lib/snippets";
+import {Base} from "content-src/components/Base/Base";
+import {DetectUserSessionStart} from "content-src/lib/detect-user-session-start";
+import {initStore} from "content-src/lib/init-store";
+import {Provider} from "react-redux";
+import React from "react";
+import ReactDOM from "react-dom";
+import {reducers} from "common/Reducers.jsm";
+
+const store = initStore(reducers, global.gActivityStreamPrerenderedState);
+
+new DetectUserSessionStart(store).sendEventOrAddListener();
+
+// If we are starting in a prerendered state, we must wait until the first render
+// to request state rehydration (see Base.jsx). If we are NOT in a prerendered state,
+// we can request it immedately.
+if (!global.gActivityStreamPrerenderedState) {
+  store.dispatch(ac.AlsoToMain({type: at.NEW_TAB_STATE_REQUEST}));
+}
+
+ReactDOM.hydrate(<Provider store={store}>
+  <Base
+    isFirstrun={global.document.location.href === "about:welcome"}
+    isPrerendered={!!global.gActivityStreamPrerenderedState}
+    locale={global.document.documentElement.lang}
+    strings={global.gActivityStreamStrings} />
+</Provider>, document.getElementById("root"));
+
+addSnippetsSubscriber(store);
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/asrouter-content.jsx
@@ -0,0 +1,188 @@
+import {actionCreators as ac, ASRouterActions as ra} from "common/Actions.jsm";
+import {OUTGOING_MESSAGE_NAME as AS_GENERAL_OUTGOING_MESSAGE_NAME} from "content-src/lib/init-store";
+import {ImpressionsWrapper} from "./components/ImpressionsWrapper/ImpressionsWrapper";
+import {OnboardingMessage} from "./templates/OnboardingMessage/OnboardingMessage";
+import React from "react";
+import ReactDOM from "react-dom";
+import {SimpleSnippet} from "./templates/SimpleSnippet/SimpleSnippet";
+
+const INCOMING_MESSAGE_NAME = "ASRouter:parent-to-child";
+const OUTGOING_MESSAGE_NAME = "ASRouter:child-to-parent";
+
+export const ASRouterUtils = {
+  addListener(listener) {
+    global.addMessageListener(INCOMING_MESSAGE_NAME, listener);
+  },
+  removeListener(listener) {
+    global.removeMessageListener(INCOMING_MESSAGE_NAME, listener);
+  },
+  sendMessage(action) {
+    global.sendAsyncMessage(OUTGOING_MESSAGE_NAME, action);
+  },
+  blockById(id) {
+    ASRouterUtils.sendMessage({type: "BLOCK_MESSAGE_BY_ID", data: {id}});
+  },
+  blockBundle(bundle) {
+    ASRouterUtils.sendMessage({type: "BLOCK_BUNDLE", data: {bundle}});
+  },
+  executeAction({button_action, button_action_params}) {
+    if (button_action in ra) {
+      ASRouterUtils.sendMessage({type: button_action, data: {button_action_params}});
+    }
+  },
+  unblockById(id) {
+    ASRouterUtils.sendMessage({type: "UNBLOCK_MESSAGE_BY_ID", data: {id}});
+  },
+  unblockBundle(bundle) {
+    ASRouterUtils.sendMessage({type: "UNBLOCK_BUNDLE", data: {bundle}});
+  },
+  getNextMessage() {
+    ASRouterUtils.sendMessage({type: "GET_NEXT_MESSAGE"});
+  },
+  overrideMessage(id) {
+    ASRouterUtils.sendMessage({type: "OVERRIDE_MESSAGE", data: {id}});
+  },
+  sendTelemetry(ping) {
+    const payload = ac.ASRouterUserEvent(ping);
+    global.sendAsyncMessage(AS_GENERAL_OUTGOING_MESSAGE_NAME, payload);
+  }
+};
+
+// Note: nextProps/prevProps refer to props passed to <ImpressionsWrapper />, not <ASRouterUISurface />
+function shouldSendImpressionOnUpdate(nextProps, prevProps) {
+  return (nextProps.message.id && (!prevProps.message || prevProps.message.id !== nextProps.message.id));
+}
+
+export class ASRouterUISurface extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.onMessageFromParent = this.onMessageFromParent.bind(this);
+    this.sendImpression = this.sendImpression.bind(this);
+    this.sendUserActionTelemetry = this.sendUserActionTelemetry.bind(this);
+    this.state = {message: {}, bundle: {}};
+  }
+
+  sendUserActionTelemetry(extraProps = {}) {
+    const {message, bundle} = this.state;
+    if (!message && !extraProps.message_id) {
+      throw new Error(`You must provide a message_id for bundled messages`);
+    }
+    const eventType = `${message.provider || bundle.provider}_user_event`;
+    ASRouterUtils.sendTelemetry({
+      message_id: message.id || extraProps.message_id,
+      source: extraProps.id,
+      action: eventType,
+      ...extraProps
+    });
+  }
+
+  sendImpression(extraProps) {
+    this.sendUserActionTelemetry({event: "IMPRESSION", ...extraProps});
+  }
+
+  onBlockById(id) {
+    return () => ASRouterUtils.blockById(id);
+  }
+
+  clearBundle(bundle) {
+    return () => ASRouterUtils.blockBundle(bundle);
+  }
+
+  onMessageFromParent({data: action}) {
+    switch (action.type) {
+      case "SET_MESSAGE":
+        this.setState({message: action.data});
+        break;
+      case "SET_BUNDLED_MESSAGES":
+        this.setState({bundle: action.data});
+        break;
+      case "CLEAR_MESSAGE":
+        if (action.data.id === this.state.message.id) {
+          this.setState({message: {}});
+        }
+        break;
+      case "CLEAR_BUNDLE":
+        if (this.state.bundle.bundle) {
+          this.setState({bundle: {}});
+        }
+        break;
+      case "CLEAR_ALL":
+        this.setState({message: {}, bundle: {}});
+    }
+  }
+
+  componentWillMount() {
+    ASRouterUtils.addListener(this.onMessageFromParent);
+    ASRouterUtils.sendMessage({type: "CONNECT_UI_REQUEST"});
+  }
+
+  componentWillUnmount() {
+    ASRouterUtils.removeListener(this.onMessageFromParent);
+  }
+
+  renderSnippets() {
+    return (
+      <ImpressionsWrapper
+        id="NEWTAB_FOOTER_BAR"
+        message={this.state.message}
+        sendImpression={this.sendImpression}
+        shouldSendImpressionOnUpdate={shouldSendImpressionOnUpdate}
+        // This helps with testing
+        document={this.props.document}>
+          <SimpleSnippet
+            {...this.state.message}
+            UISurface="NEWTAB_FOOTER_BAR"
+            getNextMessage={ASRouterUtils.getNextMessage}
+            onBlock={this.onBlockById(this.state.message.id)}
+            sendUserActionTelemetry={this.sendUserActionTelemetry} />
+      </ImpressionsWrapper>);
+  }
+
+  renderOnboarding() {
+    return (
+      <OnboardingMessage
+        {...this.state.bundle}
+        UISurface="NEWTAB_OVERLAY"
+        onAction={ASRouterUtils.executeAction}
+        onDoneButton={this.clearBundle(this.state.bundle.bundle)}
+        getNextMessage={ASRouterUtils.getNextMessage}
+        sendUserActionTelemetry={this.sendUserActionTelemetry} />);
+  }
+
+  render() {
+    const {message, bundle} = this.state;
+    if (!message.id && !bundle.template) { return null; }
+    if (bundle.template === "onboarding") { return this.renderOnboarding(); }
+    return this.renderSnippets();
+  }
+}
+
+ASRouterUISurface.defaultProps = {document: global.document};
+
+export class ASRouterContent {
+  constructor() {
+    this.initialized = false;
+    this.containerElement = null;
+  }
+
+  _mount() {
+    this.containerElement = global.document.getElementById("snippets-container");
+    ReactDOM.render(<ASRouterUISurface />, this.containerElement);
+  }
+
+  _unmount() {
+    ReactDOM.unmountComponentAtNode(this.containerElement);
+  }
+
+  init() {
+    this._mount();
+    this.initialized = true;
+  }
+
+  uninit() {
+    if (this.initialized) {
+      this._unmount();
+      this.initialized = false;
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/components/Button/Button.jsx
@@ -0,0 +1,26 @@
+import React from "react";
+import {safeURI} from "../../template-utils";
+
+const ALLOWED_STYLE_TAGS = ["color", "backgroundColor"];
+
+export const Button = props => {
+  const style = {};
+
+  // Add allowed style tags from props, e.g. props.color becomes style={color: props.color}
+  for (const tag of ALLOWED_STYLE_TAGS) {
+    if (typeof props[tag] !== "undefined") {
+      style[tag] = props[tag];
+    }
+  }
+  // remove border if bg is set to something custom
+  if (style.backgroundColor) {
+    style.border = "0";
+  }
+
+  return (<a href={safeURI(props.url)}
+    onClick={props.onClick}
+    className={props.className || "ASRouterButton"}
+    style={style}>
+    {props.children}
+  </a>);
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/components/Button/_Button.scss
@@ -0,0 +1,13 @@
+.ASRouterButton {
+  white-space: nowrap;
+  border-radius: 4px;
+  border: 1px solid var(--newtab-border-secondary-color);
+  background-color: var(--newtab-button-secondary-color);
+  font-family: inherit;
+  padding: 8px 15px;
+  margin-inline-start: 12px;
+  color: inherit;
+  .tall & {
+    margin-inline-start: 20px;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/components/ImpressionsWrapper/ImpressionsWrapper.jsx
@@ -0,0 +1,60 @@
+import React from "react";
+
+export const VISIBLE = "visible";
+export const VISIBILITY_CHANGE_EVENT = "visibilitychange";
+
+/**
+ * Component wrapper used to send telemetry pings on every impression.
+ */
+export class ImpressionsWrapper extends React.PureComponent {
+  // This sends an event when a user sees a set of new content. If content
+  // changes while the page is hidden (i.e. preloaded or on a hidden tab),
+  // only send the event if the page becomes visible again.
+  sendImpressionOrAddListener() {
+    if (this.props.document.visibilityState === VISIBLE) {
+      this.props.sendImpression({id: this.props.id});
+    } else {
+      // We should only ever send the latest impression stats ping, so remove any
+      // older listeners.
+      if (this._onVisibilityChange) {
+        this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
+      }
+
+      // When the page becomes visible, send the impression stats ping if the section isn't collapsed.
+      this._onVisibilityChange = () => {
+        if (this.props.document.visibilityState === VISIBLE) {
+          this.props.sendImpression({id: this.props.id});
+          this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
+        }
+      };
+      this.props.document.addEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
+    }
+  }
+
+  componentWillUnmount() {
+    if (this._onVisibilityChange) {
+      this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
+    }
+  }
+
+  componentDidMount() {
+    if (this.props.sendOnMount) {
+      this.sendImpressionOrAddListener();
+    }
+  }
+
+  componentDidUpdate(prevProps) {
+    if (this.props.shouldSendImpressionOnUpdate(this.props, prevProps)) {
+      this.sendImpressionOrAddListener();
+    }
+  }
+
+  render() {
+    return this.props.children;
+  }
+}
+
+ImpressionsWrapper.defaultProps = {
+  document: global.document,
+  sendOnMount: true
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/components/ModalOverlay/ModalOverlay.jsx
@@ -0,0 +1,30 @@
+import React from "react";
+
+export class ModalOverlay extends React.PureComponent {
+  componentWillMount() {
+    this.setState({active: true});
+    document.body.classList.add("modal-open");
+  }
+
+  componentWillUnmount() {
+    document.body.classList.remove("modal-open");
+    this.setState({active: false});
+  }
+
+  render() {
+    const {active} = this.state;
+    const {title, button_label} = this.props;
+    return (
+      <div>
+        <div className={`modalOverlayOuter ${active ? "active" : ""}`} />
+        <div className={`modalOverlayInner ${active ? "active" : ""}`}>
+          <h2> {title} </h2>
+          {this.props.children}
+          <div className="footer">
+            <button onClick={this.props.onDoneButton} className="button primary modalButton"> {button_label} </button>
+          </div>
+        </div>
+      </div>
+    );
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/components/ModalOverlay/_ModalOverlay.scss
@@ -0,0 +1,93 @@
+.activity-stream {
+  &.modal-open {
+    overflow: hidden;
+  }
+}
+.modalOverlayOuter {
+  background: $white;
+  opacity: 0.93;
+  height: 100%;
+  position: fixed;
+  top: 0;
+  width: 100%;
+  display: none;
+  z-index: 100000;
+
+  &.active {
+    display: block;
+  }
+}
+
+.modalOverlayInner {
+  width: 960px;
+  height: 510px;
+  position: fixed;
+  top: calc(50% - 255px); // halfway down minus half the height of the modal
+  left: calc(50% - 480px); // halfway across minus half the width of the modal
+  background: $white;
+  box-shadow: 0 1px 15px 0 $black-30;
+  border-radius: 4px;
+  display: none;
+  z-index: 100001;
+
+
+  // modal takes over entire screen
+  @media(max-width: 960px) {
+    width: 100%;
+    height: 100%;
+    top: 0;
+    left: 0;
+    box-shadow: none;
+    border-radius: 0;
+  }
+
+  // if modal is short enough, add a vertical scroll bar
+  @media(max-width: 850px) and (max-height: 730px) {
+    overflow-y: scroll;
+  }
+
+  &.active {
+    display: block;
+  }
+
+  h2 {
+    color: $grey-60;
+    text-align: center;
+    font-weight: 200;
+    margin-top: 30px;
+    font-size: 28px;
+    line-height: 37px;
+    letter-spacing: -0.13px;
+
+    @media(max-width: 960px) {
+      margin-top: 100px;
+    }
+
+    @media(max-width: 850px) {
+      margin-top: 30px;
+    }
+  }
+
+  .footer {
+    border-top: 1px solid $grey-30;
+    height: 70px;
+    width: 100%;
+    position: absolute;
+    bottom: 0;
+    text-align: center;
+    background-color: $white;
+
+    // if modal is short enough, footer becomes sticky
+    @media(max-width: 850px) and (max-height: 730px) {
+      position: sticky;
+    }
+
+    .modalButton {
+      margin-top: 20px;
+      width: 150px;
+      height: 30px;
+      padding: 4px 0 6px 0;
+      font-size: 15px;
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/components/SnippetBase/SnippetBase.jsx
@@ -0,0 +1,26 @@
+import React from "react";
+
+export class SnippetBase extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.onBlockClicked = this.onBlockClicked.bind(this);
+  }
+
+  onBlockClicked() {
+    this.props.sendUserActionTelemetry({event: "BLOCK", id: this.props.UISurface});
+    this.props.onBlock();
+  }
+
+  render() {
+    const {props} = this;
+
+    const containerClassName = `SnippetBaseContainer${props.className ? ` ${props.className}` : ""}`;
+
+    return (<div className={containerClassName}>
+      <div className="innerWrapper">
+        {props.children}
+      </div>
+      <button className="blockButton" onClick={this.onBlockClicked} />
+    </div>);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/components/SnippetBase/_SnippetBase.scss
@@ -0,0 +1,58 @@
+.SnippetBaseContainer {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background-color: var(--newtab-snippets-background-color);
+  color: var(--newtab-text-primary-color);
+  font-size: 12px;
+  line-height: 16px;
+  border-top: 1px solid var(--newtab-snippets-hairline-color);
+  box-shadow: $shadow-secondary;
+  display: flex;
+  align-items: center;
+
+  .innerWrapper {
+    margin: 0 auto;
+    display: flex;
+    align-items: center;
+    padding: 12px $section-horizontal-padding;
+
+    // This is to account for the block button on smaller screens
+    padding-inline-end: 36px;
+    @media (min-width: $break-point-large) {
+      padding-inline-end: $section-horizontal-padding;
+    }
+
+    max-width: $wrapper-max-width-large;
+    @media (min-width: $break-point-widest) {
+      max-width: $wrapper-max-width-widest;
+    }
+  }
+
+  .blockButton {
+    display: none;
+    background: none;
+    border: 0;
+    position: absolute;
+    top: 50%;
+    offset-inline-end: 12px;
+    height: 16px;
+    width: 16px;
+    background-image: url('resource://activity-stream/data/content/assets/glyph-dismiss-16.svg');
+    -moz-context-properties: fill;
+    fill: var(--newtab-icon-primary-color);
+    opacity: 0.5;
+    margin-top: -8px;
+    padding: 0;
+    cursor: pointer;
+
+    @media (min-width: 766px) {
+      offset-inline-end: 24px;
+    }
+  }
+
+  &:hover .blockButton {
+    display: block;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/schemas/message-format.md
@@ -0,0 +1,44 @@
+## Activity Stream Router message format
+
+Field name | Type     | Required | Description | Example / Note
+---        | ---      | ---      | ---         | ---
+`id`       | `string` | Yes | A unique identifier for the message that should not conflict with any other previous message | `ONBOARDING_1`
+`template` | `string` | Yes | An id matching an existing Activity Stream Router template | [See example](https://github.com/mozilla/activity-stream/blob/33669c67c2269078a6d3d6d324fb48175d98f634/system-addon/content-src/message-center/templates/SimpleSnippet.jsx)
+`publish_start` | `date` | No | When to start showing the message | `1524474850876`
+`publish_end` | `date` | No | When to stop showing the message | `1524474850876`
+`content` | `object` | Yes | An object containing all variables/props to be rendered in the template. Subset of allowed tags detailed below. | [See example below](#html-subset)
+`campaign` | `string` | No | Campaign id that the message belongs to | `RustWebAssembly`
+`targeting` | `string` `JEXL` | Yes | A [JEXL expression](http://normandy.readthedocs.io/en/latest/user/filter_expressions.html#jexl-basics) with all targeting information needed in order to decide if the message is shown | Not yet implemented, [some examples](http://normandy.readthedocs.io/en/latest/user/filter_expressions.html#examples)
+
+### Message example
+```javascript
+{
+  id: "ONBOARDING_1",
+  template: "simple_snippet",
+  content: {
+    title: "Find it faster",
+    body: "Access all of your favorite search engines with a click. Search the whole Web or just one website from the search box."
+  }
+}
+```
+
+### HTML subset
+The following tags are allowed in the content of the snippet: `i, b, u, strong, em, br`.
+
+Links cannot be rendered using regular anchor tags because [Fluent does not allow for href attributes](https://github.com/projectfluent/fluent.js/blob/a03d3aa833660f8c620738b26c80e46b1a4edb05/fluent-dom/src/overlay.js#L13). They will be wrapped in custom tags, for example `<cta>link</cta>` and the url will be provided as part of the payload:
+```
+{
+  "id": "7899",
+  "content": {
+    "text": "Use the CMD (CTRL) + T keyboard shortcut to <cta>open a new tab quickly!</cta>",
+    "links": {
+      "cta": {
+        "url": "https://support.mozilla.org/en-US/kb/keyboard-shortcuts-perform-firefox-tasks-quickly"
+      }
+    }
+  }
+}
+```
+If a tag that is not on the allowed is used, the text content will be extracted and displayed.
+
+Grouping multiple allowed elements is not possible, only the first level will be used: `<u><b>text</b></u>` will be interpreted as `<u>text</u>`.
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/schemas/provider-response.schema.json
@@ -0,0 +1,37 @@
+{
+  "title": "ProviderResponse",
+  "description": "A response object for remote providers of AS Router",
+  "type": "object",
+  "properties": {
+    "messages": {
+      "type": "array",
+      "description": "An array of router messages",
+      "items": {
+        "title": "RouterMessage",
+        "description": "A definition of an individual message",
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "string",
+            "description": "A unique identifier for the message that should not conflict with any other previous message"
+          },
+          "template": {
+            "type": "string",
+            "description": "An id matching an existing Activity Stream Router template",
+            "enum": ["simple_snippet"]
+          },
+          "content": {
+            "type": "object",
+            "description": "An object containing all variables/props to be rendered in the template. See individual template schemas for details."
+          },
+          "targeting": {
+            "type": "string",
+            "description": "a JEXL expression representing targeting information"
+          }
+        },
+        "required": ["id", "template", "content"]
+      }
+    }
+  },
+  "required": ["messages"]
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/template-utils.js
@@ -0,0 +1,17 @@
+export function safeURI(url) {
+  if (!url) {
+    return "";
+  }
+  const {protocol} = new URL(url);
+  const isAllowed = [
+    "http:",
+    "https:",
+    "data:",
+    "resource:",
+    "chrome:"
+  ].includes(protocol);
+  if (!isAllowed) {
+    console.warn(`The protocol ${protocol} is not allowed for template URLs.`); // eslint-disable-line no-console
+  }
+  return isAllowed ? url : "";
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/templates/OnboardingMessage/OnboardingMessage.jsx
@@ -0,0 +1,52 @@
+import {ModalOverlay} from "../../components/ModalOverlay/ModalOverlay";
+import React from "react";
+
+class OnboardingCard extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.onClick = this.onClick.bind(this);
+  }
+
+  onClick() {
+    const {props} = this;
+    props.sendUserActionTelemetry({event: "CLICK_BUTTON", message_id: props.id, id: props.UISurface});
+    props.onAction(props.content);
+  }
+
+  render() {
+    const {content} = this.props;
+    return (
+      <div className="onboardingMessage">
+        <div className={`onboardingMessageImage ${content.icon}`} />
+        <div className="onboardingContent">
+          <span>
+            <h3> {content.title} </h3>
+            <p> {content.text} </p>
+          </span>
+          <span>
+            <button className="button onboardingButton" onClick={this.onClick}> {content.button_label} </button>
+          </span>
+        </div>
+      </div>
+    );
+  }
+}
+
+export class OnboardingMessage extends React.PureComponent {
+  render() {
+    const {props} = this;
+    return (
+      <ModalOverlay {...props} button_label={"Start Browsing"} title={"Welcome to Firefox"}>
+        <div className="onboardingMessageContainer">
+          {props.bundle.map(message => (
+            <OnboardingCard key={message.id}
+              sendUserActionTelemetry={props.sendUserActionTelemetry}
+              onAction={props.onAction}
+              UISurface={props.UISurface}
+              {...message} />
+          ))}
+        </div>
+      </ModalOverlay>
+    );
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/templates/OnboardingMessage/_OnboardingMessage.scss
@@ -0,0 +1,142 @@
+.onboardingMessageContainer {
+  display: grid;
+  grid-column-gap: 21px;
+  grid-template-columns: auto auto auto;
+  padding-left: 30px;
+  padding-right: 30px;
+
+  // at 850px, the cards go from vertical layout to horizontal layout
+  @media(max-width: 850px) {
+    grid-template-columns: none;
+    grid-template-rows: auto auto auto;
+    padding-left: 110px;
+    padding-right: 110px;
+  }
+}
+
+.onboardingMessage {
+  height: 340px;
+  text-align: center;
+  padding: 13px;
+  font-weight: 200;
+
+  // at 850px, img floats left, content floats right next to it
+  @media(max-width: 850px) {
+    height: 170px;
+    text-align: left;
+    padding: 10px;
+    border-bottom: 1px solid #D8D8D8;
+    display: flex;
+    margin-bottom: 11px;
+
+    &:last-child {
+      border: none;
+    }
+
+    .onboardingContent {
+      padding-left: 10px;
+      height: 100%;
+
+      > span > h3 {
+        margin-top: 0;
+        margin-bottom: 4px;
+        font-weight: 400;
+      }
+
+      > span > p {
+        margin-top: 0;
+        line-height: 22px;
+        font-size: 15px;
+      }
+    }
+  }
+
+  .onboardingMessageImage {
+    height: 100px;
+    width: 120px;
+    background-size: 120px;
+    background-position: center center;
+    background-repeat: no-repeat;
+    display: inline-block;
+    vertical-align: middle;
+
+
+    @media(max-width: 850px) {
+      height: 75px;
+      min-width: 80px;
+      background-size: 80px;
+    }
+
+    &.addons {
+      background-image: url("resource://activity-stream/data/content/assets/illustration-addons@2x.png");
+    }
+
+    &.privatebrowsing {
+      background-image: url("resource://activity-stream/data/content/assets/illustration-privatebrowsing@2x.png");
+    }
+
+    &.screenshots {
+      background-image: url("resource://activity-stream/data/content/assets/illustration-screenshots@2x.png");
+    }
+
+    &.gift {
+      background-image: url("resource://activity-stream/data/content/assets/illustration-gift@2x.png");
+    }
+  }
+
+  .onboardingContent {
+    height: 175px;
+
+    > span > h3 {
+      color: $grey-90;
+      margin-bottom: 8px;
+      font-weight: 400;
+    }
+
+    > span > p {
+      color: $grey-60;
+      margin-top: 0;
+      height: 130px;
+      margin-bottom: 12px;
+      font-size: 15px;
+      line-height: 22px;
+    }
+  }
+
+  .onboardingButton {
+    background-color: $grey-90-10;
+    border: none;
+    width: 150px;
+    height: 30px;
+    margin-bottom: 23px;
+    padding: 4px 0 6px 0;
+    font-size: 15px;
+
+    // at 850px, the button shimmies down and to the right
+    @media(max-width: 850px) {
+      float: right;
+      margin-top: -60px;
+      margin-right: -10px;
+    }
+  }
+
+
+  &::before {
+    content: '';
+    height: 220px;
+    width: 1px;
+    position: absolute;
+    background-color: #D8D8D8;
+    margin-top: 40px;
+    margin-left: 215px;
+
+    // at 850px, the line goes from vertical to horizontal
+    @media(max-width: 850px) {
+      content: none;
+    }
+  }
+
+  &:last-child::before {
+    content: none;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/templates/SimpleSnippet/SimpleSnippet.jsx
@@ -0,0 +1,53 @@
+import {Button} from "../../components/Button/Button";
+import React from "react";
+import {safeURI} from "../../template-utils";
+import {SnippetBase} from "../../components/SnippetBase/SnippetBase";
+
+const DEFAULT_ICON_PATH = "chrome://branding/content/icon64.png";
+
+export class SimpleSnippet extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.onButtonClick = this.onButtonClick.bind(this);
+  }
+
+  onButtonClick() {
+    this.props.sendUserActionTelemetry({event: "CLICK_BUTTON", id: this.props.UISurface});
+  }
+
+  renderTitle() {
+    const {title} = this.props.content;
+    return title ? <h3 className="title">{title}</h3> : null;
+  }
+
+  renderTitleIcon() {
+    const titleIcon = safeURI(this.props.content.title_icon);
+    return titleIcon ? <span className="titleIcon" style={{backgroundImage: `url("${titleIcon}")`}} /> : null;
+  }
+
+  renderButton(className) {
+    const {props} = this;
+    return (<Button
+      className={className}
+      onClick={this.onButtonClick}
+      url={props.content.button_url}
+      color={props.content.button_color}
+      backgroundColor={props.content.button_background_color}>
+      {props.content.button_label}
+    </Button>);
+  }
+
+  render() {
+    const {props} = this;
+    const hasLink = props.content.button_url && props.content.button_type === "anchor";
+    const hasButton = props.content.button_url && !props.content.button_type;
+    const className = `SimpleSnippet${props.content.tall ? " tall" : ""}`;
+    return (<SnippetBase {...props} className={className}>
+      <img src={safeURI(props.content.icon) || DEFAULT_ICON_PATH} className="icon" />
+      <div>
+        {this.renderTitleIcon()} {this.renderTitle()} <p className="body">{props.content.text}</p> {hasLink ? this.renderButton("ASRouterAnchor") : null}
+      </div>
+      {hasButton ? <div>{this.renderButton()}</div> : null}
+    </SnippetBase>);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/templates/SimpleSnippet/SimpleSnippet.schema.json
@@ -0,0 +1,66 @@
+{
+  "title": "SimpleSnippet",
+  "description": "A simple template with an icon, text, and optional button.",
+  "version": "0.2.0",
+  "type": "object",
+  "properties": {
+    "title": {
+      "type": "string",
+      "description": "Snippet title displayed before snippet text"
+    },
+    "text": {
+      "type": "string",
+      "description": "Main body text of snippet"
+    },
+    "icon": {
+      "type": "string",
+      "description": "Snippet icon. 64x64px. SVG or PNG preferred."
+    },
+    "title_icon": {
+      "type": "string",
+      "description": "Small icon that shows up before the title / text. 16x16px. SVG or PNG preferred. Grayscale."
+    },
+    "button_url": {
+      "type": "string",
+      "description": "A url, button_label links to this"
+    },
+    "button_label": {
+      "type": "string",
+      "description": "Text for a button next to main snippet text that links to button_url. Requires button_url."
+    },
+    "button_color": {
+      "type": "string",
+      "description": "The text color of the button. Valid CSS color."
+    },
+    "button_background_color": {
+      "type": "string",
+      "description": "The background color of the button. Valid CSS color."
+    },
+    "button_type": {
+      "type": "string",
+      "enum": ["anchor", "button"],
+      "description": "(**temporary**, until we get html support in text field Bug 1457233) Style for button, either a regular button or a text link."
+    },
+    "tall": {
+      "type": "boolean",
+      "description": "To be used by fundraising only, increases height to roughly 120px. Defaults to false."
+    },
+    "links": {
+      "additionalProperties": {
+        "url": {
+          "type": "string",
+          "description": "The url where the link points to."
+        }
+      }
+    }
+  },
+  "additionalProperties": false,
+  "required": ["text"],
+  "dependencies": {
+    "button_url": ["button_label"],
+    "button_label": ["button_url"],
+    "button_type": ["button_url"],
+    "button_color": ["button_url"],
+    "button_background_color": ["button_url"]
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/asrouter/templates/SimpleSnippet/_SimpleSnippet.scss
@@ -0,0 +1,42 @@
+.SimpleSnippet {
+  &.tall {
+    padding: 27px 0;
+  }
+
+  .title {
+    display: inline;
+    font-size: inherit;
+    margin: 0;
+  }
+
+  .titleIcon {
+    background-repeat: no-repeat;
+    background-size: 14px;
+    height: 16px;
+    width: 16px;
+    margin-top: 2px;
+    margin-inline-end: 2px;
+    display: inline-block;
+    vertical-align: top;
+  }
+
+  .body {
+    display: inline;
+    margin: 0;
+  }
+
+  .icon {
+    height: 42px;
+    width: 42px;
+    margin-inline-end: 12px;
+    flex-shrink: 0;
+  }
+  &.tall .icon {
+    margin-inline-end: 20px;
+  }
+
+  .ASRouterAnchor {
+    color: inherit;
+    text-decoration: underline;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx
@@ -0,0 +1,101 @@
+import {ASRouterUtils} from "../../asrouter/asrouter-content";
+import React from "react";
+
+export class ASRouterAdmin extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.onMessage = this.onMessage.bind(this);
+    this.findOtherBundledMessagesOfSameTemplate = this.findOtherBundledMessagesOfSameTemplate.bind(this);
+    this.state = {};
+  }
+
+  onMessage({data: action}) {
+    if (action.type === "ADMIN_SET_STATE") {
+      this.setState(action.data);
+    }
+  }
+
+  componentWillMount() {
+    ASRouterUtils.sendMessage({type: "ADMIN_CONNECT_STATE"});
+    ASRouterUtils.addListener(this.onMessage);
+  }
+
+  componentWillUnmount() {
+    ASRouterUtils.removeListener(this.onMessage);
+  }
+
+  findOtherBundledMessagesOfSameTemplate(template) {
+    return this.state.messages.filter(msg => msg.template === template && msg.bundled);
+  }
+
+  handleBlock(msg) {
+    if (msg.bundled) {
+      // If we are blocking a message that belongs to a bundle, block all other messages that are bundled of that same template
+      let bundle = this.findOtherBundledMessagesOfSameTemplate(msg.template);
+      return () => ASRouterUtils.blockBundle(bundle);
+    }
+    return () => ASRouterUtils.blockById(msg.id);
+  }
+
+  handleUnblock(msg) {
+    if (msg.bundled) {
+      // If we are unblocking a message that belongs to a bundle, unblock all other messages that are bundled of that same template
+      let bundle = this.findOtherBundledMessagesOfSameTemplate(msg.template);
+      return () => ASRouterUtils.unblockBundle(bundle);
+    }
+    return () => ASRouterUtils.unblockById(msg.id);
+  }
+
+  handleOverride(id) {
+    return () => ASRouterUtils.overrideMessage(id);
+  }
+
+  renderMessageItem(msg) {
+    const isCurrent = msg.id === this.state.lastMessageId;
+    const isBlocked = this.state.blockList.includes(msg.id);
+
+    let itemClassName = "message-item";
+    if (isCurrent) { itemClassName += " current"; }
+    if (isBlocked) { itemClassName += " blocked"; }
+
+    return (<tr className={itemClassName} key={msg.id}>
+      <td className="message-id"><span>{msg.id}</span></td>
+      <td>
+        <button className={`button ${(isBlocked ? "" : " primary")}`} onClick={isBlocked ? this.handleUnblock(msg) : this.handleBlock(msg)}>{isBlocked ? "Unblock" : "Block"}</button>
+       {isBlocked ? null : <button className="button" onClick={this.handleOverride(msg.id)}>Show</button>}
+      </td>
+      <td className="message-summary">
+        <pre>{JSON.stringify(msg, null, 2)}</pre>
+      </td>
+    </tr>);
+  }
+
+  renderMessages() {
+    if (!this.state.messages) {
+      return null;
+    }
+    return (<table><tbody>
+      {this.state.messages.map(msg => this.renderMessageItem(msg))}
+    </tbody></table>);
+  }
+
+  renderProviders() {
+    return (<table><tbody>
+      {this.state.providers.map((provider, i) => (<tr className="message-item" key={i}>
+        <td>{provider.id}</td>
+        <td>{provider.type === "remote" ? <a target="_blank" href={provider.url}>{provider.url}</a> : "(local)"}</td>
+      </tr>))}
+    </tbody></table>);
+  }
+
+  render() {
+    return (<div className="asrouter-admin outer-wrapper">
+      <h1>AS Router Admin</h1>
+      <button className="button primary" onClick={ASRouterUtils.getNextMessage}>Refresh Current Message</button>
+      <h2>Message Providers</h2>
+      {this.state.providers ? this.renderProviders() : null}
+      <h2>Messages</h2>
+      {this.renderMessages()}
+    </div>);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/ASRouterAdmin/ASRouterAdmin.scss
@@ -0,0 +1,78 @@
+
+.asrouter-admin {
+  $border-color: var(--newtab-border-secondary-color);
+  $monospace: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Mono', 'Droid Sans Mono', 'Source Code Pro', monospace;
+  max-width: 996px;
+  margin: 0 auto;
+  font-size: 14px;
+  // Reset .outer-wrapper styles
+  display: inherit;
+  padding: 0 0 92px;
+
+  h1 {
+    font-weight: 200;
+    font-size: 32px;
+  }
+
+  table {
+    border-collapse: collapse;
+    width: 100%;
+  }
+
+  .message-item {
+    &:first-child td {
+      border-top: 1px solid $border-color;
+    }
+
+    td {
+      vertical-align: top;
+      border-bottom: 1px solid $border-color;
+      padding: 8px;
+
+      &:first-child {
+        border-left: 1px solid $border-color;
+      }
+
+      &:last-child {
+        border-right: 1px solid $border-color;
+      }
+    }
+
+    &.current {
+      .message-id span {
+        background: $yellow-50;
+        padding: 2px 5px;
+
+        .dark-theme & {
+          color: $black;
+        }
+      }
+    }
+
+    &.blocked {
+      .message-id,
+      .message-summary {
+        opacity: 0.5;
+      }
+
+      .message-id {
+        opacity: 0.5;
+      }
+    }
+
+    .message-id {
+      font-family: $monospace;
+      font-size: 12px;
+    }
+  }
+
+  pre {
+    background: var(--newtab-textbox-background-color);
+    margin: 0;
+    padding: 8px;
+    font-size: 12px;
+    max-width: 750px;
+    overflow: auto;
+    font-family: $monospace;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/Base/Base.jsx
@@ -0,0 +1,148 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {addLocaleData, injectIntl, IntlProvider} from "react-intl";
+import {ASRouterAdmin} from "content-src/components/ASRouterAdmin/ASRouterAdmin";
+import {ConfirmDialog} from "content-src/components/ConfirmDialog/ConfirmDialog";
+import {connect} from "react-redux";
+import {ErrorBoundary} from "content-src/components/ErrorBoundary/ErrorBoundary";
+import {ManualMigration} from "content-src/components/ManualMigration/ManualMigration";
+import {PrerenderData} from "common/PrerenderData.jsm";
+import React from "react";
+import {Search} from "content-src/components/Search/Search";
+import {Sections} from "content-src/components/Sections/Sections";
+import {StartupOverlay} from "content-src/components/StartupOverlay/StartupOverlay";
+
+const PrefsButton = injectIntl(props => (
+  <div className="prefs-button">
+    <button className="icon icon-settings" onClick={props.onClick} title={props.intl.formatMessage({id: "settings_pane_button_label"})} />
+  </div>
+));
+
+// Add the locale data for pluralization and relative-time formatting for now,
+// this just uses english locale data. We can make this more sophisticated if
+// more features are needed.
+function addLocaleDataForReactIntl(locale) {
+  addLocaleData([{locale, parentLocale: "en"}]);
+}
+
+export class _Base extends React.PureComponent {
+  componentWillMount() {
+    const {App, locale, Theme} = this.props;
+    if (Theme.className) {
+      this.updateTheme(Theme);
+    }
+    this.sendNewTabRehydrated(App);
+    addLocaleDataForReactIntl(locale);
+  }
+
+  componentDidMount() {
+    // Request state AFTER the first render to ensure we don't cause the
+    // prerendered DOM to be unmounted. Otherwise, NEW_TAB_STATE_REQUEST is
+    // dispatched right after the store is ready.
+    if (this.props.isPrerendered) {
+      this.props.dispatch(ac.AlsoToMain({type: at.NEW_TAB_STATE_REQUEST}));
+      this.props.dispatch(ac.AlsoToMain({type: at.PAGE_PRERENDERED}));
+    }
+  }
+
+  componentWillUnmount() {
+    this.updateTheme({className: ""});
+  }
+
+  componentWillUpdate({App, Theme}) {
+    this.updateTheme(Theme);
+    this.sendNewTabRehydrated(App);
+  }
+
+  updateTheme(Theme) {
+    const bodyClassName = [
+      "activity-stream",
+      Theme.className,
+      this.props.isFirstrun ? "welcome" : ""
+    ].filter(v => v).join(" ");
+    global.document.body.className = bodyClassName;
+  }
+
+  // The NEW_TAB_REHYDRATED event is used to inform feeds that their
+  // data has been consumed e.g. for counting the number of tabs that
+  // have rendered that data.
+  sendNewTabRehydrated(App) {
+    if (App && App.initialized && !this.renderNotified) {
+      this.props.dispatch(ac.AlsoToMain({type: at.NEW_TAB_REHYDRATED, data: {}}));
+      this.renderNotified = true;
+    }
+  }
+
+  render() {
+    const {props} = this;
+    const {App, locale, strings} = props;
+    const {initialized} = App;
+
+    if (props.Prefs.values.asrouterExperimentEnabled && window.location.hash === "#asrouter") {
+      return (<ASRouterAdmin />);
+    }
+
+    if (!props.isPrerendered && !initialized) {
+      return null;
+    }
+
+    return (<IntlProvider locale={locale} messages={strings}>
+        <ErrorBoundary className="base-content-fallback">
+          <BaseContent {...this.props} />
+        </ErrorBoundary>
+      </IntlProvider>);
+  }
+}
+
+export class BaseContent extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.openPreferences = this.openPreferences.bind(this);
+  }
+
+  openPreferences() {
+    this.props.dispatch(ac.OnlyToMain({type: at.SETTINGS_OPEN}));
+    this.props.dispatch(ac.UserEvent({event: "OPEN_NEWTAB_PREFS"}));
+  }
+
+  render() {
+    const {props} = this;
+    const {App} = props;
+    const {initialized} = App;
+    const prefs = props.Prefs.values;
+
+    const shouldBeFixedToTop = PrerenderData.arePrefsValid(name => prefs[name]);
+
+    const outerClassName = [
+      "outer-wrapper",
+      shouldBeFixedToTop && "fixed-to-top"
+    ].filter(v => v).join(" ");
+
+    return (
+      <div>
+        <div className={outerClassName}>
+          <main>
+            {prefs.showSearch &&
+              <div className="non-collapsible-section">
+                <ErrorBoundary>
+                  <Search />
+                </ErrorBoundary>
+              </div>
+            }
+            <div className={`body-wrapper${(initialized ? " on" : "")}`}>
+              {!prefs.migrationExpired &&
+                <div className="non-collapsible-section">
+                  <ManualMigration />
+                </div>
+                }
+              <Sections />
+              <PrefsButton onClick={this.openPreferences} />
+            </div>
+            <ConfirmDialog />
+          </main>
+        </div>
+        {this.props.isFirstrun && <StartupOverlay />}
+      </div>);
+  }
+}
+
+export const Base = connect(state => ({App: state.App, Prefs: state.Prefs, Theme: state.Theme}))(_Base);
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/Base/_Base.scss
@@ -0,0 +1,96 @@
+.outer-wrapper {
+  color: var(--newtab-text-primary-color);
+  display: flex;
+  flex-grow: 1;
+  min-height: 100vh;
+  padding: ($section-spacing + $section-vertical-padding) $base-gutter $base-gutter;
+
+  &.fixed-to-top {
+    display: block;
+  }
+
+  a {
+    color: var(--newtab-link-primary-color);
+  }
+}
+
+main {
+  margin: auto;
+  // Offset the snippets container so things at the bottom of the page are still
+  // visible when snippets / onboarding are visible. Adjust for other spacing.
+  padding-bottom: $snippets-container-height - $section-spacing - $base-gutter;
+  width: $wrapper-default-width;
+
+  @media (min-width: $break-point-small) {
+    width: $wrapper-max-width-small;
+  }
+
+  @media (min-width: $break-point-medium) {
+    width: $wrapper-max-width-medium;
+  }
+
+  @media (min-width: $break-point-large) {
+    width: $wrapper-max-width-large;
+  }
+
+  @media (min-width: $break-point-widest) {
+    width: $wrapper-max-width-widest;
+  }
+
+  section {
+    margin-bottom: $section-spacing;
+    position: relative;
+  }
+}
+
+.base-content-fallback {
+  // Make the error message be centered against the viewport
+  height: 100vh;
+}
+
+.body-wrapper {
+  // Hide certain elements so the page structure is fixed, e.g., placeholders,
+  // while avoiding flashes of changing content, e.g., icons and text
+  $selectors-to-hide: '
+    .section-title,
+    .sections-list .section:last-of-type,
+    .topic
+  ';
+
+  #{$selectors-to-hide} {
+    opacity: 0;
+  }
+
+  &.on {
+    #{$selectors-to-hide} {
+      opacity: 1;
+    }
+  }
+}
+
+.non-collapsible-section {
+  padding: 0 $section-horizontal-padding;
+}
+
+.prefs-button {
+  button {
+    background-color: transparent;
+    border: 0;
+    cursor: pointer;
+    fill: var(--newtab-icon-primary-color);
+    offset-inline-end: 15px;
+    padding: 15px;
+    position: fixed;
+    top: 15px;
+    z-index: 12001;
+
+    &:hover,
+    &:focus {
+      background-color: var(--newtab-element-hover-color);
+    }
+
+    &:active {
+      background-color: var(--newtab-element-active-color);
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/Card/Card.jsx
@@ -0,0 +1,312 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {cardContextTypes} from "./types";
+import {connect} from "react-redux";
+import {FormattedMessage} from "react-intl";
+import {GetPlatformString} from "content-src/lib/link-menu-options";
+import {LinkMenu} from "content-src/components/LinkMenu/LinkMenu";
+import React from "react";
+
+// Keep track of pending image loads to only request once
+const gImageLoading = new Map();
+
+/**
+ * Card component.
+ * Cards are found within a Section component and contain information about a link such
+ * as preview image, page title, page description, and some context about if the page
+ * was visited, bookmarked, trending etc...
+ * Each Section can make an unordered list of Cards which will create one instane of
+ * this class. Each card will then get a context menu which reflects the actions that
+ * can be done on this Card.
+ */
+export class _Card extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.state = {
+      activeCard: null,
+      imageLoaded: false,
+      showContextMenu: false,
+      cardImage: null
+    };
+    this.onMenuButtonClick = this.onMenuButtonClick.bind(this);
+    this.onMenuUpdate = this.onMenuUpdate.bind(this);
+    this.onLinkClick = this.onLinkClick.bind(this);
+  }
+
+  /**
+   * Helper to conditionally load an image and update state when it loads.
+   */
+  async maybeLoadImage() {
+    // No need to load if it's already loaded or no image
+    const {cardImage} = this.state;
+    if (!cardImage) {
+      return;
+    }
+
+    const imageUrl = cardImage.url;
+    if (!this.state.imageLoaded) {
+      // Initialize a promise to share a load across multiple card updates
+      if (!gImageLoading.has(imageUrl)) {
+        const loaderPromise = new Promise((resolve, reject) => {
+          const loader = new Image();
+          loader.addEventListener("load", resolve);
+          loader.addEventListener("error", reject);
+          loader.src = imageUrl;
+        });
+
+        // Save and remove the promise only while it's pending
+        gImageLoading.set(imageUrl, loaderPromise);
+        loaderPromise.catch(ex => ex).then(() => gImageLoading.delete(imageUrl)).catch();
+      }
+
+      // Wait for the image whether just started loading or reused promise
+      await gImageLoading.get(imageUrl);
+
+      // Only update state if we're still waiting to load the original image
+      if (_Card.isImageInState(this.state, this.props.link.image) && !this.state.imageLoaded) {
+        this.setState({imageLoaded: true});
+      }
+    }
+  }
+
+  /**
+   * Checks if `.image` property on link object is a local image with blob data.
+   * This function only works for props since state has `.url` and not `.data`.
+   *
+   * @param {obj|string} image
+   * @returns {bool} true if image is a local image object, otherwise false
+   *                 (otherwise, image will be a URL as a string)
+   */
+  static isLocalImageObject(image) {
+    return image && image.data && image.path;
+  }
+
+  /**
+   * Helper to obtain the next state based on nextProps and prevState.
+   *
+   * NOTE: Rename this method to getDerivedStateFromProps when we update React
+   *       to >= 16.3. We will need to update tests as well. We cannot rename this
+   *       method to getDerivedStateFromProps now because there is a mismatch in
+   *       the React version that we are using for both testing and production.
+   *       (i.e. react-test-render => "16.3.2", react => "16.2.0").
+   *
+   * See https://github.com/airbnb/enzyme/blob/master/packages/enzyme-adapter-react-16/package.json#L43.
+   */
+  static getNextStateFromProps(nextProps, prevState) {
+    const {image} = nextProps.link;
+    const imageInState = _Card.isImageInState(prevState, image);
+    let nextState = null;
+
+    // Image is updating.
+    if (!imageInState && nextProps.link) {
+      nextState = {imageLoaded: false};
+    }
+
+    if (imageInState) {
+      return nextState;
+    }
+
+    nextState = nextState || {};
+
+    // Since image was updated, attempt to revoke old image blob URL, if it exists.
+    _Card.maybeRevokeImageBlob(prevState);
+
+    if (!image) {
+      nextState.cardImage = null;
+    } else if (_Card.isLocalImageObject(image)) {
+      nextState.cardImage = {url: global.URL.createObjectURL(image.data), path: image.path};
+    } else {
+      nextState.cardImage = {url: image};
+    }
+
+    return nextState;
+  }
+
+  /**
+   * Helper to conditionally revoke the previous card image if it is a blob.
+   */
+  static maybeRevokeImageBlob(prevState) {
+    if (prevState.cardImage && prevState.cardImage.path) {
+      global.URL.revokeObjectURL(prevState.cardImage.url);
+    }
+  }
+
+  /**
+   * Helper to check if an image is already in state.
+   */
+  static isImageInState(state, image) {
+    const {cardImage} = state;
+
+    // Both image and cardImage are present.
+    if (image && cardImage) {
+      return _Card.isLocalImageObject(image) ?
+             cardImage.path === image.path :
+             cardImage.url === image;
+    }
+
+    // This will only handle the remaining three possible outcomes.
+    // (i.e. everything except when both image and cardImage are present)
+    return !image && !cardImage;
+  }
+
+  onMenuButtonClick(event) {
+    event.preventDefault();
+    this.setState({
+      activeCard: this.props.index,
+      showContextMenu: true
+    });
+  }
+
+  /**
+   * Report to telemetry additional information about the item.
+   */
+  _getTelemetryInfo() {
+    // Filter out "history" type for being the default
+    if (this.props.link.type !== "history") {
+      return {value: {card_type: this.props.link.type}};
+    }
+
+    return null;
+  }
+
+  onLinkClick(event) {
+    event.preventDefault();
+    if (this.props.link.type === "download") {
+      this.props.dispatch(ac.OnlyToMain({
+        type: at.SHOW_DOWNLOAD_FILE,
+        data: this.props.link
+      }));
+    } else {
+      const {altKey, button, ctrlKey, metaKey, shiftKey} = event;
+      this.props.dispatch(ac.OnlyToMain({
+        type: at.OPEN_LINK,
+        data: Object.assign(this.props.link, {event: {altKey, button, ctrlKey, metaKey, shiftKey}})
+      }));
+    }
+    if (this.props.isWebExtension) {
+      this.props.dispatch(ac.WebExtEvent(at.WEBEXT_CLICK, {
+        source: this.props.eventSource,
+        url: this.props.link.url,
+        action_position: this.props.index
+      }));
+    } else {
+      this.props.dispatch(ac.UserEvent(Object.assign({
+        event: "CLICK",
+        source: this.props.eventSource,
+        action_position: this.props.index
+      }, this._getTelemetryInfo())));
+
+      if (this.props.shouldSendImpressionStats) {
+        this.props.dispatch(ac.ImpressionStats({
+          source: this.props.eventSource,
+          click: 0,
+          tiles: [{id: this.props.link.guid, pos: this.props.index}]
+        }));
+      }
+    }
+  }
+
+  onMenuUpdate(showContextMenu) {
+    this.setState({showContextMenu});
+  }
+
+  componentDidMount() {
+    this.maybeLoadImage();
+  }
+
+  componentDidUpdate() {
+    this.maybeLoadImage();
+  }
+
+  // NOTE: Remove this function when we update React to >= 16.3 since React will
+  //       call getDerivedStateFromProps automatically. We will also need to
+  //       rename getNextStateFromProps to getDerivedStateFromProps.
+  componentWillMount() {
+    const nextState = _Card.getNextStateFromProps(this.props, this.state);
+    if (nextState) {
+      this.setState(nextState);
+    }
+  }
+
+  // NOTE: Remove this function when we update React to >= 16.3 since React will
+  //       call getDerivedStateFromProps automatically. We will also need to
+  //       rename getNextStateFromProps to getDerivedStateFromProps.
+  componentWillReceiveProps(nextProps) {
+    const nextState = _Card.getNextStateFromProps(nextProps, this.state);
+    if (nextState) {
+      this.setState(nextState);
+    }
+  }
+
+  componentWillUnmount() {
+    _Card.maybeRevokeImageBlob(this.state);
+  }
+
+  render() {
+    const {index, className, link, dispatch, contextMenuOptions, eventSource, shouldSendImpressionStats} = this.props;
+    const {props} = this;
+    const isContextMenuOpen = this.state.showContextMenu && this.state.activeCard === index;
+    // Display "now" as "trending" until we have new strings #3402
+    const {icon, intlID} = cardContextTypes[link.type === "now" ? "trending" : link.type] || {};
+    const hasImage = this.state.cardImage || link.hasImage;
+    const imageStyle = {backgroundImage: this.state.cardImage ? `url(${this.state.cardImage.url})` : "none"};
+    const outerClassName = [
+      "card-outer",
+      className,
+      isContextMenuOpen && "active",
+      props.placeholder && "placeholder"
+    ].filter(v => v).join(" ");
+
+    return (<li className={outerClassName}>
+      <a href={link.type === "pocket" ? link.open_url : link.url} onClick={!props.placeholder ? this.onLinkClick : undefined}>
+        <div className="card">
+          <div className="card-preview-image-outer">
+            {hasImage &&
+              <div className={`card-preview-image${this.state.imageLoaded ? " loaded" : ""}`} style={imageStyle} />
+            }
+          </div>
+          <div className="card-details">
+            {link.type === "download" && <div className="card-host-name alternate"><FormattedMessage id={GetPlatformString(this.props.platform)} /></div>}
+            {link.hostname &&
+              <div className="card-host-name">
+                {link.hostname.slice(0, 100)}{link.type === "download" && `  \u2014 ${link.description}`}
+              </div>
+            }
+            <div className={[
+              "card-text",
+              icon ? "" : "no-context",
+              link.description ? "" : "no-description",
+              link.hostname ? "" : "no-host-name"
+            ].join(" ")}>
+              <h4 className="card-title" dir="auto">{link.title}</h4>
+              <p className="card-description" dir="auto">{link.description}</p>
+            </div>
+            <div className="card-context">
+              {icon && !link.context && <span className={`card-context-icon icon icon-${icon}`} />}
+              {link.icon && link.context && <span className="card-context-icon icon" style={{backgroundImage: `url('${link.icon}')`}} />}
+              {intlID && !link.context && <div className="card-context-label"><FormattedMessage id={intlID} defaultMessage="Visited" /></div>}
+              {link.context && <div className="card-context-label">{link.context}</div>}
+            </div>
+          </div>
+        </div>
+      </a>
+      {!props.placeholder && <button className="context-menu-button icon"
+        onClick={this.onMenuButtonClick}>
+        <span className="sr-only">{`Open context menu for ${link.title}`}</span>
+      </button>}
+      {isContextMenuOpen &&
+        <LinkMenu
+          dispatch={dispatch}
+          index={index}
+          source={eventSource}
+          onUpdate={this.onMenuUpdate}
+          options={link.contextMenuOptions || contextMenuOptions}
+          site={link}
+          siteInfo={this._getTelemetryInfo()}
+          shouldSendImpressionStats={shouldSendImpressionStats} />
+      }
+   </li>);
+  }
+}
+_Card.defaultProps = {link: {}};
+export const Card = connect(state => ({platform: state.Prefs.values.platform}))(_Card);
+export const PlaceholderCard = props => <Card placeholder={true} className={props.className} />;
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/Card/_Card.scss
@@ -0,0 +1,315 @@
+.card-outer {
+  @include context-menu-button;
+  background: var(--newtab-card-background-color);
+  border-radius: $border-radius;
+  display: inline-block;
+  height: $card-height;
+  margin-inline-end: $base-gutter;
+  position: relative;
+  width: 100%;
+
+  &.placeholder {
+    background: transparent;
+
+    .card {
+      box-shadow: inset $inner-box-shadow;
+    }
+
+    .card-preview-image-outer,
+    .card-context {
+      display: none;
+    }
+  }
+
+  .card {
+    border-radius: $border-radius;
+    box-shadow: var(--newtab-card-shadow);
+    height: 100%;
+  }
+
+  > a {
+    color: inherit;
+    display: block;
+    height: 100%;
+    outline: none;
+    position: absolute;
+    width: 100%;
+
+    &:-moz-any(.active, :focus) {
+      .card {
+        @include fade-in-card;
+      }
+
+      .card-title {
+        color: var(--newtab-link-primary-color);
+      }
+    }
+  }
+
+  &:-moz-any(:hover, :focus, .active):not(.placeholder) {
+    @include fade-in-card;
+    @include context-menu-button-hover;
+    outline: none;
+
+    .card-title {
+      color: var(--newtab-link-primary-color);
+    }
+
+    .alternate ~ .card-host-name {
+      display: none;
+    }
+
+    .card-host-name.alternate {
+      display: block;
+    }
+  }
+
+  .card-preview-image-outer {
+    background-color: $grey-30;
+    border-radius: $border-radius $border-radius 0 0;
+    height: $card-preview-image-height;
+    overflow: hidden;
+    position: relative;
+
+    &::after {
+      border-bottom: 1px solid var(--newtab-card-hairline-color);
+      bottom: 0;
+      content: '';
+      position: absolute;
+      width: 100%;
+    }
+
+    .card-preview-image {
+      background-position: center;
+      background-repeat: no-repeat;
+      background-size: cover;
+      height: 100%;
+      opacity: 0;
+      transition: opacity 1s $photon-easing;
+      width: 100%;
+
+      &.loaded {
+        opacity: 1;
+      }
+    }
+  }
+
+  .card-details {
+    padding: 15px 16px 12px;
+  }
+
+  .card-text {
+    max-height: 4 * $card-text-line-height + $card-title-margin;
+    overflow: hidden;
+
+    &.no-host-name,
+    &.no-context {
+      max-height: 5 * $card-text-line-height + $card-title-margin;
+    }
+
+    &.no-host-name.no-context {
+      max-height: 6 * $card-text-line-height + $card-title-margin;
+    }
+
+    &:not(.no-description) .card-title {
+      max-height: 3 * $card-text-line-height;
+      overflow: hidden;
+    }
+  }
+
+  .card-host-name {
+    color: var(--newtab-text-secondary-color);
+    font-size: 10px;
+    overflow: hidden;
+    padding-bottom: 4px;
+    text-overflow: ellipsis;
+    text-transform: uppercase;
+    white-space: nowrap;
+  }
+
+  .card-host-name.alternate { display: none; }
+
+  .card-title {
+    font-size: 14px;
+    font-weight: 600;
+    line-height: $card-text-line-height;
+    margin: 0 0 $card-title-margin;
+    word-wrap: break-word;
+  }
+
+  .card-description {
+    font-size: 12px;
+    line-height: $card-text-line-height;
+    margin: 0;
+    overflow: hidden;
+    word-wrap: break-word;
+  }
+
+  .card-context {
+    bottom: 0;
+    color: var(--newtab-text-secondary-color);
+    display: flex;
+    font-size: 11px;
+    offset-inline-start: 0;
+    padding: 9px 16px 9px 14px;
+    position: absolute;
+  }
+
+  .card-context-icon {
+    fill: var(--newtab-text-secondary-color);
+    height: 22px;
+    margin-inline-end: 6px;
+  }
+
+  .card-context-label {
+    flex-grow: 1;
+    line-height: 22px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+}
+
+.normal-cards {
+  .card-outer {
+    // Wide layout styles
+    @media (min-width: $break-point-widest) {
+      $line-height: 23px;
+      height: $card-height-large;
+
+      .card-preview-image-outer {
+        height: $card-preview-image-height-large;
+      }
+
+      .card-details {
+        padding: 13px 16px 12px;
+      }
+
+      .card-text {
+        max-height: 6 * $line-height + $card-title-margin;
+      }
+
+      .card-host-name {
+        font-size: 12px;
+        padding-bottom: 5px;
+      }
+
+      .card-title {
+        font-size: 17px;
+        line-height: $line-height;
+        margin-bottom: 0;
+      }
+
+      .card-text:not(.no-description) {
+        .card-title {
+          max-height: 3 * $line-height;
+        }
+      }
+
+      .card-description {
+        font-size: 15px;
+        line-height: $line-height;
+      }
+
+      .card-context {
+        bottom: 4px;
+        font-size: 14px;
+      }
+    }
+  }
+}
+
+.compact-cards {
+  $card-detail-vertical-spacing: 12px;
+  $card-title-font-size: 12px;
+
+  .card-outer {
+    height: $card-height-compact;
+
+    .card-preview-image-outer {
+      height: $card-preview-image-height-compact;
+    }
+
+    .card-details {
+      padding: $card-detail-vertical-spacing 16px;
+    }
+
+    .card-host-name {
+      line-height: 10px;
+    }
+
+    .card-text {
+      .card-title,
+      &:not(.no-description) .card-title {
+        font-size: $card-title-font-size;
+        line-height: $card-title-font-size + 1;
+        max-height: $card-title-font-size + 1;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+    }
+
+    .card-description {
+      display: none;
+    }
+
+    .card-context {
+      $icon-size: 16px;
+      $container-size: 32px;
+      background-color: var(--newtab-card-background-color);
+      border-radius: $container-size / 2;
+      clip-path: inset(-1px -1px $container-size - ($card-height-compact - $card-preview-image-height-compact - 2 * $card-detail-vertical-spacing));
+      height: $container-size;
+      width: $container-size;
+      padding: ($container-size - $icon-size) / 2;
+      top: $card-preview-image-height-compact - $icon-size;
+      offset-inline-end: 12px;
+      offset-inline-start: auto;
+
+      &::after {
+        border: 1px solid var(--newtab-card-hairline-color);
+        border-bottom: 0;
+        border-radius: ($container-size / 2) + 1 ($container-size / 2) + 1 0 0;
+        content: '';
+        position: absolute;
+        height: ($container-size + 2) / 2;
+        width: $container-size + 2;
+        top: -1px;
+        left: -1px;
+      }
+
+      .card-context-icon {
+        margin-inline-end: 0;
+        height: $icon-size;
+        width: $icon-size;
+
+        &.icon-bookmark-added {
+          fill: $bookmark-icon-fill;
+        }
+
+        &.icon-download {
+          fill: $download-icon-fill;
+        }
+
+        &.icon-history-item {
+          fill: $history-icon-fill;
+        }
+
+        &.icon-pocket {
+          fill: $pocket-icon-fill;
+        }
+      }
+
+      .card-context-label {
+        display: none;
+      }
+    }
+  }
+
+  @media not all and (min-width: $break-point-widest) {
+    .hide-for-narrow {
+      display: none;
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/Card/types.js
@@ -0,0 +1,26 @@
+export const cardContextTypes = {
+  history: {
+    intlID: "type_label_visited",
+    icon: "history-item"
+  },
+  bookmark: {
+    intlID: "type_label_bookmarked",
+    icon: "bookmark-added"
+  },
+  trending: {
+    intlID: "type_label_recommended",
+    icon: "trending"
+  },
+  now: {
+    intlID: "type_label_now",
+    icon: "now"
+  },
+  pocket: {
+    intlID: "type_label_pocket",
+    icon: "pocket"
+  },
+  download: {
+    intlID: "type_label_downloaded",
+    icon: "download"
+  }
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/CollapsibleSection/CollapsibleSection.jsx
@@ -0,0 +1,218 @@
+import {FormattedMessage, injectIntl} from "react-intl";
+import {actionCreators as ac} from "common/Actions.jsm";
+import {ErrorBoundary} from "content-src/components/ErrorBoundary/ErrorBoundary";
+import React from "react";
+import {SectionMenu} from "content-src/components/SectionMenu/SectionMenu";
+import {SectionMenuOptions} from "content-src/lib/section-menu-options";
+
+const VISIBLE = "visible";
+const VISIBILITY_CHANGE_EVENT = "visibilitychange";
+
+function getFormattedMessage(message) {
+  return typeof message === "string" ? <span>{message}</span> : <FormattedMessage {...message} />;
+}
+
+export class Disclaimer extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.onAcknowledge = this.onAcknowledge.bind(this);
+  }
+
+  onAcknowledge() {
+    this.props.dispatch(ac.SetPref(this.props.disclaimerPref, false));
+    this.props.dispatch(ac.UserEvent({event: "DISCLAIMER_ACKED", source: this.props.eventSource}));
+  }
+
+  render() {
+    const {disclaimer} = this.props;
+    return (
+      <div className="section-disclaimer">
+          <div className="section-disclaimer-text">
+            {getFormattedMessage(disclaimer.text)}
+            {disclaimer.link &&
+              <a href={disclaimer.link.href} target="_blank" rel="noopener noreferrer">
+                {getFormattedMessage(disclaimer.link.title || disclaimer.link)}
+              </a>
+            }
+          </div>
+
+          <button onClick={this.onAcknowledge}>
+            {getFormattedMessage(disclaimer.button)}
+          </button>
+      </div>
+    );
+  }
+}
+
+export const DisclaimerIntl = injectIntl(Disclaimer);
+
+export class _CollapsibleSection extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.onBodyMount = this.onBodyMount.bind(this);
+    this.onHeaderClick = this.onHeaderClick.bind(this);
+    this.onTransitionEnd = this.onTransitionEnd.bind(this);
+    this.enableOrDisableAnimation = this.enableOrDisableAnimation.bind(this);
+    this.onMenuButtonClick = this.onMenuButtonClick.bind(this);
+    this.onMenuButtonMouseEnter = this.onMenuButtonMouseEnter.bind(this);
+    this.onMenuButtonMouseLeave = this.onMenuButtonMouseLeave.bind(this);
+    this.onMenuUpdate = this.onMenuUpdate.bind(this);
+    this.state = {enableAnimation: true, isAnimating: false, menuButtonHover: false, showContextMenu: false};
+  }
+
+  componentWillMount() {
+    this.props.document.addEventListener(VISIBILITY_CHANGE_EVENT, this.enableOrDisableAnimation);
+  }
+
+  componentWillUpdate(nextProps) {
+    // Check if we're about to go from expanded to collapsed
+    if (!this.props.collapsed && nextProps.collapsed) {
+      // This next line forces a layout flush of the section body, which has a
+      // max-height style set, so that the upcoming collapse animation can
+      // animate from that height to the collapsed height. Without this, the
+      // update is coalesced and there's no animation from no-max-height to 0.
+      this.sectionBody.scrollHeight; // eslint-disable-line no-unused-expressions
+    }
+  }
+
+  componentWillUnmount() {
+    this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this.enableOrDisableAnimation);
+  }
+
+  enableOrDisableAnimation() {
+    // Only animate the collapse/expand for visible tabs.
+    const visible = this.props.document.visibilityState === VISIBLE;
+    if (this.state.enableAnimation !== visible) {
+      this.setState({enableAnimation: visible});
+    }
+  }
+
+  onBodyMount(node) {
+    this.sectionBody = node;
+  }
+
+  onHeaderClick() {
+    // If this.sectionBody is unset, it means that we're in some sort of error
+    // state, probably displaying the error fallback, so we won't be able to
+    // compute the height, and we don't want to persist the preference.
+    // If props.collapsed is undefined handler shouldn't do anything.
+    if (!this.sectionBody || this.props.collapsed === undefined) {
+      return;
+    }
+
+    // Get the current height of the body so max-height transitions can work
+    this.setState({
+      isAnimating: true,
+      maxHeight: `${this.sectionBody.scrollHeight}px`
+    });
+    const {action, userEvent} = SectionMenuOptions.CheckCollapsed(this.props);
+    this.props.dispatch(action);
+    this.props.dispatch(ac.UserEvent({
+      event: userEvent,
+      source: this.props.source
+    }));
+  }
+
+  onTransitionEnd(event) {
+    // Only update the animating state for our own transition (not a child's)
+    if (event.target === event.currentTarget) {
+      this.setState({isAnimating: false});
+    }
+  }
+
+  renderIcon() {
+    const {icon} = this.props;
+    if (icon && icon.startsWith("moz-extension://")) {
+      return <span className="icon icon-small-spacer" style={{backgroundImage: `url('${icon}')`}} />;
+    }
+    return <span className={`icon icon-small-spacer icon-${icon || "webextension"}`} />;
+  }
+
+  onMenuButtonClick(event) {
+    event.preventDefault();
+    this.setState({showContextMenu: true});
+  }
+
+  onMenuButtonMouseEnter() {
+    this.setState({menuButtonHover: true});
+  }
+
+  onMenuButtonMouseLeave() {
+    this.setState({menuButtonHover: false});
+  }
+
+  onMenuUpdate(showContextMenu) {
+    this.setState({showContextMenu});
+  }
+
+  render() {
+    const isCollapsible = this.props.collapsed !== undefined;
+    const {enableAnimation, isAnimating, maxHeight, menuButtonHover, showContextMenu} = this.state;
+    const {id, eventSource, collapsed, disclaimer, title, extraMenuOptions, showPrefName, privacyNoticeURL, dispatch, isFirst, isLast, isWebExtension} = this.props;
+    const disclaimerPref = `section.${id}.showDisclaimer`;
+    const needsDisclaimer = disclaimer && this.props.Prefs.values[disclaimerPref];
+    const active = menuButtonHover || showContextMenu;
+    return (
+      <section
+        className={`collapsible-section ${this.props.className}${enableAnimation ? " animation-enabled" : ""}${collapsed ? " collapsed" : ""}${active ? " active" : ""}`}
+        // Note: data-section-id is used for web extension api tests in mozilla central
+        data-section-id={id}>
+        <div className="section-top-bar">
+          <h3 className="section-title">
+            <span className="click-target" onClick={this.onHeaderClick}>
+              {this.renderIcon()}
+              {getFormattedMessage(title)}
+              {isCollapsible && <span className={`collapsible-arrow icon ${collapsed ? "icon-arrowhead-forward-small" : "icon-arrowhead-down-small"}`} />}
+            </span>
+          </h3>
+          <div>
+            <button
+              className="context-menu-button icon"
+              onClick={this.onMenuButtonClick}
+              onMouseEnter={this.onMenuButtonMouseEnter}
+              onMouseLeave={this.onMenuButtonMouseLeave}>
+              <span className="sr-only">
+                <FormattedMessage id="section_context_menu_button_sr" />
+              </span>
+            </button>
+            {showContextMenu &&
+              <SectionMenu
+                id={id}
+                extraOptions={extraMenuOptions}
+                eventSource={eventSource}
+                showPrefName={showPrefName}
+                privacyNoticeURL={privacyNoticeURL}
+                collapsed={collapsed}
+                onUpdate={this.onMenuUpdate}
+                isFirst={isFirst}
+                isLast={isLast}
+                dispatch={dispatch}
+                isWebExtension={isWebExtension} />
+            }
+          </div>
+        </div>
+        <ErrorBoundary className="section-body-fallback">
+          <div
+            className={`section-body${isAnimating ? " animating" : ""}`}
+            onTransitionEnd={this.onTransitionEnd}
+            ref={this.onBodyMount}
+            style={isAnimating && !collapsed ? {maxHeight} : null}>
+            {needsDisclaimer && <DisclaimerIntl disclaimerPref={disclaimerPref} disclaimer={disclaimer} eventSource={eventSource} dispatch={this.props.dispatch} />}
+            {this.props.children}
+          </div>
+        </ErrorBoundary>
+      </section>
+    );
+  }
+}
+
+_CollapsibleSection.defaultProps = {
+  document: global.document || {
+    addEventListener: () => {},
+    removeEventListener: () => {},
+    visibilityState: "hidden"
+  },
+  Prefs: {values: {}}
+};
+
+export const CollapsibleSection = injectIntl(_CollapsibleSection);
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/CollapsibleSection/_CollapsibleSection.scss
@@ -0,0 +1,166 @@
+.collapsible-section {
+  padding: $section-vertical-padding $section-horizontal-padding;
+  transition-delay: 100ms;
+  transition-duration: 100ms;
+  transition-property: background-color;
+
+  .section-title {
+    font-size: $section-title-font-size;
+    font-weight: bold;
+    margin: 0;
+    text-transform: uppercase;
+
+    span {
+      color: var(--newtab-section-header-text-color);
+      display: inline-block;
+      fill: var(--newtab-section-header-text-color);
+      vertical-align: middle;
+    }
+
+    .click-target {
+      cursor: pointer;
+      vertical-align: top;
+      white-space: nowrap;
+    }
+
+    .collapsible-arrow {
+      margin-inline-start: 8px;
+      margin-top: -1px;
+    }
+  }
+
+  .section-top-bar {
+    height: 19px;
+    margin-bottom: 13px;
+    position: relative;
+
+    .context-menu-button {
+      background: url('chrome://browser/skin/page-action.svg') no-repeat right center;
+      border: 0;
+      cursor: pointer;
+      fill: var(--newtab-section-header-text-color);
+      height: 100%;
+      offset-inline-end: 0;
+      opacity: 0;
+      position: absolute;
+      top: 0;
+      transition-duration: 200ms;
+      transition-property: opacity;
+      width: $context-menu-button-size;
+
+      &:-moz-any(:active, :focus, :hover) {
+        fill: $grey-90;
+        opacity: 1;
+      }
+    }
+
+    .context-menu {
+      top: 16px;
+    }
+
+    @media (max-width: $break-point-widest + $card-width * 1.5) {
+      @include context-menu-open-left;
+    }
+  }
+
+  &:hover,
+  &.active {
+    .section-top-bar {
+      .context-menu-button {
+        opacity: 1;
+      }
+    }
+  }
+
+  &.active {
+    background: var(--newtab-element-hover-color);
+    border-radius: 4px;
+
+    .section-top-bar {
+      .context-menu-button {
+        fill: var(--newtab-section-active-contextmenu-color);
+      }
+    }
+  }
+
+  .section-disclaimer {
+    $max-button-width: 130px;
+    $min-button-height: 26px;
+
+    color: var(--newtab-text-conditional-color);
+    font-size: 13px;
+    margin-bottom: 16px;
+    position: relative;
+
+    .section-disclaimer-text {
+      display: inline-block;
+      min-height: $min-button-height;
+      width: calc(100% - #{$max-button-width});
+
+      @media (max-width: $break-point-medium) {
+        width: $card-width;
+      }
+    }
+
+    a {
+      color: var(--newtab-link-primary-color);
+      font-weight: bold;
+      padding-left: 3px;
+    }
+
+    button {
+      background: var(--newtab-button-secondary-color);
+      border: 1px solid $grey-40;
+      border-radius: 4px;
+      cursor: pointer;
+      margin-top: 2px;
+      max-width: $max-button-width;
+      min-height: $min-button-height;
+      offset-inline-end: 0;
+
+      &:hover:not(.dismiss) {
+        box-shadow: $shadow-primary;
+        transition: box-shadow 150ms;
+      }
+
+      @media (min-width: $break-point-small) {
+        position: absolute;
+      }
+    }
+  }
+
+  .section-body-fallback {
+    height: $card-height;
+  }
+
+  .section-body {
+    // This is so the top sites favicon and card dropshadows don't get clipped during animation:
+    $horizontal-padding: 7px;
+    margin: 0 (-$horizontal-padding);
+    padding: 0 $horizontal-padding;
+
+    &.animating {
+      overflow: hidden;
+      pointer-events: none;
+    }
+  }
+
+  &.animation-enabled {
+    .section-title {
+      .collapsible-arrow {
+        transition: transform 0.5s $photon-easing;
+      }
+    }
+
+    .section-body {
+      transition: max-height 0.5s $photon-easing;
+    }
+  }
+
+  &.collapsed {
+    .section-body {
+      max-height: 0;
+      overflow: hidden;
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/ComponentPerfTimer/ComponentPerfTimer.jsx
@@ -0,0 +1,163 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {perfService as perfSvc} from "common/PerfService.jsm";
+import React from "react";
+
+// Currently record only a fixed set of sections. This will prevent data
+// from custom sections from showing up or from topstories.
+const RECORDED_SECTIONS = ["highlights", "topsites"];
+
+export class ComponentPerfTimer extends React.Component {
+  constructor(props) {
+    super(props);
+    // Just for test dependency injection:
+    this.perfSvc = this.props.perfSvc || perfSvc;
+
+    this._sendBadStateEvent = this._sendBadStateEvent.bind(this);
+    this._sendPaintedEvent = this._sendPaintedEvent.bind(this);
+    this._reportMissingData = false;
+    this._timestampHandled = false;
+    this._recordedFirstRender = false;
+  }
+
+  componentDidMount() {
+    if (!RECORDED_SECTIONS.includes(this.props.id)) {
+      return;
+    }
+
+    this._maybeSendPaintedEvent();
+  }
+
+  componentDidUpdate() {
+    if (!RECORDED_SECTIONS.includes(this.props.id)) {
+      return;
+    }
+
+    this._maybeSendPaintedEvent();
+  }
+
+  /**
+   * Call the given callback after the upcoming frame paints.
+   *
+   * @note Both setTimeout and requestAnimationFrame are throttled when the page
+   * is hidden, so this callback may get called up to a second or so after the
+   * requestAnimationFrame "paint" for hidden tabs.
+   *
+   * Newtabs hidden while loading will presumably be fairly rare (other than
+   * preloaded tabs, which we will be filtering out on the server side), so such
+   * cases should get lost in the noise.
+   *
+   * If we decide that it's important to find out when something that's hidden
+   * has "painted", however, another option is to post a message to this window.
+   * That should happen even faster than setTimeout, and, at least as of this
+   * writing, it's not throttled in hidden windows in Firefox.
+   *
+   * @param {Function} callback
+   *
+   * @returns void
+   */
+  _afterFramePaint(callback) {
+    requestAnimationFrame(() => setTimeout(callback, 0));
+  }
+
+  _maybeSendBadStateEvent() {
+    // Follow up bugs:
+    // https://github.com/mozilla/activity-stream/issues/3691
+    if (!this.props.initialized) {
+      // Remember to report back when data is available.
+      this._reportMissingData = true;
+    } else if (this._reportMissingData) {
+      this._reportMissingData = false;
+      // Report how long it took for component to become initialized.
+      this._sendBadStateEvent();
+    }
+  }
+
+  _maybeSendPaintedEvent() {
+    // If we've already handled a timestamp, don't do it again.
+    if (this._timestampHandled || !this.props.initialized) {
+      return;
+    }
+
+    // And if we haven't, we're doing so now, so remember that. Even if
+    // something goes wrong in the callback, we can't try again, as we'd be
+    // sending back the wrong data, and we have to do it here, so that other
+    // calls to this method while waiting for the next frame won't also try to
+    // handle it.
+    this._timestampHandled = true;
+    this._afterFramePaint(this._sendPaintedEvent);
+  }
+
+  /**
+   * Triggered by call to render. Only first call goes through due to
+   * `_recordedFirstRender`.
+   */
+  _ensureFirstRenderTsRecorded() {
+    // Used as t0 for recording how long component took to initialize.
+    if (!this._recordedFirstRender) {
+      this._recordedFirstRender = true;
+      // topsites_first_render_ts, highlights_first_render_ts.
+      const key = `${this.props.id}_first_render_ts`;
+      this.perfSvc.mark(key);
+    }
+  }
+
+  /**
+   * Creates `TELEMETRY_UNDESIRED_EVENT` with timestamp in ms
+   * of how much longer the data took to be ready for display than it would
+   * have been the ideal case.
+   * https://github.com/mozilla/ping-centre/issues/98
+   */
+  _sendBadStateEvent() {
+    // highlights_data_ready_ts, topsites_data_ready_ts.
+    const dataReadyKey = `${this.props.id}_data_ready_ts`;
+    this.perfSvc.mark(dataReadyKey);
+
+    try {
+      const firstRenderKey = `${this.props.id}_first_render_ts`;
+      // value has to be Int32.
+      const value = parseInt(this.perfSvc.getMostRecentAbsMarkStartByName(dataReadyKey) -
+                             this.perfSvc.getMostRecentAbsMarkStartByName(firstRenderKey), 10);
+      this.props.dispatch(ac.OnlyToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        // highlights_data_late_by_ms, topsites_data_late_by_ms.
+        data: {[`${this.props.id}_data_late_by_ms`]: value}
+      }));
+    } catch (ex) {
+      // If this failed, it's likely because the `privacy.resistFingerprinting`
+      // pref is true.
+    }
+  }
+
+  _sendPaintedEvent() {
+    // Record first_painted event but only send if topsites.
+    if (this.props.id !== "topsites") {
+      return;
+    }
+
+    // topsites_first_painted_ts.
+    const key = `${this.props.id}_first_painted_ts`;
+    this.perfSvc.mark(key);
+
+    try {
+      const data = {};
+      data[key] = this.perfSvc.getMostRecentAbsMarkStartByName(key);
+
+      this.props.dispatch(ac.OnlyToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data
+      }));
+    } catch (ex) {
+      // If this failed, it's likely because the `privacy.resistFingerprinting`
+      // pref is true.  We should at least not blow up, and should continue
+      // to set this._timestampHandled to avoid going through this again.
+    }
+  }
+
+  render() {
+    if (RECORDED_SECTIONS.includes(this.props.id)) {
+      this._ensureFirstRenderTsRecorded();
+      this._maybeSendBadStateEvent();
+    }
+    return this.props.children;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/ConfirmDialog/ConfirmDialog.jsx
@@ -0,0 +1,78 @@
+import {actionCreators as ac, actionTypes} from "common/Actions.jsm";
+import {connect} from "react-redux";
+import {FormattedMessage} from "react-intl";
+import React from "react";
+
+/**
+ * ConfirmDialog component.
+ * One primary action button, one cancel button.
+ *
+ * Content displayed is controlled by `data` prop the component receives.
+ * Example:
+ * data: {
+ *   // Any sort of data needed to be passed around by actions.
+ *   payload: site.url,
+ *   // Primary button AlsoToMain action.
+ *   action: "DELETE_HISTORY_URL",
+ *   // Primary button USerEvent action.
+ *   userEvent: "DELETE",
+ *   // Array of locale ids to display.
+ *   message_body: ["confirm_history_delete_p1", "confirm_history_delete_notice_p2"],
+ *   // Text for primary button.
+ *   confirm_button_string_id: "menu_action_delete"
+ * },
+ */
+export class _ConfirmDialog extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this._handleCancelBtn = this._handleCancelBtn.bind(this);
+    this._handleConfirmBtn = this._handleConfirmBtn.bind(this);
+  }
+
+  _handleCancelBtn() {
+    this.props.dispatch({type: actionTypes.DIALOG_CANCEL});
+    this.props.dispatch(ac.UserEvent({event: actionTypes.DIALOG_CANCEL, source: this.props.data.eventSource}));
+  }
+
+  _handleConfirmBtn() {
+    this.props.data.onConfirm.forEach(this.props.dispatch);
+  }
+
+  _renderModalMessage() {
+    const message_body = this.props.data.body_string_id;
+
+    if (!message_body) {
+      return null;
+    }
+
+    return (<span>
+      {message_body.map(msg => <p key={msg}><FormattedMessage id={msg} /></p>)}
+    </span>);
+  }
+
+  render() {
+    if (!this.props.visible) {
+      return null;
+    }
+
+    return (<div className="confirmation-dialog">
+      <div className="modal-overlay" onClick={this._handleCancelBtn} />
+      <div className="modal">
+        <section className="modal-message">
+          {this.props.data.icon && <span className={`icon icon-spacer icon-${this.props.data.icon}`} />}
+          {this._renderModalMessage()}
+        </section>
+        <section className="actions">
+          <button onClick={this._handleCancelBtn}>
+            <FormattedMessage id={this.props.data.cancel_button_string_id} />
+          </button>
+          <button className="done" onClick={this._handleConfirmBtn}>
+            <FormattedMessage id={this.props.data.confirm_button_string_id} />
+          </button>
+        </section>
+      </div>
+    </div>);
+  }
+}
+
+export const ConfirmDialog = connect(state => state.Dialog)(_ConfirmDialog);
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/ConfirmDialog/_ConfirmDialog.scss
@@ -0,0 +1,67 @@
+.confirmation-dialog {
+  .modal {
+    box-shadow: 0 2px 2px 0 $black-10;
+    left: 50%;
+    margin-left: -200px;
+    position: fixed;
+    top: 20%;
+    width: 400px;
+  }
+
+  section {
+    margin: 0;
+  }
+
+  .modal-message {
+    display: flex;
+    padding: 16px;
+    padding-bottom: 0;
+
+    p {
+      margin: 0;
+      margin-bottom: 16px;
+    }
+  }
+
+  .actions {
+    border: 0;
+    display: flex;
+    flex-wrap: nowrap;
+    padding: 0 16px;
+
+    button {
+      margin-inline-end: 16px;
+      padding-inline-end: 18px;
+      padding-inline-start: 18px;
+      white-space: normal;
+      width: 50%;
+
+      &.done {
+        margin-inline-end: 0;
+        margin-inline-start: 0;
+      }
+    }
+  }
+
+  .icon {
+    margin-inline-end: 16px;
+  }
+}
+
+.modal-overlay {
+  background: var(--newtab-overlay-color);
+  height: 100%;
+  left: 0;
+  position: fixed;
+  top: 0;
+  width: 100%;
+  z-index: 11001;
+}
+
+.modal {
+  background: var(--newtab-modal-color);
+  border: $border-secondary;
+  border-radius: 5px;
+  font-size: 15px;
+  z-index: 11002;
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/ContextMenu/ContextMenu.jsx
@@ -0,0 +1,83 @@
+import React from "react";
+
+export class ContextMenu extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.hideContext = this.hideContext.bind(this);
+    this.onClick = this.onClick.bind(this);
+  }
+
+  hideContext() {
+    this.props.onUpdate(false);
+  }
+
+  componentDidMount() {
+    setTimeout(() => {
+      global.addEventListener("click", this.hideContext);
+    }, 0);
+  }
+
+  componentWillUnmount() {
+    global.removeEventListener("click", this.hideContext);
+  }
+
+  onClick(event) {
+    // Eat all clicks on the context menu so they don't bubble up to window.
+    // This prevents the context menu from closing when clicking disabled items
+    // or the separators.
+    event.stopPropagation();
+  }
+
+  render() {
+    return (<span className="context-menu" onClick={this.onClick}>
+      <ul role="menu" className="context-menu-list">
+        {this.props.options.map((option, i) => (option.type === "separator" ?
+          (<li key={i} className="separator" />) :
+          (option.type !== "empty" && <ContextMenuItem key={i} option={option} hideContext={this.hideContext} />)
+        ))}
+      </ul>
+    </span>);
+  }
+}
+
+export class ContextMenuItem extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.onClick = this.onClick.bind(this);
+    this.onKeyDown = this.onKeyDown.bind(this);
+  }
+
+  onClick() {
+    this.props.hideContext();
+    this.props.option.onClick();
+  }
+
+  onKeyDown(event) {
+    const {option} = this.props;
+    switch (event.key) {
+      case "Tab":
+        // tab goes down in context menu, shift + tab goes up in context menu
+        // if we're on the last item, one more tab will close the context menu
+        // similarly, if we're on the first item, one more shift + tab will close it
+        if ((event.shiftKey && option.first) || (!event.shiftKey && option.last)) {
+          this.props.hideContext();
+        }
+        break;
+      case "Enter":
+        this.props.hideContext();
+        option.onClick();
+        break;
+    }
+  }
+
+  render() {
+    const {option} = this.props;
+    return (
+      <li role="menuitem" className="context-menu-item">
+        <a onClick={this.onClick} onKeyDown={this.onKeyDown} tabIndex="0" className={option.disabled ? "disabled" : ""}>
+          {option.icon && <span className={`icon icon-spacer icon-${option.icon}`} />}
+          {option.label}
+        </a>
+      </li>);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/ContextMenu/_ContextMenu.scss
@@ -0,0 +1,52 @@
+.context-menu {
+  background: var(--newtab-contextmenu-background-color);
+  border-radius: $context-menu-border-radius;
+  box-shadow: $context-menu-shadow;
+  display: block;
+  font-size: $context-menu-font-size;
+  margin-inline-start: 5px;
+  offset-inline-start: 100%;
+  position: absolute;
+  top: ($context-menu-button-size / 4);
+  z-index: 10000;
+
+  > ul {
+    list-style: none;
+    margin: 0;
+    padding: $context-menu-outer-padding 0;
+
+    > li {
+      margin: 0;
+      width: 100%;
+
+      &.separator {
+        border-bottom: $border-secondary;
+        margin: $context-menu-outer-padding 0;
+      }
+
+      > a {
+        align-items: center;
+        color: inherit;
+        cursor: pointer;
+        display: flex;
+        line-height: 16px;
+        outline: none;
+        padding: $context-menu-item-padding;
+        white-space: nowrap;
+
+        &:-moz-any(:focus, :hover) {
+          background: var(--newtab-element-hover-color);
+        }
+
+        &:active {
+          background: var(--newtab-element-active-color);
+        }
+
+        &.disabled {
+          opacity: 0.4;
+          pointer-events: none;
+        }
+      }
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/ErrorBoundary/ErrorBoundary.jsx
@@ -0,0 +1,68 @@
+import {FormattedMessage} from "react-intl";
+import React from "react";
+
+export class ErrorBoundaryFallback extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.windowObj = this.props.windowObj || window;
+    this.onClick = this.onClick.bind(this);
+  }
+
+  /**
+   * Since we only get here if part of the page has crashed, do a
+   * forced reload to give us the best chance at recovering.
+   */
+  onClick() {
+    this.windowObj.location.reload(true);
+  }
+
+  render() {
+    const defaultClass = "as-error-fallback";
+    let className;
+    if ("className" in this.props) {
+      className = `${this.props.className} ${defaultClass}`;
+    } else {
+      className = defaultClass;
+    }
+
+    // href="#" to force normal link styling stuff (eg cursor on hover)
+    return (
+      <div className={className}>
+        <div>
+          <FormattedMessage
+            defaultMessage="Oops, something went wrong loading this content."
+            id="error_fallback_default_info" />
+        </div>
+        <span>
+          <a href="#" className="reload-button" onClick={this.onClick}>
+            <FormattedMessage
+              defaultMessage="Refresh page to try again."
+              id="error_fallback_default_refresh_suggestion" />
+          </a>
+        </span>
+      </div>
+    );
+  }
+}
+ErrorBoundaryFallback.defaultProps = {className: "as-error-fallback"};
+
+export class ErrorBoundary extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.state = {hasError: false};
+  }
+
+  componentDidCatch(error, info) {
+    this.setState({hasError: true});
+  }
+
+  render() {
+    if (!this.state.hasError) {
+      return (this.props.children);
+    }
+
+    return <this.props.FallbackComponent className={this.props.className} />;
+  }
+}
+
+ErrorBoundary.defaultProps = {FallbackComponent: ErrorBoundaryFallback};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/ErrorBoundary/_ErrorBoundary.scss
@@ -0,0 +1,17 @@
+.as-error-fallback {
+  align-items: center;
+  border-radius: $border-radius;
+  box-shadow: inset $inner-box-shadow;
+  color: var(--newtab-text-conditional-color);
+  display: flex;
+  flex-direction: column;
+  font-size: $error-fallback-font-size;
+  justify-content: center;
+  justify-items: center;
+  line-height: $error-fallback-line-height;
+
+  a {
+    color: var(--newtab-text-conditional-color);
+    text-decoration: underline;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/LinkMenu/LinkMenu.jsx
@@ -0,0 +1,56 @@
+import {actionCreators as ac} from "common/Actions.jsm";
+import {connect} from "react-redux";
+import {ContextMenu} from "content-src/components/ContextMenu/ContextMenu";
+import {injectIntl} from "react-intl";
+import {LinkMenuOptions} from "content-src/lib/link-menu-options";
+import React from "react";
+
+const DEFAULT_SITE_MENU_OPTIONS = ["CheckPinTopSite", "EditTopSite", "Separator", "OpenInNewWindow", "OpenInPrivateWindow", "Separator", "BlockUrl"];
+
+export class _LinkMenu extends React.PureComponent {
+  getOptions() {
+    const {props} = this;
+    const {site, index, source, isPrivateBrowsingEnabled, siteInfo, platform} = props;
+
+    // Handle special case of default site
+    const propOptions = !site.isDefault ? props.options : DEFAULT_SITE_MENU_OPTIONS;
+
+    const options = propOptions.map(o => LinkMenuOptions[o](site, index, source, isPrivateBrowsingEnabled, siteInfo, platform)).map(option => {
+      const {action, impression, id, string_id, type, userEvent} = option;
+      if (!type && id) {
+        option.label = props.intl.formatMessage({id: string_id || id});
+        option.onClick = () => {
+          props.dispatch(action);
+          if (userEvent) {
+            const userEventData = Object.assign({
+              event: userEvent,
+              source,
+              action_position: index
+            }, siteInfo);
+            props.dispatch(ac.UserEvent(userEventData));
+          }
+          if (impression && props.shouldSendImpressionStats) {
+            props.dispatch(impression);
+          }
+        };
+      }
+      return option;
+    });
+
+    // This is for accessibility to support making each item tabbable.
+    // We want to know which item is the first and which item
+    // is the last, so we can close the context menu accordingly.
+    options[0].first = true;
+    options[options.length - 1].last = true;
+    return options;
+  }
+
+  render() {
+    return (<ContextMenu
+      onUpdate={this.props.onUpdate}
+      options={this.getOptions()} />);
+  }
+}
+
+const getState = state => ({isPrivateBrowsingEnabled: state.Prefs.values.isPrivateBrowsingEnabled, platform: state.Prefs.values.platform});
+export const LinkMenu = connect(getState)(injectIntl(_LinkMenu));
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/ManualMigration/ManualMigration.jsx
@@ -0,0 +1,49 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {connect} from "react-redux";
+import {FormattedMessage} from "react-intl";
+import React from "react";
+
+/**
+ * Manual migration component used to start the profile import wizard.
+ * Message is presented temporarily and will go away if:
+ * 1.  User clicks "No Thanks"
+ * 2.  User completed the data import
+ * 3.  After 3 active days
+ * 4.  User clicks "Cancel" on the import wizard (currently not implemented).
+ */
+export class _ManualMigration extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.onLaunchTour = this.onLaunchTour.bind(this);
+    this.onCancelTour = this.onCancelTour.bind(this);
+  }
+
+  onLaunchTour() {
+    this.props.dispatch(ac.AlsoToMain({type: at.MIGRATION_START}));
+    this.props.dispatch(ac.UserEvent({event: at.MIGRATION_START}));
+  }
+
+  onCancelTour() {
+    this.props.dispatch(ac.AlsoToMain({type: at.MIGRATION_CANCEL}));
+    this.props.dispatch(ac.UserEvent({event: at.MIGRATION_CANCEL}));
+  }
+
+  render() {
+    return (<div className="manual-migration-container">
+        <p>
+          <span className="icon icon-import" />
+          <FormattedMessage id="manual_migration_explanation2" />
+        </p>
+        <div className="manual-migration-actions actions">
+          <button className="dismiss" onClick={this.onCancelTour}>
+            <FormattedMessage id="manual_migration_cancel_button" />
+          </button>
+          <button onClick={this.onLaunchTour}>
+            <FormattedMessage id="manual_migration_import_button" />
+          </button>
+        </div>
+    </div>);
+  }
+}
+
+export const ManualMigration = connect()(_ManualMigration);
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/ManualMigration/_ManualMigration.scss
@@ -0,0 +1,52 @@
+.manual-migration-container {
+  color: var(--newtab-text-conditional-color);
+  font-size: 13px;
+  line-height: 15px;
+  margin-bottom: $section-spacing;
+  text-align: center;
+
+  @media (min-width: $break-point-medium) {
+    display: flex;
+    justify-content: space-between;
+    text-align: left;
+  }
+
+  p {
+    margin: 0;
+    @media (min-width: $break-point-medium) {
+      align-self: center;
+      display: flex;
+      justify-content: space-between;
+    }
+  }
+
+  .icon {
+    display: none;
+    @media (min-width: $break-point-medium) {
+      align-self: center;
+      display: block;
+      fill: var(--newtab-icon-secondary-color);
+      margin-inline-end: 6px;
+    }
+  }
+}
+
+.manual-migration-actions {
+  border: 0;
+  display: block;
+  flex-wrap: nowrap;
+
+  @media (min-width: $break-point-medium) {
+    display: flex;
+    justify-content: space-between;
+    padding: 0;
+  }
+
+  button {
+    align-self: center;
+    height: 26px;
+    margin: 0;
+    margin-inline-start: 20px;
+    padding: 0 12px;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/Search/Search.jsx
@@ -0,0 +1,88 @@
+/* globals ContentSearchUIController */
+"use strict";
+
+import {FormattedMessage, injectIntl} from "react-intl";
+import {actionCreators as ac} from "common/Actions.jsm";
+import {connect} from "react-redux";
+import {IS_NEWTAB} from "content-src/lib/constants";
+import React from "react";
+
+export class _Search extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.onClick = this.onClick.bind(this);
+    this.onInputMount = this.onInputMount.bind(this);
+  }
+
+  handleEvent(event) {
+    // Also track search events with our own telemetry
+    if (event.detail.type === "Search") {
+      this.props.dispatch(ac.UserEvent({event: "SEARCH"}));
+    }
+  }
+
+  onClick(event) {
+    window.gContentSearchController.search(event);
+  }
+
+  componentWillUnmount() {
+    delete window.gContentSearchController;
+  }
+
+  onInputMount(input) {
+    if (input) {
+      // The "healthReportKey" and needs to be "newtab" or "abouthome" so that
+      // BrowserUsageTelemetry.jsm knows to handle events with this name, and
+      // can add the appropriate telemetry probes for search. Without the correct
+      // name, certain tests like browser_UsageTelemetry_content.js will fail
+      // (See github ticket #2348 for more details)
+      const healthReportKey = IS_NEWTAB ? "newtab" : "abouthome";
+
+      // The "searchSource" needs to be "newtab" or "homepage" and is sent with
+      // the search data and acts as context for the search request (See
+      // nsISearchEngine.getSubmission). It is necessary so that search engine
+      // plugins can correctly atribute referrals. (See github ticket #3321 for
+      // more details)
+      const searchSource = IS_NEWTAB ? "newtab" : "homepage";
+
+      // gContentSearchController needs to exist as a global so that tests for
+      // the existing about:home can find it; and so it allows these tests to pass.
+      // In the future, when activity stream is default about:home, this can be renamed
+      window.gContentSearchController = new ContentSearchUIController(input, input.parentNode,
+        healthReportKey, searchSource);
+      addEventListener("ContentSearchClient", this);
+    } else {
+      window.gContentSearchController = null;
+      removeEventListener("ContentSearchClient", this);
+    }
+  }
+
+  /*
+   * Do not change the ID on the input field, as legacy newtab code
+   * specifically looks for the id 'newtab-search-text' on input fields
+   * in order to execute searches in various tests
+   */
+  render() {
+    return (<div className="search-wrapper">
+      <label htmlFor="newtab-search-text" className="search-label">
+        <span className="sr-only"><FormattedMessage id="search_web_placeholder" /></span>
+      </label>
+      <input
+        id="newtab-search-text"
+        maxLength="256"
+        placeholder={this.props.intl.formatMessage({id: "search_web_placeholder"})}
+        ref={this.onInputMount}
+        title={this.props.intl.formatMessage({id: "search_web_placeholder"})}
+        type="search" />
+      <button
+        id="searchSubmit"
+        className="search-button"
+        onClick={this.onClick}
+        title={this.props.intl.formatMessage({id: "search_button"})}>
+        <span className="sr-only"><FormattedMessage id="search_button" /></span>
+      </button>
+    </div>);
+  }
+}
+
+export const Search = connect()(injectIntl(_Search));
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/Search/_Search.scss
@@ -0,0 +1,153 @@
+.search-wrapper {
+  $search-height: 35px;
+  $search-icon-size: 18px;
+  $search-icon-padding: 8px;
+  $search-icon-width: 2 * $search-icon-padding + $search-icon-size;
+  $search-input-left-label-width: 35px;
+  $search-button-width: 36px;
+  $glyph-forward: url('chrome://browser/skin/forward.svg');
+
+  cursor: default;
+  display: flex;
+  height: $search-height;
+  margin-bottom: $section-spacing;
+  position: relative;
+  width: 100%;
+
+  input {
+    background: var(--newtab-textbox-background-color) var(--newtab-search-icon) $search-icon-padding center / $search-icon-size no-repeat;
+    border: solid 1px var(--newtab-search-border-color);
+    box-shadow: $shadow-secondary, 0 0 0 1px $black-15;
+    font-size: 15px;
+    -moz-context-properties: fill;
+    fill: var(--newtab-search-icon-color);
+    padding: 0;
+    padding-inline-end: $search-button-width;
+    padding-inline-start: $search-icon-width;
+    width: 100%;
+
+    &:dir(rtl) {
+      background-position-x: right $search-icon-padding;
+    }
+  }
+
+  &:hover input {
+    box-shadow: $shadow-secondary, 0 0 0 1px $black-25;
+  }
+
+  &:active input,
+  input:focus {
+    border: $input-border-active;
+    box-shadow: var(--newtab-textbox-focus-boxshadow);
+  }
+
+  .search-button {
+    background: $glyph-forward no-repeat center center;
+    background-size: 16px 16px;
+    border: 0;
+    border-radius: 0 $border-radius $border-radius 0;
+    -moz-context-properties: fill;
+    fill: var(--newtab-search-icon-color);
+    height: 100%;
+    offset-inline-end: 0;
+    position: absolute;
+    width: $search-button-width;
+
+    &:focus,
+    &:hover {
+      background-color: $grey-90-10;
+      cursor: pointer;
+    }
+
+    &:active {
+      background-color: $grey-90-20;
+    }
+
+    &:dir(rtl) {
+      transform: scaleX(-1);
+    }
+  }
+}
+
+@at-root {
+  // Adjust the style of the contentSearchUI-generated table
+  .contentSearchSuggestionTable {
+    background-color: var(--newtab-search-dropdown-color);
+    border: 0;
+    box-shadow: $context-menu-shadow;
+    transform: translateY($textbox-shadow-size);
+
+    .contentSearchHeader {
+      background-color: var(--newtab-search-dropdown-header-color);
+      color: var(--newtab-text-secondary-color);
+    }
+
+    .contentSearchHeader,
+    .contentSearchSettingsButton {
+      border-color: var(--newtab-border-secondary-color);
+    }
+
+    .contentSearchSuggestionsList {
+      border: 0;
+    }
+
+    .contentSearchOneOffsTable {
+      background-color: var(--newtab-search-dropdown-header-color);
+      border-top: solid 1px var(--newtab-border-secondary-color);
+    }
+
+    .contentSearchSearchWithHeaderSearchText {
+      color: var(--newtab-text-primary-color);
+    }
+
+    .contentSearchSuggestionsContainer {
+      background-color: var(--newtab-search-dropdown-color);
+    }
+
+    .contentSearchSuggestionRow {
+      &.selected {
+        background: var(--newtab-element-hover-color);
+        color: var(--newtab-text-primary-color);
+
+        &:active {
+          background: var(--newtab-element-active-color);
+        }
+
+        .historyIcon {
+          fill: var(--newtab-icon-secondary-color);
+        }
+      }
+    }
+
+    .contentSearchOneOffsTable {
+      .contentSearchSuggestionsContainer {
+        background-color: var(--newtab-search-dropdown-header-color);
+      }
+    }
+
+    .contentSearchOneOffItem {
+      // Make the border slightly shorter by offsetting from the top and bottom
+      $border-offset: 18%;
+
+      background-image: none;
+      border-image: linear-gradient(transparent $border-offset, var(--newtab-border-secondary-color) $border-offset, var(--newtab-border-secondary-color) 100% - $border-offset, transparent 100% - $border-offset) 1;
+      border-inline-end: 1px solid;
+      position: relative;
+
+      &.selected {
+        background: var(--newtab-element-hover-color);
+      }
+
+      &:active {
+        background: var(--newtab-element-active-color);
+      }
+    }
+
+    .contentSearchSettingsButton {
+      &:hover {
+        background: var(--newtab-element-hover-color);
+        color: var(--newtab-text-primary-color);
+      }
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/SectionMenu/SectionMenu.jsx
@@ -0,0 +1,56 @@
+import {actionCreators as ac} from "common/Actions.jsm";
+import {ContextMenu} from "content-src/components/ContextMenu/ContextMenu";
+import {injectIntl} from "react-intl";
+import React from "react";
+import {SectionMenuOptions} from "content-src/lib/section-menu-options";
+
+const DEFAULT_SECTION_MENU_OPTIONS = ["MoveUp", "MoveDown", "Separator", "RemoveSection", "CheckCollapsed", "Separator", "ManageSection"];
+const WEBEXT_SECTION_MENU_OPTIONS = ["MoveUp", "MoveDown", "Separator", "CheckCollapsed", "Separator", "ManageWebExtension"];
+
+export class _SectionMenu extends React.PureComponent {
+  getOptions() {
+    const {props} = this;
+
+    const propOptions = props.isWebExtension ? [...WEBEXT_SECTION_MENU_OPTIONS] : [...DEFAULT_SECTION_MENU_OPTIONS];
+    // Prepend custom options and a separator
+    if (props.extraOptions) {
+      propOptions.splice(0, 0, ...props.extraOptions, "Separator");
+    }
+    // Insert privacy notice before the last option ("ManageSection")
+    if (props.privacyNoticeURL) {
+      propOptions.splice(-1, 0, "PrivacyNotice");
+    }
+
+    const options = propOptions.map(o => SectionMenuOptions[o](props)).map(option => {
+      const {action, id, type, userEvent} = option;
+      if (!type && id) {
+        option.label = props.intl.formatMessage({id});
+        option.onClick = () => {
+          props.dispatch(action);
+          if (userEvent) {
+            props.dispatch(ac.UserEvent({
+              event: userEvent,
+              source: props.source
+            }));
+          }
+        };
+      }
+      return option;
+    });
+
+    // This is for accessibility to support making each item tabbable.
+    // We want to know which item is the first and which item
+    // is the last, so we can close the context menu accordingly.
+    options[0].first = true;
+    options[options.length - 1].last = true;
+    return options;
+  }
+
+  render() {
+    return (<ContextMenu
+      onUpdate={this.props.onUpdate}
+      options={this.getOptions()} />);
+  }
+}
+
+export const SectionMenu = injectIntl(_SectionMenu);
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/Sections/Sections.jsx
@@ -0,0 +1,258 @@
+import {Card, PlaceholderCard} from "content-src/components/Card/Card";
+import {FormattedMessage, injectIntl} from "react-intl";
+import {actionCreators as ac} from "common/Actions.jsm";
+import {CollapsibleSection} from "content-src/components/CollapsibleSection/CollapsibleSection";
+import {ComponentPerfTimer} from "content-src/components/ComponentPerfTimer/ComponentPerfTimer";
+import {connect} from "react-redux";
+import React from "react";
+import {Topics} from "content-src/components/Topics/Topics";
+import {TopSites} from "content-src/components/TopSites/TopSites";
+
+const VISIBLE = "visible";
+const VISIBILITY_CHANGE_EVENT = "visibilitychange";
+const CARDS_PER_ROW_DEFAULT = 3;
+const CARDS_PER_ROW_COMPACT_WIDE = 4;
+
+function getFormattedMessage(message) {
+  return typeof message === "string" ? <span>{message}</span> : <FormattedMessage {...message} />;
+}
+
+export class Section extends React.PureComponent {
+  get numRows() {
+    const {rowsPref, maxRows, Prefs} = this.props;
+    return rowsPref ? Prefs.values[rowsPref] : maxRows;
+  }
+
+  _dispatchImpressionStats() {
+    const {props} = this;
+    let cardsPerRow = CARDS_PER_ROW_DEFAULT;
+    if (props.compactCards && global.matchMedia(`(min-width: 1072px)`).matches) {
+      // If the section has compact cards and the viewport is wide enough, we show
+      // 4 columns instead of 3.
+      // $break-point-widest = 1072px (from _variables.scss)
+      cardsPerRow = CARDS_PER_ROW_COMPACT_WIDE;
+    }
+    const maxCards = cardsPerRow * this.numRows;
+    const cards = props.rows.slice(0, maxCards);
+
+    if (this.needsImpressionStats(cards)) {
+      props.dispatch(ac.ImpressionStats({
+        source: props.eventSource,
+        tiles: cards.map(link => ({id: link.guid}))
+      }));
+      this.impressionCardGuids = cards.map(link => link.guid);
+    }
+  }
+
+  // This sends an event when a user sees a set of new content. If content
+  // changes while the page is hidden (i.e. preloaded or on a hidden tab),
+  // only send the event if the page becomes visible again.
+  sendImpressionStatsOrAddListener() {
+    const {props} = this;
+
+    if (!props.shouldSendImpressionStats || !props.dispatch) {
+      return;
+    }
+
+    if (props.document.visibilityState === VISIBLE) {
+      this._dispatchImpressionStats();
+    } else {
+      // We should only ever send the latest impression stats ping, so remove any
+      // older listeners.
+      if (this._onVisibilityChange) {
+        props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
+      }
+
+      // When the page becomes visible, send the impression stats ping if the section isn't collapsed.
+      this._onVisibilityChange = () => {
+        if (props.document.visibilityState === VISIBLE) {
+          if (!this.props.pref.collapsed) {
+            this._dispatchImpressionStats();
+          }
+          props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
+        }
+      };
+      props.document.addEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
+    }
+  }
+
+  componentDidMount() {
+    if (this.props.rows.length && !this.props.pref.collapsed) {
+      this.sendImpressionStatsOrAddListener();
+    }
+  }
+
+  componentDidUpdate(prevProps) {
+    const {props} = this;
+    const isCollapsed = props.pref.collapsed;
+    const wasCollapsed = prevProps.pref.collapsed;
+    if (
+      // Don't send impression stats for the empty state
+      props.rows.length &&
+      (
+        // We only want to send impression stats if the content of the cards has changed
+        // and the section is not collapsed...
+        (props.rows !== prevProps.rows && !isCollapsed) ||
+        // or if we are expanding a section that was collapsed.
+        (wasCollapsed && !isCollapsed)
+      )
+    ) {
+      this.sendImpressionStatsOrAddListener();
+    }
+  }
+
+  componentWillUnmount() {
+    if (this._onVisibilityChange) {
+      this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
+    }
+  }
+
+  needsImpressionStats(cards) {
+    if (!this.impressionCardGuids || (this.impressionCardGuids.length !== cards.length)) {
+      return true;
+    }
+
+    for (let i = 0; i < cards.length; i++) {
+      if (cards[i].guid !== this.impressionCardGuids[i]) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  render() {
+    const {
+      id, eventSource, title, icon, rows,
+      emptyState, dispatch, compactCards,
+      contextMenuOptions, initialized, disclaimer,
+      pref, privacyNoticeURL, isFirst, isLast
+    } = this.props;
+
+    const maxCardsPerRow = compactCards ? CARDS_PER_ROW_COMPACT_WIDE : CARDS_PER_ROW_DEFAULT;
+    const {numRows} = this;
+    const maxCards = maxCardsPerRow * numRows;
+    const maxCardsOnNarrow = CARDS_PER_ROW_DEFAULT * numRows;
+
+    // Show topics only for top stories and if it's not initialized yet (so
+    // content doesn't shift when it is loaded) or has loaded with topics
+    const shouldShowTopics = (id === "topstories" &&
+      (!this.props.topics || this.props.topics.length > 0));
+
+    const realRows = rows.slice(0, maxCards);
+
+    // The empty state should only be shown after we have initialized and there is no content.
+    // Otherwise, we should show placeholders.
+    const shouldShowEmptyState = initialized && !rows.length;
+
+    const cards = [];
+    if (!shouldShowEmptyState) {
+      for (let i = 0; i < maxCards; i++) {
+        const link = realRows[i];
+        // On narrow viewports, we only show 3 cards per row. We'll mark the rest as
+        // .hide-for-narrow to hide in CSS via @media query.
+        const className = (i >= maxCardsOnNarrow) ? "hide-for-narrow" : "";
+        cards.push(link ? (
+          <Card key={i}
+            index={i}
+            className={className}
+            dispatch={dispatch}
+            link={link}
+            contextMenuOptions={contextMenuOptions}
+            eventSource={eventSource}
+            shouldSendImpressionStats={this.props.shouldSendImpressionStats}
+            isWebExtension={this.props.isWebExtension} />
+        ) : (
+          <PlaceholderCard key={i} className={className} />
+        ));
+      }
+    }
+
+    const sectionClassName = [
+      "section",
+      compactCards ? "compact-cards" : "normal-cards"
+    ].join(" ");
+
+    // <Section> <-- React component
+    // <section> <-- HTML5 element
+    return (<ComponentPerfTimer {...this.props}>
+      <CollapsibleSection className={sectionClassName} icon={icon}
+        title={title}
+        id={id}
+        eventSource={eventSource}
+        disclaimer={disclaimer}
+        collapsed={this.props.pref.collapsed}
+        showPrefName={(pref && pref.feed) || id}
+        privacyNoticeURL={privacyNoticeURL}
+        Prefs={this.props.Prefs}
+        isFirst={isFirst}
+        isLast={isLast}
+        dispatch={this.props.dispatch}
+        isWebExtension={this.props.isWebExtension}>
+
+        {!shouldShowEmptyState && (<ul className="section-list" style={{padding: 0}}>
+          {cards}
+        </ul>)}
+        {shouldShowEmptyState &&
+          <div className="section-empty-state">
+            <div className="empty-state">
+              {emptyState.icon && emptyState.icon.startsWith("moz-extension://") ?
+                <img className="empty-state-icon icon" style={{"background-image": `url('${emptyState.icon}')`}} /> :
+                <img className={`empty-state-icon icon icon-${emptyState.icon}`} />}
+              <p className="empty-state-message">
+                {getFormattedMessage(emptyState.message)}
+              </p>
+            </div>
+          </div>}
+        {shouldShowTopics && <Topics topics={this.props.topics} read_more_endpoint={this.props.read_more_endpoint} />}
+      </CollapsibleSection>
+    </ComponentPerfTimer>);
+  }
+}
+
+Section.defaultProps = {
+  document: global.document,
+  rows: [],
+  emptyState: {},
+  pref: {},
+  title: ""
+};
+
+export const SectionIntl = connect(state => ({Prefs: state.Prefs}))(injectIntl(Section));
+
+export class _Sections extends React.PureComponent {
+  renderSections() {
+    const sections = [];
+    const enabledSections = this.props.Sections.filter(section => section.enabled);
+    const {sectionOrder, "feeds.topsites": showTopSites} = this.props.Prefs.values;
+    // Enabled sections doesn't include Top Sites, so we add it if enabled.
+    const expectedCount = enabledSections.length + ~~showTopSites;
+
+    for (const sectionId of sectionOrder.split(",")) {
+      const commonProps = {
+        key: sectionId,
+        isFirst: sections.length === 0,
+        isLast: sections.length === expectedCount - 1
+      };
+      if (sectionId === "topsites" && showTopSites) {
+        sections.push(<TopSites {...commonProps} />);
+      } else {
+        const section = enabledSections.find(s => s.id === sectionId);
+        if (section) {
+          sections.push(<SectionIntl {...section} {...commonProps} />);
+        }
+      }
+    }
+    return sections;
+  }
+
+  render() {
+    return (
+      <div className="sections-list">
+        {this.renderSections()}
+      </div>
+    );
+  }
+}
+
+export const Sections = connect(state => ({Sections: state.Sections, Prefs: state.Prefs}))(_Sections);
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/Sections/_Sections.scss
@@ -0,0 +1,77 @@
+.sections-list {
+  .section-list {
+    display: grid;
+    grid-gap: $base-gutter;
+    grid-template-columns: repeat(auto-fit, $card-width);
+    margin: 0;
+
+    @media (max-width: $break-point-medium) {
+      @include context-menu-open-left;
+    }
+
+    @media (min-width: $break-point-medium) and (max-width: $break-point-large) {
+      :nth-child(2n) {
+        @include context-menu-open-left;
+      }
+    }
+
+    @media (min-width: $break-point-large) and (max-width: $break-point-large + 2 * $card-width) {
+      :nth-child(3n) {
+        @include context-menu-open-left;
+      }
+    }
+
+    @media (min-width: $break-point-widest) and (max-width: $break-point-widest + 2 * $card-width) {
+      :nth-child(3n) {
+        @include context-menu-open-left;
+      }
+    }
+  }
+
+  .section-empty-state {
+    border: $border-secondary;
+    border-radius: $border-radius;
+    display: flex;
+    height: $card-height;
+    width: 100%;
+
+    .empty-state {
+      margin: auto;
+      max-width: 350px;
+
+      .empty-state-icon {
+        background-position: center;
+        background-repeat: no-repeat;
+        background-size: 50px 50px;
+        -moz-context-properties: fill;
+        display: block;
+        fill: var(--newtab-icon-secondary-color);
+        height: 50px;
+        margin: 0 auto;
+        width: 50px;
+      }
+
+      .empty-state-message {
+        color: var(--newtab-text-primary-color);
+        font-size: 13px;
+        margin-bottom: 0;
+        text-align: center;
+      }
+    }
+
+    @media (min-width: $break-point-widest) {
+      height: $card-height-large;
+    }
+  }
+}
+
+@media (min-width: $break-point-widest) {
+  .sections-list {
+    // Compact cards stay the same size but normal cards get bigger.
+    .normal-cards {
+      .section-list {
+        grid-template-columns: repeat(auto-fit, $card-width-large);
+      }
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/StartupOverlay/StartupOverlay.jsx
@@ -0,0 +1,89 @@
+import {FormattedMessage, injectIntl} from "react-intl";
+import {actionCreators as ac} from "common/Actions.jsm";
+import {connect} from "react-redux";
+import React from "react";
+
+export class _StartupOverlay extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.onInputChange = this.onInputChange.bind(this);
+    this.onSubmit = this.onSubmit.bind(this);
+    this.clickSkip = this.clickSkip.bind(this);
+    this.initScene = this.initScene.bind(this);
+    this.removeOverlay = this.removeOverlay.bind(this);
+
+    this.state = {emailInput: ""};
+    this.initScene();
+  }
+
+  initScene() {
+    // Timeout to allow the scene to render once before attaching the attribute
+    // to trigger the animation.
+    setTimeout(() => {
+      this.setState({show: true});
+    }, 10);
+  }
+
+  removeOverlay() {
+    window.removeEventListener("visibilitychange", this.removeOverlay);
+    this.setState({show: false});
+    setTimeout(() => {
+      // Allow scrolling and fully remove overlay after animation finishes.
+      document.body.classList.remove("welcome");
+    }, 400);
+  }
+
+  onInputChange(e) {
+    this.setState({emailInput: e.target.value});
+  }
+
+  onSubmit() {
+    this.props.dispatch(ac.UserEvent({event: "SUBMIT_EMAIL"}));
+    window.addEventListener("visibilitychange", this.removeOverlay);
+  }
+
+  clickSkip() {
+    this.props.dispatch(ac.UserEvent({event: "SKIPPED_SIGNIN"}));
+    this.removeOverlay();
+  }
+
+  render() {
+    let termsLink = (<a href="https://accounts.firefox.com/legal/terms" target="_blank" rel="noopener noreferrer"><FormattedMessage id="firstrun_terms_of_service" /></a>);
+    let privacyLink = (<a href="https://accounts.firefox.com/legal/privacy" target="_blank" rel="noopener noreferrer"><FormattedMessage id="firstrun_privacy_notice" /></a>);
+    return (
+      <div className={`overlay-wrapper ${this.state.show ? "show " : ""}`}>
+        <div className="background" />
+        <div className="firstrun-scene">
+          <div className="fxaccounts-container">
+            <div className="firstrun-left-divider">
+              <h1 className="firstrun-title"><FormattedMessage id="firstrun_title" /></h1>
+              <p className="firstrun-content"><FormattedMessage id="firstrun_content" /></p>
+              <a className="firstrun-link" href="https://www.mozilla.org/firefox/features/sync/" target="_blank" rel="noopener noreferrer"><FormattedMessage id="firstrun_learn_more_link" /></a>
+            </div>
+            <div className="firstrun-sign-in">
+              <p className="form-header"><FormattedMessage id="firstrun_form_header" /><span><FormattedMessage id="firstrun_form_sub_header" /></span></p>
+              <form method="get" action="https://accounts.firefox.com?entrypoint=activity-stream-firstrun&utm_source=activity-stream&utm_campaign=firstrun" target="_blank" rel="noopener noreferrer" onSubmit={this.onSubmit}>
+                <input name="service" type="hidden" value="sync" />
+                <input name="action" type="hidden" value="email" />
+                <input name="context" type="hidden" value="fx_desktop_v3" />
+                <input className="email-input" name="email" type="email" required="true" placeholder={this.props.intl.formatMessage({id: "firstrun_email_input_placeholder"})} onChange={this.onInputChange} />
+                <div className="extra-links">
+                  <FormattedMessage
+                    id="firstrun_extra_legal_links"
+                    values={{
+                      terms: termsLink,
+                      privacy: privacyLink
+                    }} />
+                </div>
+                <button className="continue-button" type="submit"><FormattedMessage id="firstrun_continue_to_login" /></button>
+              </form>
+              <button className="skip-button" disabled={!!this.state.emailInput} onClick={this.clickSkip}><FormattedMessage id="firstrun_skip_login" /></button>
+            </div>
+          </div>
+        </div>
+      </div>
+    );
+  }
+}
+
+export const StartupOverlay = connect()(injectIntl(_StartupOverlay));
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/StartupOverlay/_StartupOverlay.scss
@@ -0,0 +1,247 @@
+.activity-stream {
+  &.welcome {
+    overflow: hidden;
+  }
+
+  &:not(.welcome) {
+    .overlay-wrapper {
+      display: none;
+    }
+  }
+}
+
+.overlay-wrapper {
+  position: fixed;
+  top: 0;
+  width: 100vw;
+  height: 100vh;
+  z-index: 21000;
+  font-weight: 200;
+  transition: opacity 0.4s;
+  opacity: 0;
+
+  &.show {
+    transition: none;
+    opacity: 1;
+
+    .firstrun-sign-in {
+      transition: opacity 1.5s, transform 1.5s;
+      transition-delay: 0.2s;
+      transform: translateY(-50%) scale(1);
+      opacity: 1;
+    }
+
+    .firstrun-firefox-logo {
+      transition: opacity 2.3s;
+      opacity: 1;
+    }
+
+    .firstrun-title,
+    .firstrun-content,
+    .firstrun-link {
+      transition: transform 0.5s, opacity 0.8s;
+      transform: translateY(0);
+      opacity: 1;
+    }
+
+    .firstrun-title {
+      transition-delay: 0.2s;
+    }
+
+    .firstrun-content {
+      transition-delay: 0.4s;
+    }
+
+    .firstrun-link {
+      transition-delay: 0.6s;
+    }
+
+    .fxaccounts-container {
+      transition: none;
+      opacity: 1;
+    }
+  }
+}
+
+.background {
+  width: 100%;
+  height: 100%;
+  display: block;
+  background: url('#{$image-path}fox-tail.png') top -200px center no-repeat,
+  linear-gradient(to bottom, $blue-70 40%, #004EC2 60%, $blue-60 80%, #0080FF 90%, #00C7FF 100%) top center no-repeat,
+  $blue-70;
+  background-size: cover;
+}
+
+.firstrun-sign-in {
+  transform: translateY(-50%) scale(0.8);
+  position: relative;
+  top: 50%;
+  width: 358px;
+  opacity: 0;
+  background-color: $white;
+  float: inline-end;
+  color: $grey-90;
+  text-align: center;
+  padding: 10px;
+
+  .extra-links {
+    font-size: 12px;
+    max-width: 340px;
+    margin: 14px 50px;
+    color: #676F7E;
+    cursor: default;
+
+    a {
+      color: $grey-50;
+      cursor: pointer;
+      text-decoration: underline;
+    }
+
+    a:hover,
+    a:active,
+    a:focus {
+      color: $blue-50;
+    }
+  }
+
+  .email-input {
+    box-shadow: none;
+    margin: auto;
+    width: 244px;
+    display: block;
+    height: 40px;
+    padding-inline-start: 20px;
+    border: 1px solid $grey-50;
+    border-radius: 2px;
+    font-size: 16px;
+
+    &:hover {
+      border-color: $grey-90;
+    }
+  }
+
+  .form-header {
+    font-size: 18px;
+    margin: 15px auto;
+  }
+
+  .form-header span {
+    font-size: 14px;
+    margin-top: 4px;
+    display: block;
+  }
+
+  button {
+    border-radius: 2px;
+    display: block;
+    cursor: pointer;
+    margin: 10px auto 0;
+  }
+
+  .continue-button {
+    font-size: 18px;
+    height: 43px;
+    width: 250px;
+    padding: 8px 0;
+    border: 1px solid $blue-60;
+    color: $white;
+    background-color: $blue-50;
+    transition-duration: 150ms;
+    transition-property: background-color;
+
+    &:not([disabled]):active {
+      background: $blue-70;
+      border-color: $blue-80;
+    }
+  }
+
+  .skip-button {
+    font-size: 13px;
+    margin-top: 40px;
+    margin-bottom: 20px;
+    background-color: #FCFCFC;
+    color: $blue-50;
+    border: 1px solid $blue-50;
+    min-height: 24px;
+    padding: 5px 10px;
+    transition: background-color 150ms, color 150ms, border-color 150ms;
+
+    &[disabled] {
+      background-color: #EBEBEB;
+      border-color: #B1B1B1;
+      color: #6A6A6A;
+      cursor: default;
+      opacity: 0.5;
+    }
+
+    &:not([disabled]):hover {
+      background-color: $blue-50;
+      border-color: $blue-60;
+      color: $white;
+    }
+  }
+}
+
+.firstrun-left-divider {
+  position: relative;
+  float: inline-start;
+  clear: both;
+  width: 435px;
+}
+
+.firstrun-content {
+  line-height: 1.5;
+  margin-bottom: 48px;
+  max-width: 352px;
+  background: url('#{$image-path}sync-devices.svg') bottom center no-repeat;
+  padding-bottom: 210px;
+}
+
+.firstrun-link {
+  color: $white;
+  display: block;
+  text-decoration: underline;
+
+  &:hover,
+  &:active,
+  &:focus {
+    color: $white;
+  }
+}
+
+.firstrun-title {
+  background: url('chrome://branding/content/about-logo.png') top left no-repeat;
+  background-size: 90px 90px;
+  margin: 40px 0 10px;
+  padding-top: 110px;
+  font-weight: 200;
+}
+
+[dir='rtl'] {
+  .firstrun-title {
+    background-position: top right;
+  }
+}
+
+.fxaccounts-container {
+  position: absolute;
+  bottom: 0;
+  right: 0;
+  top: 0;
+  left: 0;
+  color: $white;
+  height: 515px;
+  margin: auto;
+  width: 819px;
+  z-index: 10;
+  transition: opacity 0.3s;
+  opacity: 0;
+}
+
+.firstrun-title,
+.firstrun-content,
+.firstrun-link {
+  opacity: 0;
+  transform: translateY(-5px);
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/TopSites/TopSite.jsx
@@ -0,0 +1,425 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {FormattedMessage, injectIntl} from "react-intl";
+import {
+  MIN_CORNER_FAVICON_SIZE,
+  MIN_RICH_FAVICON_SIZE,
+  TOP_SITES_CONTEXT_MENU_OPTIONS,
+  TOP_SITES_SOURCE
+} from "./TopSitesConstants";
+import {LinkMenu} from "content-src/components/LinkMenu/LinkMenu";
+import React from "react";
+import {TOP_SITES_MAX_SITES_PER_ROW} from "common/Reducers.jsm";
+
+export class TopSiteLink extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.onDragEvent = this.onDragEvent.bind(this);
+  }
+
+  /*
+   * Helper to determine whether the drop zone should allow a drop. We only allow
+   * dropping top sites for now.
+   */
+  _allowDrop(e) {
+    return e.dataTransfer.types.includes("text/topsite-index");
+  }
+
+  onDragEvent(event) {
+    switch (event.type) {
+      case "click":
+        // Stop any link clicks if we started any dragging
+        if (this.dragged) {
+          event.preventDefault();
+        }
+        break;
+      case "dragstart":
+        this.dragged = true;
+        event.dataTransfer.effectAllowed = "move";
+        event.dataTransfer.setData("text/topsite-index", this.props.index);
+        event.target.blur();
+        this.props.onDragEvent(event, this.props.index, this.props.link, this.props.title);
+        break;
+      case "dragend":
+        this.props.onDragEvent(event);
+        break;
+      case "dragenter":
+      case "dragover":
+      case "drop":
+        if (this._allowDrop(event)) {
+          event.preventDefault();
+          this.props.onDragEvent(event, this.props.index);
+        }
+        break;
+      case "mousedown":
+        // Reset at the first mouse event of a potential drag
+        this.dragged = false;
+        break;
+    }
+  }
+
+  render() {
+    const {children, className, defaultStyle, isDraggable, link, onClick, title} = this.props;
+    const topSiteOuterClassName = `top-site-outer${className ? ` ${className}` : ""}${link.isDragged ? " dragged" : ""}`;
+    const {tippyTopIcon, faviconSize} = link;
+    const [letterFallback] = title;
+    let imageClassName;
+    let imageStyle;
+    let showSmallFavicon = false;
+    let smallFaviconStyle;
+    let smallFaviconFallback;
+    if (defaultStyle) { // force no styles (letter fallback) even if the link has imagery
+      smallFaviconFallback = false;
+    } else if (link.customScreenshotURL) {
+      // assume high quality custom screenshot and use rich icon styles and class names
+      imageClassName = "top-site-icon rich-icon";
+      imageStyle = {
+        backgroundColor: link.backgroundColor,
+        backgroundImage: `url(${link.screenshot})`
+      };
+    } else if (tippyTopIcon || faviconSize >= MIN_RICH_FAVICON_SIZE) {
+      // styles and class names for top sites with rich icons
+      imageClassName = "top-site-icon rich-icon";
+      imageStyle = {
+        backgroundColor: link.backgroundColor,
+        backgroundImage: `url(${tippyTopIcon || link.favicon})`
+      };
+    } else {
+      // styles and class names for top sites with screenshot + small icon in top left corner
+      imageClassName = `screenshot${link.screenshot ? " active" : ""}`;
+      imageStyle = {backgroundImage: link.screenshot ? `url(${link.screenshot})` : "none"};
+
+      // only show a favicon in top left if it's greater than 16x16
+      if (faviconSize >= MIN_CORNER_FAVICON_SIZE) {
+        showSmallFavicon = true;
+        smallFaviconStyle = {backgroundImage:  `url(${link.favicon})`};
+      } else if (link.screenshot) {
+        // Don't show a small favicon if there is no screenshot, because that
+        // would result in two fallback icons
+        showSmallFavicon = true;
+        smallFaviconFallback = true;
+      }
+    }
+    let draggableProps = {};
+    if (isDraggable) {
+      draggableProps = {
+        onClick: this.onDragEvent,
+        onDragEnd: this.onDragEvent,
+        onDragStart: this.onDragEvent,
+        onMouseDown: this.onDragEvent
+      };
+    }
+    return (<li className={topSiteOuterClassName} onDrop={this.onDragEvent} onDragOver={this.onDragEvent} onDragEnter={this.onDragEvent} onDragLeave={this.onDragEvent} {...draggableProps}>
+      <div className="top-site-inner">
+         <a href={link.url} onClick={onClick}>
+            <div className="tile" aria-hidden={true} data-fallback={letterFallback}>
+              <div className={imageClassName} style={imageStyle} />
+              {showSmallFavicon && <div
+                className="top-site-icon default-icon"
+                data-fallback={smallFaviconFallback && letterFallback}
+                style={smallFaviconStyle} />}
+           </div>
+           <div className={`title ${link.isPinned ? "pinned" : ""}`}>
+             {link.isPinned && <div className="icon icon-pin-small" />}
+              <span dir="auto">{title}</span>
+           </div>
+         </a>
+         {children}
+      </div>
+    </li>);
+  }
+}
+TopSiteLink.defaultProps = {
+  title: "",
+  link: {},
+  isDraggable: true
+};
+
+export class TopSite extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.state = {showContextMenu: false};
+    this.onLinkClick = this.onLinkClick.bind(this);
+    this.onMenuButtonClick = this.onMenuButtonClick.bind(this);
+    this.onMenuUpdate = this.onMenuUpdate.bind(this);
+  }
+
+  /**
+   * Report to telemetry additional information about the item.
+   */
+  _getTelemetryInfo() {
+    const value = {icon_type: this.props.link.iconType};
+    // Filter out "not_pinned" type for being the default
+    if (this.props.link.isPinned) {
+      value.card_type = "pinned";
+    }
+    return {value};
+  }
+
+  userEvent(event) {
+    this.props.dispatch(ac.UserEvent(Object.assign({
+      event,
+      source: TOP_SITES_SOURCE,
+      action_position: this.props.index
+    }, this._getTelemetryInfo())));
+  }
+
+  onLinkClick(event) {
+    this.userEvent("CLICK");
+
+    // Specially handle a top site link click for "typed" frecency bonus as
+    // specified as a property on the link.
+    event.preventDefault();
+    const {altKey, button, ctrlKey, metaKey, shiftKey} = event;
+    this.props.dispatch(ac.OnlyToMain({
+      type: at.OPEN_LINK,
+      data: Object.assign(this.props.link, {event: {altKey, button, ctrlKey, metaKey, shiftKey}})
+    }));
+  }
+
+  onMenuButtonClick(event) {
+    event.preventDefault();
+    this.props.onActivate(this.props.index);
+    this.setState({showContextMenu: true});
+  }
+
+  onMenuUpdate(showContextMenu) {
+    this.setState({showContextMenu});
+  }
+
+  render() {
+    const {props} = this;
+    const {link} = props;
+    const isContextMenuOpen = this.state.showContextMenu && props.activeIndex === props.index;
+    const title = link.label || link.hostname;
+    return (<TopSiteLink {...props} onClick={this.onLinkClick} onDragEvent={this.props.onDragEvent} className={`${props.className || ""}${isContextMenuOpen ? " active" : ""}`} title={title}>
+        <div>
+          <button className="context-menu-button icon" onClick={this.onMenuButtonClick}>
+            <span className="sr-only">
+              <FormattedMessage id="context_menu_button_sr" values={{title}} />
+            </span>
+          </button>
+          {isContextMenuOpen &&
+            <LinkMenu
+              dispatch={props.dispatch}
+              index={props.index}
+              onUpdate={this.onMenuUpdate}
+              options={TOP_SITES_CONTEXT_MENU_OPTIONS}
+              site={link}
+              siteInfo={this._getTelemetryInfo()}
+              source={TOP_SITES_SOURCE} />
+          }
+        </div>
+    </TopSiteLink>);
+  }
+}
+TopSite.defaultProps = {
+  link: {},
+  onActivate() {}
+};
+
+export class TopSitePlaceholder extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.onEditButtonClick = this.onEditButtonClick.bind(this);
+  }
+
+  onEditButtonClick() {
+    this.props.dispatch(
+      {type: at.TOP_SITES_EDIT, data: {index: this.props.index}});
+  }
+
+  render() {
+    return (<TopSiteLink {...this.props} className={`placeholder ${this.props.className || ""}`} isDraggable={false}>
+      <button className="context-menu-button edit-button icon"
+       title={this.props.intl.formatMessage({id: "edit_topsites_edit_button"})}
+       onClick={this.onEditButtonClick} />
+    </TopSiteLink>);
+  }
+}
+
+export class _TopSiteList extends React.PureComponent {
+  static get DEFAULT_STATE() {
+    return {
+      activeIndex: null,
+      draggedIndex: null,
+      draggedSite: null,
+      draggedTitle: null,
+      topSitesPreview: null
+    };
+  }
+
+  constructor(props) {
+    super(props);
+    this.state = _TopSiteList.DEFAULT_STATE;
+    this.onDragEvent = this.onDragEvent.bind(this);
+    this.onActivate = this.onActivate.bind(this);
+  }
+
+  componentWillReceiveProps(nextProps) {
+    if (this.state.draggedSite) {
+      const prevTopSites = this.props.TopSites && this.props.TopSites.rows;
+      const newTopSites = nextProps.TopSites && nextProps.TopSites.rows;
+      if (prevTopSites && prevTopSites[this.state.draggedIndex] &&
+        prevTopSites[this.state.draggedIndex].url === this.state.draggedSite.url &&
+        (!newTopSites[this.state.draggedIndex] || newTopSites[this.state.draggedIndex].url !== this.state.draggedSite.url)) {
+        // We got the new order from the redux store via props. We can clear state now.
+        this.setState(_TopSiteList.DEFAULT_STATE);
+      }
+    }
+  }
+
+  userEvent(event, index) {
+    this.props.dispatch(ac.UserEvent({
+      event,
+      source: TOP_SITES_SOURCE,
+      action_position: index
+    }));
+  }
+
+  onDragEvent(event, index, link, title) {
+    switch (event.type) {
+      case "dragstart":
+        this.dropped = false;
+        this.setState({
+          draggedIndex: index,
+          draggedSite: link,
+          draggedTitle: title,
+          activeIndex: null
+        });
+        this.userEvent("DRAG", index);
+        break;
+      case "dragend":
+        if (!this.dropped) {
+          // If there was no drop event, reset the state to the default.
+          this.setState(_TopSiteList.DEFAULT_STATE);
+        }
+        break;
+      case "dragenter":
+        if (index === this.state.draggedIndex) {
+          this.setState({topSitesPreview: null});
+        } else {
+          this.setState({topSitesPreview: this._makeTopSitesPreview(index)});
+        }
+        break;
+      case "drop":
+        if (index !== this.state.draggedIndex) {
+          this.dropped = true;
+          this.props.dispatch(ac.AlsoToMain({
+            type: at.TOP_SITES_INSERT,
+            data: {
+              site: {
+                url: this.state.draggedSite.url,
+                label: this.state.draggedTitle,
+                customScreenshotURL: this.state.draggedSite.customScreenshotURL
+              },
+              index,
+              draggedFromIndex: this.state.draggedIndex
+            }
+          }));
+          this.userEvent("DROP", index);
+        }
+        break;
+    }
+  }
+
+  _getTopSites() {
+    // Make a copy of the sites to truncate or extend to desired length
+    let topSites = this.props.TopSites.rows.slice();
+    topSites.length = this.props.TopSitesRows * TOP_SITES_MAX_SITES_PER_ROW;
+    return topSites;
+  }
+
+  /**
+   * Make a preview of the topsites that will be the result of dropping the currently
+   * dragged site at the specified index.
+   */
+  _makeTopSitesPreview(index) {
+    const topSites = this._getTopSites();
+    topSites[this.state.draggedIndex] = null;
+    const pinnedOnly = topSites.map(site => ((site && site.isPinned) ? site : null));
+    const unpinned = topSites.filter(site => site && !site.isPinned);
+    const siteToInsert = Object.assign({}, this.state.draggedSite, {isPinned: true, isDragged: true});
+    if (!pinnedOnly[index]) {
+      pinnedOnly[index] = siteToInsert;
+    } else {
+      // Find the hole to shift the pinned site(s) towards. We shift towards the
+      // hole left by the site being dragged.
+      let holeIndex = index;
+      const indexStep = index > this.state.draggedIndex ? -1 : 1;
+      while (pinnedOnly[holeIndex]) {
+        holeIndex += indexStep;
+      }
+
+      // Shift towards the hole.
+      const shiftingStep = index > this.state.draggedIndex ? 1 : -1;
+      while (holeIndex !== index) {
+        const nextIndex = holeIndex + shiftingStep;
+        pinnedOnly[holeIndex] = pinnedOnly[nextIndex];
+        holeIndex = nextIndex;
+      }
+      pinnedOnly[index] = siteToInsert;
+    }
+
+    // Fill in the remaining holes with unpinned sites.
+    const preview = pinnedOnly;
+    for (let i = 0; i < preview.length; i++) {
+      if (!preview[i]) {
+        preview[i] = unpinned.shift() || null;
+      }
+    }
+
+    return preview;
+  }
+
+  onActivate(index) {
+    this.setState({activeIndex: index});
+  }
+
+  render() {
+    const {props} = this;
+    const topSites = this.state.topSitesPreview || this._getTopSites();
+    const topSitesUI = [];
+    const commonProps = {
+      onDragEvent: this.onDragEvent,
+      dispatch: props.dispatch,
+      intl: props.intl
+    };
+    // We assign a key to each placeholder slot. We need it to be independent
+    // of the slot index (i below) so that the keys used stay the same during
+    // drag and drop reordering and the underlying DOM nodes are reused.
+    // This mostly (only?) affects linux so be sure to test on linux before changing.
+    let holeIndex = 0;
+
+    // On narrow viewports, we only show 6 sites per row. We'll mark the rest as
+    // .hide-for-narrow to hide in CSS via @media query.
+    const maxNarrowVisibleIndex = props.TopSitesRows * 6;
+
+    for (let i = 0, l = topSites.length; i < l; i++) {
+      const link = topSites[i] && Object.assign({}, topSites[i], {iconType: this.props.topSiteIconType(topSites[i])});
+      const slotProps = {
+        key: link ? link.url : holeIndex++,
+        index: i
+      };
+      if (i >= maxNarrowVisibleIndex) {
+        slotProps.className = "hide-for-narrow";
+      }
+      topSitesUI.push(!link ? (
+        <TopSitePlaceholder
+          {...slotProps}
+          {...commonProps} />
+      ) : (
+        <TopSite
+          link={link}
+          activeIndex={this.state.activeIndex}
+          onActivate={this.onActivate}
+          {...slotProps}
+          {...commonProps} />
+      ));
+    }
+    return (<ul className={`top-sites-list${this.state.draggedSite ? " dnd-active" : ""}`}>
+      {topSitesUI}
+    </ul>);
+  }
+}
+
+export const TopSiteList = injectIntl(_TopSiteList);
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/TopSites/TopSiteForm.jsx
@@ -0,0 +1,251 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {FormattedMessage} from "react-intl";
+import React from "react";
+import {TOP_SITES_SOURCE} from "./TopSitesConstants";
+import {TopSiteFormInput} from "./TopSiteFormInput";
+import {TopSiteLink} from "./TopSite";
+
+export class TopSiteForm extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    const {site} = props;
+    this.state = {
+      label: site ? (site.label || site.hostname) : "",
+      url: site ? site.url : "",
+      validationError: false,
+      customScreenshotUrl: site ? site.customScreenshotURL : "",
+      showCustomScreenshotForm: site ? site.customScreenshotURL : false
+    };
+    this.onClearScreenshotInput = this.onClearScreenshotInput.bind(this);
+    this.onLabelChange = this.onLabelChange.bind(this);
+    this.onUrlChange = this.onUrlChange.bind(this);
+    this.onCancelButtonClick = this.onCancelButtonClick.bind(this);
+    this.onClearUrlClick = this.onClearUrlClick.bind(this);
+    this.onDoneButtonClick = this.onDoneButtonClick.bind(this);
+    this.onCustomScreenshotUrlChange = this.onCustomScreenshotUrlChange.bind(this);
+    this.onPreviewButtonClick = this.onPreviewButtonClick.bind(this);
+    this.onEnableScreenshotUrlForm = this.onEnableScreenshotUrlForm.bind(this);
+    this.validateUrl = this.validateUrl.bind(this);
+  }
+
+  onLabelChange(event) {
+    this.setState({"label": event.target.value});
+  }
+
+  onUrlChange(event) {
+    this.setState({
+      url: event.target.value,
+      validationError: false
+    });
+  }
+
+  onClearUrlClick() {
+    this.setState({
+      url: "",
+      validationError: false
+    });
+  }
+
+  onEnableScreenshotUrlForm() {
+    this.setState({showCustomScreenshotForm: true});
+  }
+
+  _updateCustomScreenshotInput(customScreenshotUrl) {
+    this.setState({
+      customScreenshotUrl,
+      validationError: false
+    });
+    this.props.dispatch({type: at.PREVIEW_REQUEST_CANCEL});
+  }
+
+  onCustomScreenshotUrlChange(event) {
+    this._updateCustomScreenshotInput(event.target.value);
+  }
+
+  onClearScreenshotInput() {
+    this._updateCustomScreenshotInput("");
+  }
+
+  onCancelButtonClick(ev) {
+    ev.preventDefault();
+    this.props.onClose();
+  }
+
+  onDoneButtonClick(ev) {
+    ev.preventDefault();
+
+    if (this.validateForm()) {
+      const site = {url: this.cleanUrl(this.state.url)};
+      const {index} = this.props;
+      if (this.state.label !== "") {
+        site.label = this.state.label;
+      }
+
+      if (this.state.customScreenshotUrl) {
+        site.customScreenshotURL = this.cleanUrl(this.state.customScreenshotUrl);
+      } else if (this.props.site && this.props.site.customScreenshotURL) {
+        // Used to flag that previously cached screenshot should be removed
+        site.customScreenshotURL = null;
+      }
+      this.props.dispatch(ac.AlsoToMain({
+        type: at.TOP_SITES_PIN,
+        data: {site, index}
+      }));
+      this.props.dispatch(ac.UserEvent({
+        source: TOP_SITES_SOURCE,
+        event: "TOP_SITES_EDIT",
+        action_position: index
+      }));
+
+      this.props.onClose();
+    }
+  }
+
+  onPreviewButtonClick(event) {
+    event.preventDefault();
+    if (this.validateForm()) {
+      this.props.dispatch(ac.AlsoToMain({
+        type: at.PREVIEW_REQUEST,
+        data: {url: this.cleanUrl(this.state.customScreenshotUrl)}
+      }));
+      this.props.dispatch(ac.UserEvent({
+        source: TOP_SITES_SOURCE,
+        event: "PREVIEW_REQUEST"
+      }));
+    }
+  }
+
+  cleanUrl(url) {
+    // If we are missing a protocol, prepend http://
+    if (!url.startsWith("http:") && !url.startsWith("https:")) {
+      return `http://${url}`;
+    }
+    return url;
+  }
+
+  _tryParseUrl(url) {
+    try {
+      return new URL(url);
+    } catch (e) {
+      return null;
+    }
+  }
+
+  validateUrl(url) {
+    const validProtocols = ["http:", "https:"];
+    const urlObj = this._tryParseUrl(url) || this._tryParseUrl(this.cleanUrl(url));
+
+    return urlObj && validProtocols.includes(urlObj.protocol);
+  }
+
+  validateCustomScreenshotUrl() {
+    const {customScreenshotUrl} = this.state;
+    return !customScreenshotUrl || this.validateUrl(customScreenshotUrl);
+  }
+
+  validateForm() {
+    const validate = this.validateUrl(this.state.url) && this.validateCustomScreenshotUrl();
+
+    if (!validate) {
+      this.setState({validationError: true});
+    }
+
+    return validate;
+  }
+
+  _renderCustomScreenshotInput() {
+    const {customScreenshotUrl} = this.state;
+    const requestFailed = this.props.previewResponse === "";
+    const validationError = (this.state.validationError && !this.validateCustomScreenshotUrl()) || requestFailed;
+    // Set focus on error if the url field is valid or when the input is first rendered and is empty
+    const shouldFocus = (validationError && this.validateUrl(this.state.url)) || !customScreenshotUrl;
+    const isLoading = this.props.previewResponse === null &&
+      customScreenshotUrl && this.props.previewUrl === this.cleanUrl(customScreenshotUrl);
+
+    if (!this.state.showCustomScreenshotForm) {
+      return (<a className="enable-custom-image-input" onClick={this.onEnableScreenshotUrlForm}>
+        <FormattedMessage id="topsites_form_use_image_link" />
+      </a>);
+    }
+    return (<div className="custom-image-input-container">
+      <TopSiteFormInput
+        errorMessageId={requestFailed ? "topsites_form_image_validation" : "topsites_form_url_validation"}
+        loading={isLoading}
+        onChange={this.onCustomScreenshotUrlChange}
+        onClear={this.onClearScreenshotInput}
+        shouldFocus={shouldFocus}
+        typeUrl={true}
+        value={customScreenshotUrl}
+        validationError={validationError}
+        titleId="topsites_form_image_url_label"
+        placeholderId="topsites_form_url_placeholder"
+        intl={this.props.intl} />
+    </div>);
+  }
+
+  render() {
+    const {customScreenshotUrl} = this.state;
+    const requestFailed = this.props.previewResponse === "";
+    // For UI purposes, editing without an existing link is "add"
+    const showAsAdd = !this.props.site;
+    const previous = (this.props.site && this.props.site.customScreenshotURL) || "";
+    const changed = customScreenshotUrl && this.cleanUrl(customScreenshotUrl) !== previous;
+    // Preview mode if changes were made to the custom screenshot URL and no preview was received yet
+    // or the request failed
+    const previewMode = changed && !this.props.previewResponse;
+    const previewLink = Object.assign({}, this.props.site);
+    if (this.props.previewResponse) {
+      previewLink.screenshot = this.props.previewResponse;
+      previewLink.customScreenshotURL = this.props.previewUrl;
+    }
+    return (
+      <form className="topsite-form">
+        <div className="form-input-container">
+          <h3 className="section-title">
+            <FormattedMessage id={showAsAdd ? "topsites_form_add_header" : "topsites_form_edit_header"} />
+          </h3>
+          <div className="fields-and-preview">
+            <div className="form-wrapper">
+              <TopSiteFormInput onChange={this.onLabelChange}
+                value={this.state.label}
+                titleId="topsites_form_title_label"
+                placeholderId="topsites_form_title_placeholder"
+                intl={this.props.intl} />
+              <TopSiteFormInput onChange={this.onUrlChange}
+                shouldFocus={this.state.validationError && !this.validateUrl(this.state.url)}
+                value={this.state.url}
+                onClear={this.onClearUrlClick}
+                validationError={this.state.validationError && !this.validateUrl(this.state.url)}
+                titleId="topsites_form_url_label"
+                typeUrl={true}
+                placeholderId="topsites_form_url_placeholder"
+                errorMessageId="topsites_form_url_validation"
+                intl={this.props.intl} />
+              {this._renderCustomScreenshotInput()}
+            </div>
+            <TopSiteLink link={previewLink}
+              defaultStyle={requestFailed}
+              title={this.state.label} />
+          </div>
+        </div>
+        <section className="actions">
+          <button className="cancel" type="button" onClick={this.onCancelButtonClick}>
+            <FormattedMessage id="topsites_form_cancel_button" />
+          </button>
+          {previewMode ?
+            <button className="done preview" type="submit" onClick={this.onPreviewButtonClick}>
+              <FormattedMessage id="topsites_form_preview_button" />
+            </button> :
+            <button className="done" type="submit" onClick={this.onDoneButtonClick}>
+              <FormattedMessage id={showAsAdd ? "topsites_form_add_button" : "topsites_form_save_button"} />
+            </button>}
+        </section>
+      </form>
+    );
+  }
+}
+
+TopSiteForm.defaultProps = {
+  site: null,
+  index: -1
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/TopSites/TopSiteFormInput.jsx
@@ -0,0 +1,66 @@
+import {FormattedMessage} from "react-intl";
+import React from "react";
+
+export class TopSiteFormInput extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.state = {validationError: this.props.validationError};
+    this.onChange = this.onChange.bind(this);
+    this.onMount = this.onMount.bind(this);
+  }
+
+  componentWillReceiveProps(nextProps) {
+    if (nextProps.shouldFocus && !this.props.shouldFocus) {
+      this.input.focus();
+    }
+    if (nextProps.validationError && !this.props.validationError) {
+      this.setState({validationError: true});
+    }
+    // If the component is in an error state but the value was cleared by the parent
+    if (this.state.validationError && !nextProps.value) {
+      this.setState({validationError: false});
+    }
+  }
+
+  onChange(ev) {
+    if (this.state.validationError) {
+      this.setState({validationError: false});
+    }
+    this.props.onChange(ev);
+  }
+
+  onMount(input) {
+    this.input = input;
+  }
+
+  render() {
+    const showClearButton = this.props.value && this.props.onClear;
+    const {typeUrl} = this.props;
+    const {validationError} = this.state;
+
+    return (<label><FormattedMessage id={this.props.titleId} />
+      <div className={`field ${typeUrl ? "url" : ""}${validationError ? " invalid" : ""}`}>
+        {this.props.loading ?
+          <div className="loading-container"><div className="loading-animation" /></div> :
+          showClearButton && <div className="icon icon-clear-input" onClick={this.props.onClear} />}
+        <input type="text"
+          value={this.props.value}
+          ref={this.onMount}
+          onChange={this.onChange}
+          placeholder={this.props.intl.formatMessage({id: this.props.placeholderId})}
+          autoFocus={this.props.shouldFocus}
+          disabled={this.props.loading} />
+        {validationError &&
+          <aside className="error-tooltip">
+            <FormattedMessage id={this.props.errorMessageId} />
+          </aside>}
+      </div>
+    </label>);
+  }
+}
+
+TopSiteFormInput.defaultProps = {
+  showClearButton: false,
+  value: "",
+  validationError: false
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/TopSites/TopSites.jsx
@@ -0,0 +1,143 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {MIN_CORNER_FAVICON_SIZE, MIN_RICH_FAVICON_SIZE, TOP_SITES_SOURCE} from "./TopSitesConstants";
+import {CollapsibleSection} from "content-src/components/CollapsibleSection/CollapsibleSection";
+import {ComponentPerfTimer} from "content-src/components/ComponentPerfTimer/ComponentPerfTimer";
+import {connect} from "react-redux";
+import {injectIntl} from "react-intl";
+import React from "react";
+import {TOP_SITES_MAX_SITES_PER_ROW} from "common/Reducers.jsm";
+import {TopSiteForm} from "./TopSiteForm";
+import {TopSiteList} from "./TopSite";
+
+function topSiteIconType(link) {
+  if (link.customScreenshotURL) {
+    return "custom_screenshot";
+  }
+  if (link.tippyTopIcon || link.faviconRef === "tippytop") {
+    return "tippytop";
+  }
+  if (link.faviconSize >= MIN_RICH_FAVICON_SIZE) {
+    return "rich_icon";
+  }
+  if (link.screenshot && link.faviconSize >= MIN_CORNER_FAVICON_SIZE) {
+    return "screenshot_with_icon";
+  }
+  if (link.screenshot) {
+    return "screenshot";
+  }
+  return "no_image";
+}
+
+/**
+ * Iterates through TopSites and counts types of images.
+ * @param acc Accumulator for reducer.
+ * @param topsite Entry in TopSites.
+ */
+function countTopSitesIconsTypes(topSites) {
+  const countTopSitesTypes = (acc, link) => {
+    acc[topSiteIconType(link)]++;
+    return acc;
+  };
+
+  return topSites.reduce(countTopSitesTypes, {
+    "custom_screenshot": 0,
+    "screenshot_with_icon": 0,
+    "screenshot": 0,
+    "tippytop": 0,
+    "rich_icon": 0,
+    "no_image": 0
+  });
+}
+
+export class _TopSites extends React.PureComponent {
+  constructor(props) {
+    super(props);
+    this.onFormClose = this.onFormClose.bind(this);
+  }
+
+  /**
+   * Dispatch session statistics about the quality of TopSites icons and pinned count.
+   */
+  _dispatchTopSitesStats() {
+    const topSites = this._getVisibleTopSites();
+    const topSitesIconsStats = countTopSitesIconsTypes(topSites);
+    const topSitesPinned = topSites.filter(site => !!site.isPinned).length;
+    // Dispatch telemetry event with the count of TopSites images types.
+    this.props.dispatch(ac.AlsoToMain({
+      type: at.SAVE_SESSION_PERF_DATA,
+      data: {topsites_icon_stats: topSitesIconsStats, topsites_pinned: topSitesPinned}
+    }));
+  }
+
+  /**
+   * Return the TopSites that are visible based on prefs and window width.
+   */
+  _getVisibleTopSites() {
+    // We hide 2 sites per row when not in the wide layout.
+    let sitesPerRow = TOP_SITES_MAX_SITES_PER_ROW;
+    // $break-point-widest = 1072px (from _variables.scss)
+    if (!global.matchMedia(`(min-width: 1072px)`).matches) {
+      sitesPerRow -= 2;
+    }
+    return this.props.TopSites.rows.slice(0, this.props.TopSitesRows * sitesPerRow);
+  }
+
+  componentDidUpdate() {
+    this._dispatchTopSitesStats();
+  }
+
+  componentDidMount() {
+    this._dispatchTopSitesStats();
+  }
+
+  onFormClose() {
+    this.props.dispatch(ac.UserEvent({
+      source: TOP_SITES_SOURCE,
+      event: "TOP_SITES_EDIT_CLOSE"
+    }));
+    this.props.dispatch({type: at.TOP_SITES_CANCEL_EDIT});
+  }
+
+  render() {
+    const {props} = this;
+    const {editForm} = props.TopSites;
+
+    return (<ComponentPerfTimer id="topsites" initialized={props.TopSites.initialized} dispatch={props.dispatch}>
+      <CollapsibleSection
+        className="top-sites"
+        icon="topsites"
+        id="topsites"
+        title={{id: "header_top_sites"}}
+        extraMenuOptions={["AddTopSite"]}
+        showPrefName="feeds.topsites"
+        eventSource={TOP_SITES_SOURCE}
+        collapsed={props.TopSites.pref ? props.TopSites.pref.collapsed : undefined}
+        isFirst={props.isFirst}
+        isLast={props.isLast}
+        dispatch={props.dispatch}>
+        <TopSiteList TopSites={props.TopSites} TopSitesRows={props.TopSitesRows} dispatch={props.dispatch} intl={props.intl} topSiteIconType={topSiteIconType} />
+        <div className="edit-topsites-wrapper">
+          {editForm &&
+            <div className="edit-topsites">
+              <div className="modal-overlay" onClick={this.onFormClose} />
+              <div className="modal">
+                <TopSiteForm
+                  site={props.TopSites.rows[editForm.index]}
+                  onClose={this.onFormClose}
+                  dispatch={this.props.dispatch}
+                  intl={this.props.intl}
+                  {...editForm} />
+              </div>
+            </div>
+          }
+        </div>
+      </CollapsibleSection>
+    </ComponentPerfTimer>);
+  }
+}
+
+export const TopSites = connect(state => ({
+  TopSites: state.TopSites,
+  Prefs: state.Prefs,
+  TopSitesRows: state.Prefs.values.topSitesRows
+}))(injectIntl(_TopSites));
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/TopSites/TopSitesConstants.js
@@ -0,0 +1,7 @@
+export const TOP_SITES_SOURCE = "TOP_SITES";
+export const TOP_SITES_CONTEXT_MENU_OPTIONS = ["CheckPinTopSite", "EditTopSite", "Separator",
+  "OpenInNewWindow", "OpenInPrivateWindow", "Separator", "BlockUrl", "DeleteUrl"];
+// minimum size necessary to show a rich icon instead of a screenshot
+export const MIN_RICH_FAVICON_SIZE = 96;
+// minimum size necessary to show any icon in the top left corner with a screenshot
+export const MIN_CORNER_FAVICON_SIZE = 16;
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/TopSites/_TopSites.scss
@@ -0,0 +1,485 @@
+$top-sites-size: $grid-unit;
+$top-sites-border-radius: 6px;
+$top-sites-title-height: 30px;
+$top-sites-vertical-space: 8px;
+$screenshot-size: cover;
+$rich-icon-size: 96px;
+$default-icon-wrapper-size: 42px;
+$default-icon-size: 32px;
+$default-icon-offset: 6px;
+$half-base-gutter: $base-gutter / 2;
+
+.top-sites {
+  // Take back the margin from the bottom row of vertical spacing as well as the
+  // extra whitespace below the title text as it's vertically centered.
+  margin-bottom: $section-spacing - ($top-sites-vertical-space + $top-sites-title-height / 3);
+}
+
+.top-sites-list {
+  list-style: none;
+  margin: 0 (-$half-base-gutter);
+  padding: 0;
+
+  // Two columns
+  @media (max-width: $break-point-small) {
+    :nth-child(2n+1) {
+      @include context-menu-open-middle;
+    }
+
+    :nth-child(2n) {
+      @include context-menu-open-left;
+    }
+  }
+
+  // Three columns
+  @media (min-width: $break-point-small) and (max-width: $break-point-medium) {
+    :nth-child(3n+2),
+    :nth-child(3n) {
+      @include context-menu-open-left;
+    }
+  }
+
+  // Four columns
+  @media (min-width: $break-point-medium) and (max-width: $break-point-large) {
+    :nth-child(4n) {
+      @include context-menu-open-left;
+    }
+  }
+  @media (min-width: $break-point-medium) and (max-width: $break-point-medium + $card-width) {
+    :nth-child(4n+3) {
+      @include context-menu-open-left;
+    }
+  }
+
+  // Six columns
+  @media (min-width: $break-point-large) and (max-width: $break-point-large + 2 * $card-width) {
+    :nth-child(6n) {
+      @include context-menu-open-left;
+    }
+  }
+  @media (min-width: $break-point-large) and (max-width: $break-point-large + $card-width) {
+    :nth-child(6n+5) {
+      @include context-menu-open-left;
+    }
+  }
+
+  // Eight columns
+  @media (min-width: $break-point-widest) and (max-width: $break-point-widest + 2 * $card-width) {
+    :nth-child(8n) {
+      @include context-menu-open-left;
+    }
+  }
+  @media (min-width: $break-point-widest) and (max-width: $break-point-widest + $card-width) {
+    :nth-child(8n+7) {
+      @include context-menu-open-left;
+    }
+  }
+
+  @media not all and (min-width: $break-point-widest) {
+    .hide-for-narrow {
+      display: none;
+    }
+  }
+
+  li {
+    margin: 0 0 $top-sites-vertical-space;
+  }
+
+  &:not(.dnd-active) {
+    .top-site-outer:-moz-any(.active, :focus, :hover) {
+      .tile {
+        @include fade-in;
+      }
+
+      @include context-menu-button-hover;
+    }
+  }
+}
+
+// container for drop zone
+.top-site-outer {
+  padding: 0 $half-base-gutter;
+  display: inline-block;
+
+  // container for context menu
+  .top-site-inner {
+    position: relative;
+
+    > a {
+      color: inherit;
+      display: block;
+      outline: none;
+
+      &:-moz-any(.active, :focus) {
+        .tile {
+          @include fade-in;
+        }
+      }
+    }
+  }
+
+  @include context-menu-button;
+
+  .tile { // sass-lint:disable-block property-sort-order
+    border-radius: $top-sites-border-radius;
+    box-shadow: inset $inner-box-shadow, var(--newtab-card-shadow);
+    height: $top-sites-size;
+    position: relative;
+    width: $top-sites-size;
+
+    // For letter fallback
+    align-items: center;
+    color: var(--newtab-text-secondary-color);
+    display: flex;
+    font-size: 32px;
+    font-weight: 200;
+    justify-content: center;
+    text-transform: uppercase;
+
+    &::before {
+      content: attr(data-fallback);
+    }
+  }
+
+  .screenshot {
+    background-color: $white;
+    background-position: top left;
+    background-size: $screenshot-size;
+    border-radius: $top-sites-border-radius;
+    box-shadow: inset $inner-box-shadow;
+    height: 100%;
+    left: 0;
+    opacity: 0;
+    position: absolute;
+    top: 0;
+    transition: opacity 1s;
+    width: 100%;
+
+    &.active {
+      opacity: 1;
+    }
+  }
+
+  // Some common styles for all icons (rich and default) in top sites
+  .top-site-icon {
+    background-color: var(--newtab-topsites-background-color);
+    background-position: center center;
+    background-repeat: no-repeat;
+    border-radius: $top-sites-border-radius;
+    box-shadow: var(--newtab-topsites-icon-shadow);
+    position: absolute;
+  }
+
+  .rich-icon {
+    background-size: cover;
+    height: 100%;
+    offset-inline-start: 0;
+    top: 0;
+    width: 100%;
+  }
+
+  .default-icon { // sass-lint:disable block property-sort-order
+    background-size: $default-icon-size;
+    bottom: -$default-icon-offset;
+    height: $default-icon-wrapper-size;
+    offset-inline-end: -$default-icon-offset;
+    width: $default-icon-wrapper-size;
+
+    // for corner letter fallback
+    align-items: center;
+    display: flex;
+    font-size: 20px;
+    justify-content: center;
+
+    &[data-fallback]::before {
+      content: attr(data-fallback);
+    }
+  }
+
+  .title {
+    color: var(--newtab-topsites-label-color);
+    font: message-box;
+    height: $top-sites-title-height;
+    line-height: $top-sites-title-height;
+    text-align: center;
+    width: $top-sites-size;
+    position: relative;
+
+    .icon {
+      fill: var(--newtab-icon-tertiary-color);
+      offset-inline-start: 0;
+      position: absolute;
+      top: 10px;
+    }
+
+    span {
+      height: $top-sites-title-height;
+      display: block;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+
+    &.pinned {
+      span {
+        padding: 0 13px;
+      }
+    }
+  }
+
+  .edit-button {
+    background-image: url('#{$image-path}glyph-edit-16.svg');
+  }
+
+  &.placeholder {
+    .tile {
+      box-shadow: inset $inner-box-shadow;
+    }
+
+    .screenshot {
+      display: none;
+    }
+  }
+
+  &.dragged {
+    .tile {
+      background: $grey-20;
+      box-shadow: none;
+
+      *,
+      &::before {
+        display: none;
+      }
+    }
+
+    .title {
+      visibility: hidden;
+    }
+  }
+}
+
+.edit-topsites-wrapper {
+  .modal {
+    box-shadow: $shadow-secondary;
+    left: 0;
+    margin: 0 auto;
+    position: fixed;
+    right: 0;
+    top: 40px;
+    width: $wrapper-default-width;
+
+    @media (min-width: $break-point-small) {
+      width: $wrapper-max-width-small;
+    }
+
+    @media (min-width: $break-point-medium) {
+      width: $wrapper-max-width-medium;
+    }
+
+    @media (min-width: $break-point-large) {
+      width: $wrapper-max-width-large;
+    }
+  }
+}
+
+.topsite-form {
+  $form-width: 300px;
+  $form-spacing: 32px;
+
+  .form-input-container {
+    max-width: $form-width + 3 * $form-spacing + $rich-icon-size;
+    margin: 0 auto;
+    padding: $form-spacing;
+
+    .top-site-outer {
+      padding: 0;
+      margin: 24px 0 0;
+      margin-inline-start: $form-spacing;
+      pointer-events: none;
+    }
+
+    .section-title {
+      text-transform: none;
+      font-size: 16px;
+      margin: 0 0 16px;
+    }
+  }
+
+  .fields-and-preview {
+    display: flex;
+  }
+
+  label {
+    font-size: $section-title-font-size;
+  }
+
+  .form-wrapper {
+    width: 100%;
+
+    .field {
+      position: relative;
+
+      .icon-clear-input {
+        position: absolute;
+        transform: translateY(-50%);
+        top: 50%;
+        offset-inline-end: 8px;
+      }
+    }
+
+    .url {
+      input:dir(ltr) {
+        padding-right: 32px;
+      }
+
+      input:dir(rtl) {
+        padding-left: 32px;
+
+        &:not(:placeholder-shown) {
+          direction: ltr;
+          text-align: right;
+        }
+      }
+    }
+
+    .enable-custom-image-input {
+      display: inline-block;
+      font-size: 13px;
+      margin-top: 4px;
+      cursor: pointer;
+
+      &:hover {
+        text-decoration: underline;
+      }
+    }
+
+    .custom-image-input-container {
+      margin-top: 4px;
+
+      .loading-container {
+        width: 16px;
+        height: 16px;
+        overflow: hidden;
+        position: absolute;
+        transform: translateY(-50%);
+        top: 50%;
+        offset-inline-end: 8px;
+      }
+
+      // This animation is derived from Firefox's tab loading animation
+      // See https://searchfox.org/mozilla-central/rev/b29daa46443b30612415c35be0a3c9c13b9dc5f6/browser/themes/shared/tabs.inc.css#208-216
+      .loading-animation {
+        @keyframes tab-throbber-animation {
+          100% { transform: translateX(-960px); }
+        }
+
+        @keyframes tab-throbber-animation-rtl {
+          100% { transform: translateX(960px); }
+        }
+
+        width: 960px;
+        height: 16px;
+        -moz-context-properties: fill;
+        fill: $blue-50;
+        background-image: url('chrome://browser/skin/tabbrowser/loading.svg');
+        animation: tab-throbber-animation 1.05s steps(60) infinite;
+
+        &:dir(rtl) {
+          animation-name: tab-throbber-animation-rtl;
+        }
+      }
+    }
+
+    input {
+      &[type='text'] {
+        background-color: var(--newtab-textbox-background-color);
+        border: $input-border;
+        margin: 8px 0;
+        padding: 0 8px;
+        height: 32px;
+        width: 100%;
+        font-size: 15px;
+
+        &:focus {
+          border: $input-border-active;
+          box-shadow: var(--newtab-textbox-focus-boxshadow);
+        }
+
+        &[disabled] {
+          border: $input-border;
+          box-shadow: none;
+          opacity: 0.4;
+        }
+      }
+    }
+
+    .invalid {
+      input {
+        &[type='text'] {
+          border: $input-error-border;
+          box-shadow: $input-error-boxshadow;
+        }
+      }
+    }
+
+    .error-tooltip {
+      animation: fade-up-tt 450ms;
+      background: $red-60;
+      border-radius: 2px;
+      color: $white;
+      offset-inline-start: 3px;
+      padding: 5px 12px;
+      position: absolute;
+      top: 44px;
+      z-index: 1;
+
+      // tooltip caret
+      &::before {
+        background: $red-60;
+        bottom: -8px;
+        content: '.';
+        height: 16px;
+        offset-inline-start: 12px;
+        position: absolute;
+        text-indent: -999px;
+        top: -7px;
+        transform: rotate(45deg);
+        white-space: nowrap;
+        width: 16px;
+        z-index: -1;
+      }
+    }
+  }
+
+  .actions {
+    justify-content: flex-end;
+
+    button {
+      margin-inline-start: 10px;
+      margin-inline-end: 0;
+    }
+  }
+
+  @media (max-width: $break-point-small) {
+    .fields-and-preview {
+      flex-direction: column;
+
+      .top-site-outer {
+        margin-inline-start: 0;
+      }
+    }
+  }
+}
+
+//used for tooltips below form element
+@keyframes fade-up-tt {
+  0% {
+    opacity: 0;
+    transform: translateY(15px);
+  }
+
+  100% {
+    opacity: 1;
+    transform: translateY(0);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/Topics/Topics.jsx
@@ -0,0 +1,25 @@
+import {FormattedMessage} from "react-intl";
+import React from "react";
+
+export class Topic extends React.PureComponent {
+  render() {
+    const {url, name} = this.props;
+    return (<li><a key={name} className="topic-link" href={url}>{name}</a></li>);
+  }
+}
+
+export class Topics extends React.PureComponent {
+  render() {
+    const {topics, read_more_endpoint} = this.props;
+    return (
+      <div className="topic">
+        <span><FormattedMessage id="pocket_read_more" /></span>
+        <ul>{topics && topics.map(t => <Topic key={t.name} url={t.url} name={t.name} />)}</ul>
+
+        {read_more_endpoint && <a className="topic-read-more" href={read_more_endpoint}>
+          <FormattedMessage id="pocket_read_even_more" />
+        </a>}
+      </div>
+    );
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/components/Topics/_Topics.scss
@@ -0,0 +1,77 @@
+.topic {
+  color: var(--newtab-section-navigation-text-color);
+  font-size: 12px;
+  line-height: 1.6;
+  margin-top: $topic-margin-top;
+
+  @media (min-width: $break-point-large) {
+    line-height: 16px;
+  }
+
+  ul {
+    margin: 0;
+    padding: 0;
+    @media (min-width: $break-point-large) {
+      display: inline;
+      padding-inline-start: 12px;
+    }
+  }
+
+
+  ul li {
+    display: inline-block;
+
+    &::after {
+      content: '•';
+      padding: 8px;
+    }
+
+    &:last-child::after {
+      content: none;
+    }
+  }
+
+  .topic-link {
+    color: var(--newtab-link-secondary-color);
+    font-weight: bold;
+  }
+
+  .topic-read-more {
+    color: var(--newtab-link-secondary-color);
+    font-weight: bold;
+
+    @media (min-width: $break-point-large) {
+      // This is floating to accomodate a very large number of topics and/or
+      // very long topic names due to l10n.
+      float: right;
+
+      &:dir(rtl) {
+        float: left;
+      }
+    }
+
+    &::after {
+      background: url('#{$image-path}topic-show-more-12.svg') no-repeat center center;
+      content: '';
+      -moz-context-properties: fill;
+      display: inline-block;
+      fill: var(--newtab-link-secondary-color);
+      height: 16px;
+      margin-inline-start: 5px;
+      vertical-align: top;
+      width: 12px;
+    }
+
+    &:dir(rtl)::after  {
+      transform: scaleX(-1);
+    }
+  }
+
+  // This is a clearfix to for the topics-read-more link which is floating and causes
+  // some jank when we set overflow:hidden for the animation.
+  &::after {
+    clear: both;
+    content: '';
+    display: table;
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/lib/constants.js
@@ -0,0 +1,1 @@
+export const IS_NEWTAB = global.document && global.document.documentURI === "about:newtab";
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/lib/detect-user-session-start.js
@@ -0,0 +1,65 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {perfService as perfSvc} from "common/PerfService.jsm";
+
+const VISIBLE = "visible";
+const VISIBILITY_CHANGE_EVENT = "visibilitychange";
+
+export class DetectUserSessionStart {
+  constructor(store, options = {}) {
+    this._store = store;
+    // Overrides for testing
+    this.document = options.document || global.document;
+    this._perfService = options.perfService || perfSvc;
+    this._onVisibilityChange = this._onVisibilityChange.bind(this);
+  }
+
+  /**
+   * sendEventOrAddListener - Notify immediately if the page is already visible,
+   *                    or else set up a listener for when visibility changes.
+   *                    This is needed for accurate session tracking for telemetry,
+   *                    because tabs are pre-loaded.
+   */
+  sendEventOrAddListener() {
+    if (this.document.visibilityState === VISIBLE) {
+      // If the document is already visible, to the user, send a notification
+      // immediately that a session has started.
+      this._sendEvent();
+    } else {
+      // If the document is not visible, listen for when it does become visible.
+      this.document.addEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
+    }
+  }
+
+  /**
+   * _sendEvent - Sends a message to the main process to indicate the current
+   *              tab is now visible to the user, includes the
+   *              visibility_event_rcvd_ts time in ms from the UNIX epoch.
+   */
+  _sendEvent() {
+    this._perfService.mark("visibility_event_rcvd_ts");
+
+    try {
+      let visibility_event_rcvd_ts = this._perfService
+        .getMostRecentAbsMarkStartByName("visibility_event_rcvd_ts");
+
+      this._store.dispatch(ac.AlsoToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: {visibility_event_rcvd_ts}
+      }));
+    } catch (ex) {
+      // If this failed, it's likely because the `privacy.resistFingerprinting`
+      // pref is true.  We should at least not blow up.
+    }
+  }
+
+  /**
+   * _onVisibilityChange - If the visibility has changed to visible, sends a notification
+   *                      and removes the event listener. This should only be called once per tab.
+   */
+  _onVisibilityChange() {
+    if (this.document.visibilityState === VISIBLE) {
+      this._sendEvent();
+      this.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/lib/init-store.js
@@ -0,0 +1,139 @@
+/* eslint-env mozilla/frame-script */
+
+import {actionCreators as ac, actionTypes as at, actionUtils as au} from "common/Actions.jsm";
+import {applyMiddleware, combineReducers, createStore} from "redux";
+
+export const MERGE_STORE_ACTION = "NEW_TAB_INITIAL_STATE";
+export const OUTGOING_MESSAGE_NAME = "ActivityStream:ContentToMain";
+export const INCOMING_MESSAGE_NAME = "ActivityStream:MainToContent";
+export const EARLY_QUEUED_ACTIONS = [at.SAVE_SESSION_PERF_DATA, at.PAGE_PRERENDERED];
+
+/**
+ * A higher-order function which returns a reducer that, on MERGE_STORE action,
+ * will return the action.data object merged into the previous state.
+ *
+ * For all other actions, it merely calls mainReducer.
+ *
+ * Because we want this to merge the entire state object, it's written as a
+ * higher order function which takes the main reducer (itself often a call to
+ * combineReducers) as a parameter.
+ *
+ * @param  {function} mainReducer reducer to call if action != MERGE_STORE_ACTION
+ * @return {function}             a reducer that, on MERGE_STORE_ACTION action,
+ *                                will return the action.data object merged
+ *                                into the previous state, and the result
+ *                                of calling mainReducer otherwise.
+ */
+function mergeStateReducer(mainReducer) {
+  return (prevState, action) => {
+    if (action.type === MERGE_STORE_ACTION) {
+      return {...prevState, ...action.data};
+    }
+
+    return mainReducer(prevState, action);
+  };
+}
+
+/**
+ * messageMiddleware - Middleware that looks for SentToMain type actions, and sends them if necessary
+ */
+const messageMiddleware = store => next => action => {
+  const skipLocal = action.meta && action.meta.skipLocal;
+  if (au.isSendToMain(action)) {
+    sendAsyncMessage(OUTGOING_MESSAGE_NAME, action);
+  }
+  if (!skipLocal) {
+    next(action);
+  }
+};
+
+export const rehydrationMiddleware = store => next => action => {
+  if (store._didRehydrate) {
+    return next(action);
+  }
+
+  const isMergeStoreAction = action.type === MERGE_STORE_ACTION;
+  const isRehydrationRequest = action.type === at.NEW_TAB_STATE_REQUEST;
+
+  if (isRehydrationRequest) {
+    store._didRequestInitialState = true;
+    return next(action);
+  }
+
+  if (isMergeStoreAction) {
+    store._didRehydrate = true;
+    return next(action);
+  }
+
+  // If init happened after our request was made, we need to re-request
+  if (store._didRequestInitialState && action.type === at.INIT) {
+    return next(ac.AlsoToMain({type: at.NEW_TAB_STATE_REQUEST}));
+  }
+
+  if (au.isBroadcastToContent(action) || au.isSendToOneContent(action) || au.isSendToPreloaded(action)) {
+    // Note that actions received before didRehydrate will not be dispatched
+    // because this could negatively affect preloading and the the state
+    // will be replaced by rehydration anyway.
+    return null;
+  }
+
+  return next(action);
+};
+
+/**
+ * This middleware queues up all the EARLY_QUEUED_ACTIONS until it receives
+ * the first action from main. This is useful for those actions for main which
+ * require higher reliability, i.e. the action will not be lost in the case
+ * that it gets sent before the main is ready to receive it. Conversely, any
+ * actions allowed early are accepted to be ignorable or re-sendable.
+ */
+export const queueEarlyMessageMiddleware = store => next => action => {
+  if (store._receivedFromMain) {
+    next(action);
+  } else if (au.isFromMain(action)) {
+    next(action);
+    store._receivedFromMain = true;
+    // Sending out all the early actions as main is ready now
+    if (store._earlyActionQueue) {
+      store._earlyActionQueue.forEach(next);
+      store._earlyActionQueue = [];
+    }
+  } else if (EARLY_QUEUED_ACTIONS.includes(action.type)) {
+    store._earlyActionQueue = store._earlyActionQueue || [];
+    store._earlyActionQueue.push(action);
+  } else {
+    // Let any other type of action go through
+    next(action);
+  }
+};
+
+/**
+ * initStore - Create a store and listen for incoming actions
+ *
+ * @param  {object} reducers An object containing Redux reducers
+ * @param  {object} intialState (optional) The initial state of the store, if desired
+ * @return {object}          A redux store
+ */
+export function initStore(reducers, initialState) {
+  const store = createStore(
+    mergeStateReducer(combineReducers(reducers)),
+    initialState,
+    global.addMessageListener && applyMiddleware(rehydrationMiddleware, queueEarlyMessageMiddleware, messageMiddleware)
+  );
+
+  store._didRehydrate = false;
+  store._didRequestInitialState = false;
+
+  if (global.addMessageListener) {
+    global.addMessageListener(INCOMING_MESSAGE_NAME, msg => {
+      try {
+        store.dispatch(msg.data);
+      } catch (ex) {
+        console.error("Content msg:", msg, "Dispatch error: ", ex); // eslint-disable-line no-console
+        dump(`Content msg: ${JSON.stringify(msg)}\nDispatch error: ${ex}\n${ex.stack}`);
+      }
+    });
+  }
+
+  return store;
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/lib/link-menu-options.js
@@ -0,0 +1,215 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+
+const _OpenInPrivateWindow = site => ({
+  id: "menu_action_open_private_window",
+  icon: "new-window-private",
+  action: ac.OnlyToMain({
+    type: at.OPEN_PRIVATE_WINDOW,
+    data: {url: site.url, referrer: site.referrer}
+  }),
+  userEvent: "OPEN_PRIVATE_WINDOW"
+});
+
+export const GetPlatformString = platform => {
+  switch (platform) {
+    case "win":
+      return "menu_action_show_file_windows";
+    case "macosx":
+      return "menu_action_show_file_mac_os";
+    case "linux":
+      return "menu_action_show_file_linux";
+    default:
+      return "menu_action_show_file_default";
+  }
+};
+
+/**
+ * List of functions that return items that can be included as menu options in a
+ * LinkMenu. All functions take the site as the first parameter, and optionally
+ * the index of the site.
+ */
+export const LinkMenuOptions = {
+  Separator: () => ({type: "separator"}),
+  EmptyItem: () => ({type: "empty"}),
+  RemoveBookmark: site => ({
+    id: "menu_action_remove_bookmark",
+    icon: "bookmark-added",
+    action: ac.AlsoToMain({
+      type: at.DELETE_BOOKMARK_BY_ID,
+      data: site.bookmarkGuid
+    }),
+    userEvent: "BOOKMARK_DELETE"
+  }),
+  AddBookmark: site => ({
+    id: "menu_action_bookmark",
+    icon: "bookmark-hollow",
+    action: ac.AlsoToMain({
+      type: at.BOOKMARK_URL,
+      data: {url: site.url, title: site.title, type: site.type}
+    }),
+    userEvent: "BOOKMARK_ADD"
+  }),
+  OpenInNewWindow: site => ({
+    id: "menu_action_open_new_window",
+    icon: "new-window",
+    action: ac.AlsoToMain({
+      type: at.OPEN_NEW_WINDOW,
+      data: {
+        referrer: site.referrer,
+        typedBonus: site.typedBonus,
+        url: site.url
+      }
+    }),
+    userEvent: "OPEN_NEW_WINDOW"
+  }),
+  BlockUrl: (site, index, eventSource) => ({
+    id: "menu_action_dismiss",
+    icon: "dismiss",
+    action: ac.AlsoToMain({
+      type: at.BLOCK_URL,
+      data: {url: site.url, pocket_id: site.pocket_id}
+    }),
+    impression: ac.ImpressionStats({
+      source: eventSource,
+      block: 0,
+      tiles: [{id: site.guid, pos: index}]
+    }),
+    userEvent: "BLOCK"
+  }),
+
+  // This is an option for web extentions which will result in remove items from
+  // memory and notify the web extenion, rather than using the built-in block list.
+  WebExtDismiss: (site, index, eventSource) => ({
+    id: "menu_action_webext_dismiss",
+    string_id: "menu_action_dismiss",
+    icon: "dismiss",
+    action: ac.WebExtEvent(at.WEBEXT_DISMISS, {
+      source: eventSource,
+      url: site.url,
+      action_position: index
+    })
+  }),
+  DeleteUrl: (site, index, eventSource, isEnabled, siteInfo) => ({
+    id: "menu_action_delete",
+    icon: "delete",
+    action: {
+      type: at.DIALOG_OPEN,
+      data: {
+        onConfirm: [
+          ac.AlsoToMain({type: at.DELETE_HISTORY_URL, data: {url: site.url, pocket_id: site.pocket_id, forceBlock: site.bookmarkGuid}}),
+          ac.UserEvent(Object.assign({event: "DELETE", source: eventSource, action_position: index}, siteInfo))
+        ],
+        eventSource,
+        body_string_id: ["confirm_history_delete_p1", "confirm_history_delete_notice_p2"],
+        confirm_button_string_id: "menu_action_delete",
+        cancel_button_string_id: "topsites_form_cancel_button",
+        icon: "modal-delete"
+      }
+    },
+    userEvent: "DIALOG_OPEN"
+  }),
+  ShowFile: (site, index, eventSource, isEnabled, siteInfo, platform) => ({
+    id: GetPlatformString(platform),
+    icon: "search",
+    action: ac.OnlyToMain({
+      type: at.SHOW_DOWNLOAD_FILE,
+      data: {url: site.url}
+    })
+  }),
+  OpenFile: site => ({
+    id: "menu_action_open_file",
+    icon: "open-file",
+    action: ac.OnlyToMain({
+      type: at.OPEN_DOWNLOAD_FILE,
+      data: {url: site.url}
+    })
+  }),
+  CopyDownloadLink: site => ({
+    id: "menu_action_copy_download_link",
+    icon: "copy",
+    action: ac.OnlyToMain({
+      type: at.COPY_DOWNLOAD_LINK,
+      data: {url: site.url}
+    })
+  }),
+  GoToDownloadPage: site => ({
+    id: "menu_action_go_to_download_page",
+    icon: "download",
+    action: ac.OnlyToMain({
+      type: at.OPEN_LINK,
+      data: {url: site.referrer}
+    }),
+    disabled: !site.referrer
+  }),
+  RemoveDownload: site => ({
+    id: "menu_action_remove_download",
+    icon: "delete",
+    action: ac.OnlyToMain({
+      type: at.REMOVE_DOWNLOAD_FILE,
+      data: {url: site.url}
+    })
+  }),
+  PinTopSite: (site, index) => ({
+    id: "menu_action_pin",
+    icon: "pin",
+    action: ac.AlsoToMain({
+      type: at.TOP_SITES_PIN,
+      data: {site: {url: site.url}, index}
+    }),
+    userEvent: "PIN"
+  }),
+  UnpinTopSite: site => ({
+    id: "menu_action_unpin",
+    icon: "unpin",
+    action: ac.AlsoToMain({
+      type: at.TOP_SITES_UNPIN,
+      data: {site: {url: site.url}}
+    }),
+    userEvent: "UNPIN"
+  }),
+  SaveToPocket: (site, index, eventSource) => ({
+    id: "menu_action_save_to_pocket",
+    icon: "pocket",
+    action: ac.AlsoToMain({
+      type: at.SAVE_TO_POCKET,
+      data: {site: {url: site.url, title: site.title}}
+    }),
+    impression: ac.ImpressionStats({
+      source: eventSource,
+      pocket: 0,
+      tiles: [{id: site.guid, pos: index}]
+    }),
+    userEvent: "SAVE_TO_POCKET"
+  }),
+  DeleteFromPocket: site => ({
+    id: "menu_action_delete_pocket",
+    icon: "delete",
+    action: ac.AlsoToMain({
+      type: at.DELETE_FROM_POCKET,
+      data: {pocket_id: site.pocket_id}
+    }),
+    userEvent: "DELETE_FROM_POCKET"
+  }),
+  ArchiveFromPocket: site => ({
+    id: "menu_action_archive_pocket",
+    icon: "check",
+    action: ac.AlsoToMain({
+      type: at.ARCHIVE_FROM_POCKET,
+      data: {pocket_id: site.pocket_id}
+    }),
+    userEvent: "ARCHIVE_FROM_POCKET"
+  }),
+  EditTopSite: (site, index) => ({
+    id: "edit_topsites_button_text",
+    icon: "edit",
+    action: {
+      type: at.TOP_SITES_EDIT,
+      data: {index}
+    }
+  }),
+  CheckBookmark: site => (site.bookmarkGuid ? LinkMenuOptions.RemoveBookmark(site) : LinkMenuOptions.AddBookmark(site)),
+  CheckPinTopSite: (site, index) => (site.isPinned ? LinkMenuOptions.UnpinTopSite(site) : LinkMenuOptions.PinTopSite(site, index)),
+  CheckSavedToPocket: (site, index) => (site.pocket_id ? LinkMenuOptions.DeleteFromPocket(site) : LinkMenuOptions.SaveToPocket(site, index)),
+  CheckBookmarkOrArchive: site => (site.pocket_id ? LinkMenuOptions.ArchiveFromPocket(site) : LinkMenuOptions.CheckBookmark(site)),
+  OpenInPrivateWindow: (site, index, eventSource, isEnabled) => (isEnabled ? _OpenInPrivateWindow(site) : LinkMenuOptions.EmptyItem())
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/lib/section-menu-options.js
@@ -0,0 +1,74 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+
+/**
+ * List of functions that return items that can be included as menu options in a
+ * SectionMenu. All functions take the section as the only parameter.
+ */
+export const SectionMenuOptions = {
+  Separator: () => ({type: "separator"}),
+  MoveUp: section => ({
+    id: "section_menu_action_move_up",
+    icon: "arrowhead-up",
+    action: ac.OnlyToMain({
+      type: at.SECTION_MOVE,
+      data: {id: section.id, direction: -1}
+    }),
+    userEvent: "MENU_MOVE_UP",
+    disabled: !!section.isFirst
+  }),
+  MoveDown: section => ({
+    id: "section_menu_action_move_down",
+    icon: "arrowhead-down",
+    action: ac.OnlyToMain({
+      type: at.SECTION_MOVE,
+      data: {id: section.id, direction: +1}
+    }),
+    userEvent: "MENU_MOVE_DOWN",
+    disabled: !!section.isLast
+  }),
+  RemoveSection: section => ({
+    id: "section_menu_action_remove_section",
+    icon: "dismiss",
+    action: ac.SetPref(section.showPrefName, false),
+    userEvent: "MENU_REMOVE"
+  }),
+  CollapseSection: section => ({
+    id: "section_menu_action_collapse_section",
+    icon: "minimize",
+    action: ac.OnlyToMain({type: at.UPDATE_SECTION_PREFS, data: {id: section.id, value: {collapsed: true}}}),
+    userEvent: "MENU_COLLAPSE"
+  }),
+  ExpandSection: section => ({
+    id: "section_menu_action_expand_section",
+    icon: "maximize",
+    action: ac.OnlyToMain({type: at.UPDATE_SECTION_PREFS, data: {id: section.id, value: {collapsed: false}}}),
+    userEvent: "MENU_EXPAND"
+  }),
+  ManageSection: section => ({
+    id: "section_menu_action_manage_section",
+    icon: "settings",
+    action: ac.OnlyToMain({type: at.SETTINGS_OPEN}),
+    userEvent: "MENU_MANAGE"
+  }),
+  ManageWebExtension: section => ({
+    id: "section_menu_action_manage_webext",
+    icon: "settings",
+    action: ac.OnlyToMain({type: at.OPEN_WEBEXT_SETTINGS, data: section.id})
+  }),
+  AddTopSite: section => ({
+    id: "section_menu_action_add_topsite",
+    icon: "add",
+    action: {type: at.TOP_SITES_EDIT, data: {index: -1}},
+    userEvent: "MENU_ADD_TOPSITE"
+  }),
+  PrivacyNotice: section => ({
+    id: "section_menu_action_privacy_notice",
+    icon: "info",
+    action: ac.OnlyToMain({
+      type: at.OPEN_LINK,
+      data: {url: section.privacyNoticeURL}
+    }),
+    userEvent: "MENU_PRIVACY_NOTICE"
+  }),
+  CheckCollapsed: section => (section.collapsed ? SectionMenuOptions.ExpandSection(section) : SectionMenuOptions.CollapseSection(section))
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/lib/snippets.js
@@ -0,0 +1,427 @@
+const DATABASE_NAME = "snippets_db";
+const DATABASE_VERSION = 1;
+const SNIPPETS_OBJECTSTORE_NAME = "snippets";
+export const SNIPPETS_UPDATE_INTERVAL_MS = 14400000; // 4 hours.
+
+const SNIPPETS_ENABLED_EVENT = "Snippets:Enabled";
+const SNIPPETS_DISABLED_EVENT = "Snippets:Disabled";
+
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {ASRouterContent} from "content-src/asrouter/asrouter-content";
+
+/**
+ * SnippetsMap - A utility for cacheing values related to the snippet. It has
+ *               the same interface as a Map, but is optionally backed by
+ *               indexedDB for persistent storage.
+ *               Call .connect() to open a database connection and restore any
+ *               previously cached data, if necessary.
+ *
+ */
+export class SnippetsMap extends Map {
+  constructor(dispatch) {
+    super();
+    this._db = null;
+    this._dispatch = dispatch;
+  }
+
+  set(key, value) {
+    super.set(key, value);
+    return this._dbTransaction(db => db.put(value, key));
+  }
+
+  delete(key) {
+    super.delete(key);
+    return this._dbTransaction(db => db.delete(key));
+  }
+
+  clear() {
+    super.clear();
+    this._dispatch(ac.OnlyToMain({type: at.SNIPPETS_BLOCKLIST_CLEARED}));
+    return this._dbTransaction(db => db.clear());
+  }
+
+  get blockList() {
+    return this.get("blockList") || [];
+  }
+
+  /**
+   * blockSnippetById - Blocks a snippet given an id
+   *
+   * @param  {str|int} id   The id of the snippet
+   * @return {Promise}      Resolves when the id has been written to indexedDB,
+   *                        or immediately if the snippetMap is not connected
+   */
+  async blockSnippetById(id) {
+    if (!id) {
+      return;
+    }
+    const {blockList} = this;
+    if (!blockList.includes(id)) {
+      blockList.push(id);
+      this._dispatch(ac.AlsoToMain({type: at.SNIPPETS_BLOCKLIST_UPDATED, data: id}));
+      await this.set("blockList", blockList);
+    }
+  }
+
+  disableOnboarding() {
+    this._dispatch(ac.AlsoToMain({type: at.DISABLE_ONBOARDING}));
+  }
+
+  showFirefoxAccounts() {
+    this._dispatch(ac.AlsoToMain({type: at.SHOW_FIREFOX_ACCOUNTS}));
+  }
+
+  getTotalBookmarksCount() {
+    return new Promise(resolve => {
+      this._dispatch(ac.OnlyToMain({type: at.TOTAL_BOOKMARKS_REQUEST}));
+      global.addMessageListener("ActivityStream:MainToContent", function onMessage({data: action}) {
+        if (action.type === at.TOTAL_BOOKMARKS_RESPONSE) {
+          resolve(action.data);
+          global.removeMessageListener("ActivityStream:MainToContent", onMessage);
+        }
+      });
+    });
+  }
+
+  getAddonsInfo() {
+    return new Promise(resolve => {
+      this._dispatch(ac.OnlyToMain({type: at.ADDONS_INFO_REQUEST}));
+      global.addMessageListener("ActivityStream:MainToContent", function onMessage({data: action}) {
+        if (action.type === at.ADDONS_INFO_RESPONSE) {
+          resolve(action.data);
+          global.removeMessageListener("ActivityStream:MainToContent", onMessage);
+        }
+      });
+    });
+  }
+
+  /**
+   * connect - Attaches an indexedDB back-end to the Map so that any set values
+   *           are also cached in a store. It also restores any existing values
+   *           that are already stored in the indexedDB store.
+   *
+   * @return {type}  description
+   */
+  async connect() {
+    // Open the connection
+    const db = await this._openDB();
+
+    // Restore any existing values
+    await this._restoreFromDb(db);
+
+    // Attach a reference to the db
+    this._db = db;
+  }
+
+  /**
+   * _dbTransaction - Returns a db transaction wrapped with the given modifier
+   *                  function as a Promise. If the db has not been connected,
+   *                  it resolves immediately.
+   *
+   * @param  {func} modifier A function to call with the transaction
+   * @return {obj}           A Promise that resolves when the transaction has
+   *                         completed or errored
+   */
+  _dbTransaction(modifier) {
+    if (!this._db) {
+      return Promise.resolve();
+    }
+    return new Promise((resolve, reject) => {
+      const transaction = modifier(
+        this._db
+          .transaction(SNIPPETS_OBJECTSTORE_NAME, "readwrite")
+          .objectStore(SNIPPETS_OBJECTSTORE_NAME)
+      );
+      transaction.onsuccess = event => resolve();
+
+      /* istanbul ignore next */
+      transaction.onerror = event => reject(transaction.error);
+    });
+  }
+
+  _openDB() {
+    return new Promise((resolve, reject) => {
+      const openRequest = indexedDB.open(DATABASE_NAME, DATABASE_VERSION);
+
+      /* istanbul ignore next */
+      openRequest.onerror = event => {
+        // Try to delete the old database so that we can start this process over
+        // next time.
+        indexedDB.deleteDatabase(DATABASE_NAME);
+        reject(event);
+      };
+
+      openRequest.onupgradeneeded = event => {
+        const db = event.target.result;
+        if (!db.objectStoreNames.contains(SNIPPETS_OBJECTSTORE_NAME)) {
+          db.createObjectStore(SNIPPETS_OBJECTSTORE_NAME);
+        }
+      };
+
+      openRequest.onsuccess = event => {
+        let db = event.target.result;
+
+        /* istanbul ignore next */
+        db.onerror = err => console.error(err); // eslint-disable-line no-console
+        /* istanbul ignore next */
+        db.onversionchange = versionChangeEvent => versionChangeEvent.target.close();
+
+        resolve(db);
+      };
+    });
+  }
+
+  _restoreFromDb(db) {
+    return new Promise((resolve, reject) => {
+      let cursorRequest;
+      try {
+        cursorRequest = db.transaction(SNIPPETS_OBJECTSTORE_NAME)
+          .objectStore(SNIPPETS_OBJECTSTORE_NAME).openCursor();
+      } catch (err) {
+        // istanbul ignore next
+        reject(err);
+        // istanbul ignore next
+        return;
+      }
+
+      /* istanbul ignore next */
+      cursorRequest.onerror = event => reject(event);
+
+      cursorRequest.onsuccess = event => {
+        let cursor = event.target.result;
+        // Populate the cache from the persistent storage.
+        if (cursor) {
+          if (cursor.value !== "blockList") {
+            this.set(cursor.key, cursor.value);
+          }
+          cursor.continue();
+        } else {
+          // We are done.
+          resolve();
+        }
+      };
+    });
+  }
+}
+
+/**
+ * SnippetsProvider - Initializes a SnippetsMap and loads snippets from a
+ *                    remote location, or else default snippets if the remote
+ *                    snippets cannot be retrieved.
+ */
+export class SnippetsProvider {
+  constructor(dispatch) {
+    // Initialize the Snippets Map and attaches it to a global so that
+    // the snippet payload can interact with it.
+    global.gSnippetsMap = new SnippetsMap(dispatch);
+    this._onAction = this._onAction.bind(this);
+  }
+
+  get snippetsMap() {
+    return global.gSnippetsMap;
+  }
+
+  async _refreshSnippets() {
+    // Check if the cached version of of the snippets in snippetsMap. If it's too
+    // old, blow away the entire snippetsMap.
+    const cachedVersion = this.snippetsMap.get("snippets-cached-version");
+
+    if (cachedVersion !== this.appData.version) {
+      this.snippetsMap.clear();
+    }
+
+    // Has enough time passed for us to require an update?
+    const lastUpdate = this.snippetsMap.get("snippets-last-update");
+    const needsUpdate = !(lastUpdate >= 0) || Date.now() - lastUpdate > SNIPPETS_UPDATE_INTERVAL_MS;
+
+    if (needsUpdate && this.appData.snippetsURL) {
+      this.snippetsMap.set("snippets-last-update", Date.now());
+      try {
+        const response = await fetch(this.appData.snippetsURL);
+        if (response.status === 200) {
+          const payload = await response.text();
+
+          this.snippetsMap.set("snippets", payload);
+          this.snippetsMap.set("snippets-cached-version", this.appData.version);
+        }
+      } catch (e) {
+        console.error(e); // eslint-disable-line no-console
+      }
+    }
+  }
+
+  _noSnippetFallback() {
+    // TODO
+  }
+
+  _forceOnboardingVisibility(shouldBeVisible) {
+    const onboardingEl = document.getElementById("onboarding-notification-bar");
+
+    if (onboardingEl) {
+      onboardingEl.style.display = shouldBeVisible ? "" : "none";
+    }
+  }
+
+  _showRemoteSnippets() {
+    const snippetsEl = document.getElementById(this.elementId);
+    const payload = this.snippetsMap.get("snippets");
+
+    if (!snippetsEl) {
+      throw new Error(`No element was found with id '${this.elementId}'.`);
+    }
+
+    // This could happen if fetching failed
+    if (!payload) {
+      throw new Error("No remote snippets were found in gSnippetsMap.");
+    }
+
+    if (typeof payload !== "string") {
+      throw new Error("Snippet payload was incorrectly formatted");
+    }
+
+    // Note that injecting snippets can throw if they're invalid XML.
+    // eslint-disable-next-line no-unsanitized/property
+    snippetsEl.innerHTML = payload;
+
+    // Scripts injected by innerHTML are inactive, so we have to relocate them
+    // through DOM manipulation to activate their contents.
+    for (const scriptEl of snippetsEl.getElementsByTagName("script")) {
+      const relocatedScript = document.createElement("script");
+      relocatedScript.text = scriptEl.text;
+      scriptEl.parentNode.replaceChild(relocatedScript, scriptEl);
+    }
+  }
+
+  _onAction(msg) {
+    if (msg.data.type === at.SNIPPET_BLOCKED) {
+      if (!this.snippetsMap.blockList.includes(msg.data.data)) {
+        this.snippetsMap.set("blockList", this.snippetsMap.blockList.concat(msg.data.data));
+        document.getElementById("snippets-container").style.display = "none";
+      }
+    }
+  }
+
+  /**
+   * init - Fetch the snippet payload and show snippets
+   *
+   * @param  {obj} options
+   * @param  {str} options.appData.snippetsURL  The URL from which we fetch snippets
+   * @param  {int} options.appData.version  The current snippets version
+   * @param  {str} options.elementId  The id of the element in which to inject snippets
+   * @param  {bool} options.connect  Should gSnippetsMap connect to indexedDB?
+   */
+  async init(options) {
+    Object.assign(this, {
+      appData: {},
+      elementId: "snippets",
+      connect: true
+    }, options);
+
+    // Add listener so we know when snippets are blocked on other pages
+    if (global.addMessageListener) {
+      global.addMessageListener("ActivityStream:MainToContent", this._onAction);
+    }
+
+    // TODO: Requires enabling indexedDB on newtab
+    // Restore the snippets map from indexedDB
+    if (this.connect) {
+      try {
+        await this.snippetsMap.connect();
+      } catch (e) {
+        console.error(e); // eslint-disable-line no-console
+      }
+    }
+
+    // Cache app data values so they can be accessible from gSnippetsMap
+    for (const key of Object.keys(this.appData)) {
+      if (key === "blockList") {
+        this.snippetsMap.set("blockList", this.appData[key]);
+      } else {
+        this.snippetsMap.set(`appData.${key}`, this.appData[key]);
+      }
+    }
+
+    // Refresh snippets, if enough time has passed.
+    await this._refreshSnippets();
+
+    // Try showing remote snippets, falling back to defaults if necessary.
+    try {
+      this._showRemoteSnippets();
+    } catch (e) {
+      this._noSnippetFallback(e);
+    }
+
+    window.dispatchEvent(new Event(SNIPPETS_ENABLED_EVENT));
+
+    this._forceOnboardingVisibility(true);
+    this.initialized = true;
+  }
+
+  uninit() {
+    window.dispatchEvent(new Event(SNIPPETS_DISABLED_EVENT));
+    this._forceOnboardingVisibility(false);
+    if (global.removeMessageListener) {
+      global.removeMessageListener("ActivityStream:MainToContent", this._onAction);
+    }
+    this.initialized = false;
+  }
+}
+
+/**
+ * addSnippetsSubscriber - Creates a SnippetsProvider that Initializes
+ *                         when the store has received the appropriate
+ *                         Snippet data.
+ *
+ * @param  {obj} store   The redux store
+ * @return {obj}         Returns the snippets instance, asrouterContent instance and unsubscribe function
+ */
+export function addSnippetsSubscriber(store) {
+  const snippets = new SnippetsProvider(store.dispatch);
+  const asrouterContent = new ASRouterContent();
+
+  let initializing = false;
+
+  store.subscribe(async () => {
+    const state = store.getState();
+    // state.Prefs.values["feeds.snippets"]:  Should snippets be shown?
+    // state.Snippets.initialized             Is the snippets data initialized?
+    // snippets.initialized:                  Is SnippetsProvider currently initialised?
+    if (state.Prefs.values["feeds.snippets"] &&
+      // If the message center experiment is enabled, don't show snippets
+      !state.Prefs.values.asrouterExperimentEnabled &&
+      !state.Prefs.values.disableSnippets &&
+      state.Snippets.initialized &&
+      !snippets.initialized &&
+      // Don't call init multiple times
+      !initializing &&
+      location.href !== "about:welcome"
+    ) {
+      initializing = true;
+      await snippets.init({appData: state.Snippets});
+      initializing = false;
+    } else if (
+      (state.Prefs.values["feeds.snippets"] === false ||
+        state.Prefs.values.disableSnippets === true) &&
+      snippets.initialized
+    ) {
+      snippets.uninit();
+    }
+
+    // Turn on AS Router snippets if the experiment is enabled and the snippets pref is on;
+    // otherwise, turn it off.
+    if (
+      state.Prefs.values.asrouterExperimentEnabled &&
+      state.Prefs.values["feeds.snippets"] &&
+      !asrouterContent.initialized) {
+      asrouterContent.init();
+    } else if (
+      (!state.Prefs.values.asrouterExperimentEnabled || !state.Prefs.values["feeds.snippets"]) &&
+      asrouterContent.initialized
+    ) {
+      asrouterContent.uninit();
+    }
+  });
+
+  // These values are returned for testing purposes
+  return {snippets, asrouterContent};
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/styles/_activity-stream.scss
@@ -0,0 +1,151 @@
+@import './normalize';
+@import './variables';
+@import './theme';
+@import './icons';
+
+html {
+  height: 100%;
+}
+
+body,
+#root { // sass-lint:disable-line no-ids
+  min-height: 100vh;
+}
+
+body {
+  background-color: var(--newtab-background-color);
+  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Helvetica Neue', sans-serif;
+  font-size: 16px;
+  overflow-y: scroll;
+}
+
+h1,
+h2 {
+  font-weight: normal;
+}
+
+a {
+  text-decoration: none;
+}
+
+// For screen readers
+.sr-only {
+  border: 0;
+  clip: rect(0, 0, 0, 0);
+  height: 1px;
+  margin: -1px;
+  overflow: hidden;
+  padding: 0;
+  position: absolute;
+  width: 1px;
+}
+
+.inner-border {
+  border: $border-secondary;
+  border-radius: $border-radius;
+  height: 100%;
+  left: 0;
+  pointer-events: none;
+  position: absolute;
+  top: 0;
+  width: 100%;
+  z-index: 100;
+}
+
+@keyframes fadeIn {
+  from {
+    opacity: 0;
+  }
+
+  to {
+    opacity: 1;
+  }
+}
+
+.show-on-init {
+  opacity: 0;
+  transition: opacity 0.2s ease-in;
+
+  &.on {
+    animation: fadeIn 0.2s;
+    opacity: 1;
+  }
+}
+
+.actions {
+  border-top: $border-secondary;
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  justify-content: flex-start;
+  margin: 0;
+  padding: 15px 25px 0;
+}
+
+// Default button (grey)
+.button,
+.actions button {
+  background-color: var(--newtab-button-secondary-color);
+  border: $border-primary;
+  border-radius: 4px;
+  color: inherit;
+  cursor: pointer;
+  margin-bottom: 15px;
+  padding: 10px 30px;
+  white-space: nowrap;
+
+  &:hover:not(.dismiss) {
+    box-shadow: $shadow-primary;
+    transition: box-shadow 150ms;
+  }
+
+  &.dismiss {
+    background-color: transparent;
+    border: 0;
+    padding: 0;
+    text-decoration: underline;
+  }
+
+  // Blue button
+  &.primary,
+  &.done {
+    background-color: var(--newtab-button-primary-color);
+    border: solid 1px var(--newtab-button-primary-color);
+    color: $white;
+    margin-inline-start: auto;
+  }
+}
+
+input {
+  &[type='text'],
+  &[type='search'] {
+    border-radius: $border-radius;
+  }
+}
+
+// Make sure snippets show up above other UI elements
+#snippets-container { // sass-lint:disable-line no-ids
+  z-index: 1;
+}
+
+// Components
+@import '../components/Base/Base';
+@import '../components/ErrorBoundary/ErrorBoundary';
+@import '../components/TopSites/TopSites';
+@import '../components/Sections/Sections';
+@import '../components/StartupOverlay/StartupOverlay';
+@import '../components/Topics/Topics';
+@import '../components/Search/Search';
+@import '../components/ContextMenu/ContextMenu';
+@import '../components/ConfirmDialog/ConfirmDialog';
+@import '../components/Card/Card';
+@import '../components/ManualMigration/ManualMigration';
+@import '../components/CollapsibleSection/CollapsibleSection';
+@import '../components/ASRouterAdmin/ASRouterAdmin';
+
+// AS Router
+@import '../asrouter/components/Button/Button';
+@import '../asrouter/components/SnippetBase/SnippetBase';
+@import '../asrouter/components/ModalOverlay/ModalOverlay';
+@import '../asrouter/templates/SimpleSnippet/SimpleSnippet';
+@import '../asrouter/templates/OnboardingMessage/OnboardingMessage';
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/styles/_icons.scss
@@ -0,0 +1,180 @@
+.icon {
+  background-position: center center;
+  background-repeat: no-repeat;
+  background-size: $icon-size;
+  -moz-context-properties: fill;
+  display: inline-block;
+  fill: var(--newtab-icon-primary-color);
+  height: $icon-size;
+  vertical-align: middle;
+  width: $icon-size;
+
+  &.icon-spacer {
+    margin-inline-end: 8px;
+  }
+
+  &.icon-small-spacer {
+    margin-inline-end: 6px;
+  }
+
+  &.icon-bookmark-added {
+    background-image: url('chrome://browser/skin/bookmark.svg');
+  }
+
+  &.icon-bookmark-hollow {
+    background-image: url('chrome://browser/skin/bookmark-hollow.svg');
+  }
+
+  &.icon-clear-input {
+    fill: var(--newtab-icon-secondary-color);
+    background-image: url('#{$image-path}glyph-cancel-16.svg');
+  }
+
+  &.icon-delete {
+    background-image: url('#{$image-path}glyph-delete-16.svg');
+  }
+
+  &.icon-search {
+    background-image: url('chrome://browser/skin/search-glass.svg');
+  }
+
+  &.icon-modal-delete {
+    flex-shrink: 0;
+    background-image: url('#{$image-path}glyph-modal-delete-32.svg');
+    background-size: $larger-icon-size;
+    height: $larger-icon-size;
+    width: $larger-icon-size;
+  }
+
+  &.icon-dismiss {
+    background-image: url('#{$image-path}glyph-dismiss-16.svg');
+  }
+
+  &.icon-info {
+    background-image: url('#{$image-path}glyph-info-16.svg');
+  }
+
+  &.icon-import {
+    background-image: url('#{$image-path}glyph-import-16.svg');
+  }
+
+  &.icon-new-window {
+    @include flip-icon;
+    background-image: url('#{$image-path}glyph-newWindow-16.svg');
+  }
+
+  &.icon-new-window-private {
+    background-image: url('chrome://browser/skin/privateBrowsing.svg');
+  }
+
+  &.icon-settings {
+    background-image: url('chrome://browser/skin/settings.svg');
+  }
+
+  &.icon-pin {
+    @include flip-icon;
+    background-image: url('#{$image-path}glyph-pin-16.svg');
+  }
+
+  &.icon-unpin {
+    @include flip-icon;
+    background-image: url('#{$image-path}glyph-unpin-16.svg');
+  }
+
+  &.icon-edit {
+    background-image: url('#{$image-path}glyph-edit-16.svg');
+  }
+
+  &.icon-pocket {
+    background-image: url('#{$image-path}glyph-pocket-16.svg');
+  }
+
+  &.icon-history-item {
+    background-image: url('chrome://browser/skin/history.svg');
+  }
+
+  &.icon-trending {
+    background-image: url('#{$image-path}glyph-trending-16.svg');
+    transform: translateY(2px); // trending bolt is visually top heavy
+  }
+
+  &.icon-now {
+    background-image: url('chrome://browser/skin/history.svg');
+  }
+
+  &.icon-topsites {
+    background-image: url('#{$image-path}glyph-topsites-16.svg');
+  }
+
+  &.icon-pin-small {
+    @include flip-icon;
+    background-image: url('#{$image-path}glyph-pin-12.svg');
+    background-size: $smaller-icon-size;
+    height: $smaller-icon-size;
+    width: $smaller-icon-size;
+  }
+
+  &.icon-check {
+    background-image: url('chrome://browser/skin/check.svg');
+  }
+
+  &.icon-download {
+    background-image: url('chrome://browser/skin/downloads/download-icons.svg#arrow-with-bar');
+  }
+
+  &.icon-copy {
+    background-image: url('chrome://browser/skin/edit-copy.svg');
+  }
+
+  &.icon-open-file {
+    background-image: url('#{$image-path}glyph-open-file-16.svg');
+  }
+
+  &.icon-webextension {
+    background-image: url('#{$image-path}glyph-webextension-16.svg');
+  }
+
+  &.icon-highlights {
+    background-image: url('#{$image-path}glyph-highlights-16.svg');
+  }
+
+  &.icon-arrowhead-down {
+    background-image: url('#{$image-path}glyph-arrowhead-down-16.svg');
+  }
+
+  &.icon-arrowhead-down-small {
+    background-image: url('#{$image-path}glyph-arrowhead-down-12.svg');
+    background-size: $smaller-icon-size;
+    height: $smaller-icon-size;
+    width: $smaller-icon-size;
+  }
+
+  &.icon-arrowhead-forward-small {
+    background-image: url('#{$image-path}glyph-arrowhead-down-12.svg');
+    background-size: $smaller-icon-size;
+    height: $smaller-icon-size;
+    transform: rotate(-90deg);
+    width: $smaller-icon-size;
+
+    &:dir(rtl) {
+      transform: rotate(90deg);
+    }
+  }
+
+  &.icon-arrowhead-up {
+    background-image: url('#{$image-path}glyph-arrowhead-down-16.svg');
+    transform: rotate(180deg);
+  }
+
+  &.icon-add {
+    background-image: url('#{$image-path}glyph-add-16.svg');
+  }
+
+  &.icon-minimize {
+    background-image: url('#{$image-path}glyph-minimize-16.svg');
+  }
+
+  &.icon-maximize {
+    background-image: url('#{$image-path}glyph-maximize-16.svg');
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/styles/_normalize.scss
@@ -0,0 +1,29 @@
+html {
+  box-sizing: border-box;
+}
+
+*,
+*::before,
+*::after {
+  box-sizing: inherit;
+}
+
+*::-moz-focus-inner {
+  border: 0;
+}
+
+body {
+  margin: 0;
+}
+
+button,
+input {
+  background-color: inherit;
+  color: inherit;
+  font-family: inherit;
+  font-size: inherit;
+}
+
+[hidden] {
+  display: none !important; // sass-lint:disable-line no-important
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/styles/_theme.scss
@@ -0,0 +1,135 @@
+@function textbox-shadow($color) {
+  @return 0 0 0 1px $color, 0 0 0 $textbox-shadow-size rgba($color, 0.3);
+}
+
+@mixin textbox-focus($color) {
+  --newtab-textbox-focus-color: $color;
+  --newtab-textbox-focus-boxshadow: textbox-shadow($color);
+}
+
+// scss variables related to the theme.
+$border-primary: 1px solid var(--newtab-border-primary-color);
+$border-secondary: 1px solid var(--newtab-border-secondary-color);
+$inner-box-shadow: 0 0 0 1px var(--newtab-inner-box-shadow-color);
+$input-border: 1px solid var(--newtab-textbox-border);
+$input-border-active: 1px solid var(--newtab-textbox-focus-color);
+$input-error-border: 1px solid $red-60;
+$input-error-boxshadow: textbox-shadow($red-60);
+$shadow-primary: 0 0 0 5px var(--newtab-card-active-outline-color);
+$shadow-secondary: 0 1px 4px 0 $grey-90-20;
+
+// Default theme
+body {
+  // General styles
+  --newtab-background-color: $grey-10;
+  --newtab-border-primary-color: $grey-40;
+  --newtab-border-secondary-color: $grey-30;
+  --newtab-button-primary-color: $blue-60;
+  --newtab-button-secondary-color: inherit;
+  --newtab-element-active-color: $grey-30-60;
+  --newtab-element-hover-color: $grey-20;
+  --newtab-icon-primary-color: $grey-90-80;
+  --newtab-icon-secondary-color: $grey-90-60;
+  --newtab-icon-tertiary-color: $grey-30;
+  --newtab-inner-box-shadow-color: $black-10;
+  --newtab-link-primary-color: $blue-60;
+  --newtab-link-secondary-color: $teal-70;
+  --newtab-text-conditional-color: $grey-60;
+  --newtab-text-primary-color: $grey-90;
+  --newtab-text-secondary-color: $grey-50;
+  --newtab-textbox-background-color: $white;
+  --newtab-textbox-border: $grey-90-20;
+  @include textbox-focus($blue-60); // sass-lint:disable-line mixins-before-declarations
+
+  // Context menu
+  --newtab-contextmenu-background-color: $grey-10;
+  --newtab-contextmenu-button-color: $white;
+
+  // Modal + overlay
+  --newtab-modal-color: $white;
+  --newtab-overlay-color: $grey-20-80;
+
+  // Sections
+  --newtab-section-header-text-color: $grey-50;
+  --newtab-section-navigation-text-color: $grey-50;
+  --newtab-section-active-contextmenu-color: $grey-90;
+
+  // Search
+  --newtab-search-border-color: transparent;
+  --newtab-search-dropdown-color: $white;
+  --newtab-search-dropdown-header-color: $grey-10;
+  --newtab-search-icon-color: $grey-90-40;
+
+  // Top Sites
+  --newtab-topsites-background-color: $white;
+  --newtab-topsites-icon-shadow: inset $inner-box-shadow;
+  --newtab-topsites-label-color: inherit;
+
+  // Cards
+  --newtab-card-active-outline-color: $grey-30;
+  --newtab-card-background-color: $white;
+  --newtab-card-hairline-color: $black-10;
+  --newtab-card-shadow: 0 1px 4px 0 $grey-90-10;
+
+  // Snippets
+  --newtab-snippets-background-color: $white;
+  --newtab-snippets-hairline-color: transparent;
+}
+
+// Dark theme
+.dark-theme {
+  // General styles
+  --newtab-background-color: $grey-80;
+  --newtab-border-primary-color: $grey-10-80;
+  --newtab-border-secondary-color: $grey-10-10;
+  --newtab-button-primary-color: $blue-60;
+  --newtab-button-secondary-color: $grey-70;
+  --newtab-element-active-color: $grey-10-20;
+  --newtab-element-hover-color: $grey-10-10;
+  --newtab-icon-primary-color: $grey-10-80;
+  --newtab-icon-secondary-color: $grey-10-40;
+  --newtab-icon-tertiary-color: $grey-10-40;
+  --newtab-inner-box-shadow-color: $grey-10-20;
+  --newtab-link-primary-color: $blue-40;
+  --newtab-link-secondary-color: $pocket-teal;
+  --newtab-text-conditional-color: $grey-10;
+  --newtab-text-primary-color: $grey-10;
+  --newtab-text-secondary-color: $grey-10-80;
+  --newtab-textbox-background-color: $grey-70;
+  --newtab-textbox-border: $grey-10-20;
+  @include textbox-focus($blue-40); // sass-lint:disable-line mixins-before-declarations
+
+  // Context menu
+  --newtab-contextmenu-background-color: $grey-60;
+  --newtab-contextmenu-button-color: $grey-80;
+
+  // Modal + overlay
+  --newtab-modal-color: $grey-80;
+  --newtab-overlay-color: $grey-90-80;
+
+  // Sections
+  --newtab-section-header-text-color: $grey-10-80;
+  --newtab-section-navigation-text-color: $grey-10-80;
+  --newtab-section-active-contextmenu-color: $white;
+
+  // Search
+  --newtab-search-border-color: $grey-10-20;
+  --newtab-search-dropdown-color: $grey-70;
+  --newtab-search-dropdown-header-color: $grey-60;
+  --newtab-search-icon-color: $grey-10-60;
+
+  // Top Sites
+  --newtab-topsites-background-color: $grey-70;
+  --newtab-topsites-icon-shadow: none;
+  --newtab-topsites-label-color: $grey-10-80;
+
+  // Cards
+  --newtab-card-active-outline-color: $grey-60;
+  --newtab-card-background-color: $grey-70;
+  --newtab-card-hairline-color: $grey-10-10;
+  --newtab-card-shadow: 0 1px 8px 0 $grey-90-20;
+
+  // Snippets
+  --newtab-snippets-background-color: $grey-70;
+  --newtab-snippets-hairline-color: $white-10;
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/styles/_variables.scss
@@ -0,0 +1,187 @@
+// Photon colors from http://design.firefox.com/photon/visuals/color.html
+$blue-40: #45A1FF;
+$blue-50: #0A84FF;
+$blue-60: #0060DF;
+$blue-70: #003EAA;
+$blue-80: #002275;
+$grey-10: #F9F9FA;
+$grey-20: #EDEDF0;
+$grey-30: #D7D7DB;
+$grey-40: #B1B1B3;
+$grey-50: #737373;
+$grey-60: #4A4A4F;
+$grey-70: #38383D;
+$grey-80: #2A2A2E;
+$grey-90: #0C0C0D;
+$teal-70: #008EA4;
+$red-60: #D70022;
+$yellow-50: #FFE900;
+
+// Photon opacity from http://design.firefox.com/photon/visuals/color.html#opacity
+$grey-10-10: rgba($grey-10, 0.1);
+$grey-10-20: rgba($grey-10, 0.2);
+$grey-10-40: rgba($grey-10, 0.4);
+$grey-10-60: rgba($grey-10, 0.6);
+$grey-10-80: rgba($grey-10, 0.8);
+$grey-20-60: rgba($grey-20, 0.6);
+$grey-20-80: rgba($grey-20, 0.8);
+$grey-30-60: rgba($grey-30, 0.6);
+$grey-90-10: rgba($grey-90, 0.1);
+$grey-90-20: rgba($grey-90, 0.2);
+$grey-90-30: rgba($grey-90, 0.3);
+$grey-90-40: rgba($grey-90, 0.4);
+$grey-90-50: rgba($grey-90, 0.5);
+$grey-90-60: rgba($grey-90, 0.6);
+$grey-90-70: rgba($grey-90, 0.7);
+$grey-90-80: rgba($grey-90, 0.8);
+$grey-90-90: rgba($grey-90, 0.9);
+
+$black: #000;
+$black-5: rgba($black, 0.05);
+$black-10: rgba($black, 0.1);
+$black-15: rgba($black, 0.15);
+$black-20: rgba($black, 0.2);
+$black-25: rgba($black, 0.25);
+$black-30: rgba($black, 0.3);
+
+// Other colors
+$white: #FFF;
+$white-10: rgba($white, 0.1);
+$pocket-teal: #50BCB6;
+$bookmark-icon-fill: #0A84FF;
+$download-icon-fill: #12BC00;
+$history-icon-fill: #B1B1B3;
+$pocket-icon-fill: #D70022;
+
+// Photon transitions from http://design.firefox.com/photon/motion/duration-and-easing.html
+$photon-easing: cubic-bezier(0.07, 0.95, 0, 1);
+
+$border-radius: 3px;
+
+// Grid related styles
+$base-gutter: 32px;
+$section-horizontal-padding: 25px;
+$section-vertical-padding: 10px;
+$section-spacing: 40px - $section-vertical-padding * 2;
+$grid-unit: 96px; // 1 top site
+
+$icon-size: 16px;
+$smaller-icon-size: 12px;
+$larger-icon-size: 32px;
+
+$wrapper-default-width: $grid-unit * 2 + $base-gutter * 1 + $section-horizontal-padding * 2; // 2 top sites
+$wrapper-max-width-small: $grid-unit * 3 + $base-gutter * 2 + $section-horizontal-padding * 2; // 3 top sites
+$wrapper-max-width-medium: $grid-unit * 4 + $base-gutter * 3 + $section-horizontal-padding * 2; // 4 top sites
+$wrapper-max-width-large: $grid-unit * 6 + $base-gutter * 5 + $section-horizontal-padding * 2; // 6 top sites
+$wrapper-max-width-widest: $grid-unit * 8 + $base-gutter * 7 + $section-horizontal-padding * 2; // 8 top sites
+// For the breakpoints, we need to add space for the scrollbar to avoid weird
+// layout issues when the scrollbar is visible. 16px is wide enough to cover all
+// OSes and keeps it simpler than a per-OS value.
+$scrollbar-width: 16px;
+$break-point-small: $wrapper-max-width-small + $base-gutter * 2 + $scrollbar-width;
+$break-point-medium: $wrapper-max-width-medium + $base-gutter * 2 + $scrollbar-width;
+$break-point-large: $wrapper-max-width-large + $base-gutter * 2 + $scrollbar-width;
+$break-point-widest: $wrapper-max-width-widest + $base-gutter * 2 + $scrollbar-width;
+
+$section-title-font-size: 13px;
+
+$card-width: $grid-unit * 2 + $base-gutter;
+$card-height: 266px;
+$card-preview-image-height: 122px;
+$card-title-margin: 2px;
+$card-text-line-height: 19px;
+// Larger cards for wider screens:
+$card-width-large: 309px;
+$card-height-large: 370px;
+$card-preview-image-height-large: 155px;
+// Compact cards for Highlights
+$card-height-compact: 160px;
+$card-preview-image-height-compact: 108px;
+
+$topic-margin-top: 12px;
+
+$context-menu-button-size: 27px;
+$context-menu-button-boxshadow: 0 2px $grey-90-10;
+$context-menu-shadow: 0 5px 10px $black-30, 0 0 0 1px $black-20;
+$context-menu-font-size: 14px;
+$context-menu-border-radius: 5px;
+$context-menu-outer-padding: 5px;
+$context-menu-item-padding: 3px 12px;
+
+$error-fallback-font-size: 12px;
+$error-fallback-line-height: 1.5;
+
+$image-path: '../data/content/assets/';
+
+$snippets-container-height: 120px;
+
+$textbox-shadow-size: 4px;
+
+@mixin fade-in {
+  box-shadow: inset $inner-box-shadow, $shadow-primary;
+  transition: box-shadow 150ms;
+}
+
+@mixin fade-in-card {
+  box-shadow: $shadow-primary;
+  transition: box-shadow 150ms;
+}
+
+@mixin context-menu-button {
+  .context-menu-button {
+    background-clip: padding-box;
+    background-color: var(--newtab-contextmenu-button-color);
+    background-image: url('chrome://browser/skin/page-action.svg');
+    background-position: 55%;
+    border: $border-primary;
+    border-radius: 100%;
+    box-shadow: $context-menu-button-boxshadow;
+    cursor: pointer;
+    fill: var(--newtab-icon-primary-color);
+    height: $context-menu-button-size;
+    offset-inline-end: -($context-menu-button-size / 2);
+    opacity: 0;
+    position: absolute;
+    top: -($context-menu-button-size / 2);
+    transform: scale(0.25);
+    transition-duration: 200ms;
+    transition-property: transform, opacity;
+    width: $context-menu-button-size;
+
+    &:-moz-any(:active, :focus) {
+      opacity: 1;
+      transform: scale(1);
+    }
+  }
+}
+
+@mixin context-menu-button-hover {
+  .context-menu-button {
+    opacity: 1;
+    transform: scale(1);
+  }
+}
+
+@mixin context-menu-open-middle {
+  .context-menu {
+    margin-inline-end: auto;
+    margin-inline-start: auto;
+    offset-inline-end: auto;
+    offset-inline-start: -$base-gutter;
+  }
+}
+
+@mixin context-menu-open-left {
+  .context-menu {
+    margin-inline-end: 5px;
+    margin-inline-start: auto;
+    offset-inline-end: 0;
+    offset-inline-start: auto;
+  }
+}
+
+@mixin flip-icon {
+  &:dir(rtl) {
+    transform: scaleX(-1);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/styles/activity-stream-linux.scss
@@ -0,0 +1,7 @@
+/* This is the linux variant */ // sass-lint:disable-line no-css-comments
+
+$os-infopanel-arrow-height: 10px;
+$os-infopanel-arrow-offset-end: 6px;
+$os-infopanel-arrow-width: 20px;
+
+@import './activity-stream';
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/styles/activity-stream-mac.scss
@@ -0,0 +1,11 @@
+/* This is the mac variant */ // sass-lint:disable-line no-css-comments
+
+$os-infopanel-arrow-height: 10px;
+$os-infopanel-arrow-offset-end: 7px;
+$os-infopanel-arrow-width: 18px;
+
+.dark-theme {
+  -moz-osx-font-smoothing: grayscale;
+}
+
+@import './activity-stream';
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/content-src/styles/activity-stream-windows.scss
@@ -0,0 +1,7 @@
+/* This is the windows variant */ // sass-lint:disable-line no-css-comments
+
+$os-infopanel-arrow-height: 10px;
+$os-infopanel-arrow-offset-end: 6px;
+$os-infopanel-arrow-width: 20px;
+
+@import './activity-stream';
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/contributing.md
@@ -0,0 +1,138 @@
+# Contributing to Activity Stream
+
+Activity Stream is an enhancement to the functionality of Firefox's about:newtab page.  We welcome new 'streamers' to contribute to the project!
+
+## Where to ask questions
+
+- Most of the core dev team can be found on the `#activity-stream` channel on `irc.mozilla.org`.
+  You can also direct message the core team (`dmose`, `emtwo`, `jkerim`, `k88hudson`, `Mardak`, `nanj`, `r1cky`, `ursula`, `andreio`)
+  or our manager (`tspurway`)
+- Slack channel (staff only): #activitystream
+- Mailing List: [activity-stream-dev](https://groups.google.com/a/mozilla.com/d/forum/activity-stream-dev)
+- File issues/questions on Github: https://github.com/mozilla/activity-stream/issues. We typically triage new issues every Monday.
+
+## Architecture ##
+
+Activity Stream is a Firefox system add-on. One of the cool things about Activity Stream is that the
+[content side of the add-on](https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts)
+is written using [ReactJS](https://facebook.github.io/react/).  This makes it an awesome project for React hackers to contribute to!
+
+## Finding Bugs, Filing Tickets, Earning Karma ##
+
+Activity Stream lives on [GitHub](https://github.com/mozilla/activity-stream), but you already knew that!  If you've found
+a bug, or have a feature idea that you you'd like to see in Activity Stream, follow these simple guidelines:
+- Pick a thoughtful and terse title for the issue (ie. *not* Thing Doesn't Work!)
+- Make sure to mention your Firefox version, OS and basic system parameters (eg. Firefox 49.0, Windows XP, 512KB RAM)
+- If you can reproduce the bug, give a step-by-step recipe
+- Include [stack traces from the console(s)](https://developer.mozilla.org/en-US/docs/Mozilla/Debugging/Debugging_JavaScript) where appropriate
+- Screenshots welcome!
+- When in doubt, take a look at some [existing issues](https://github.com/mozilla/activity-stream/issues) and emulate
+
+## Take a Ticket, Hack some Code ##
+
+If you are new to the repo, you might want to pay close attention to [`Good first bug`](https://github.com/mozilla/activity-stream/issues?q=is%3Aopen+is%3Aissue+label%3A%22Good+first+bug%22),
+ [`Bug`](https://github.com/mozilla/activity-stream/issues?q=is%3Aopen%20is%3Aissue%20label%3ABug%20),
+ [`Chore`](https://github.com/mozilla/activity-stream/issues?q=is%3Aopen+is%3Aissue+label%3AChore) and
+ [`Polish`](https://github.com/mozilla/activity-stream/issues?q=is%3Aopen+is%3Aissue+label%3APolish) tags, as these are
+typically a great way to get started.  You might see a bug that is not yet assigned to anyone, or start a conversation with
+an engineer in the ticket itself, expressing your interest in taking the bug.  If you take the bug, someone will set
+the ticket to [`Assigned to Contributor`](https://github.com/mozilla/activity-stream/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22Assigned%20to%20contributor%22%20), which is a way we can be pro-active about helping you succeed in fixing the bug.
+
+When you have some code written, you can open up a [Pull Request](#pull-requests), get your code [reviewed](#code-reviews), and see your code merged into the Activity Stream codebase.
+
+If you are thinking about contributing on a longer-term basis, check out the section on [milestones](#milestones) and [priorities](#priorities)
+to get a sense of how we plan and prioritize work.
+
+## Setting up your development environment
+
+Check out [this guide](docs/v2-system-addon/1.GETTING_STARTED.md) on how to install dependencies, get set up, and run tests.
+
+## Pull Requests ##
+
+You have identified the bug, written code and now want to get it into the main repo using a [Pull Request](https://help.github.com/articles/about-pull-requests/).
+
+All code is added using a pull request against the `master` branch of our repo.  Before submitting a PR, please go through this checklist:
+- all [unit tests](#unit-tests) must pass
+- if you haven't written unit tests for your patch, eyebrows will be curmudgeonly furrowed (write unit tests!)
+- if your pull request fixes a particular ticket (it does, right?), please use the `fixes #nnn` github annotation to indicate this
+- please add a `PR / Needs review` tag to your PR (if you have permission).  This starts the code review process.  If you cannot add a tag, don't worry, we will add it during triage.
+- if you can pick a module owner to be your reviewer by including `r? @username` in the comment (if not, don't worry, we will assign a reviewer)
+- make sure your PR will merge gracefully with `master` at the time you create the PR, and that your commit history is 'clean'
+
+## Code Reviews ##
+
+You have created a PR and submitted it to the repo, and now are waiting patiently for you code review feedback.  One of the projects
+module owners will be along and will either:
+- make suggestions for some improvements
+- give you an `R+` in the comments section, indicating the review is done and the code can be merged
+
+Typically, you will iterate on the PR, making changes and pushing your changes to new commits on the PR.  When the reviewer is
+ satisfied that your code is good-to-go, you will get the coveted `R+` comment, and your code can be merged.  If you have
+ commit permission, you can go ahead and merge the code to `master`, otherwise, it will be done for you.
+
+Our project prides itself on it's respectful, patient and positive attitude when it comes to reviewing contributor's code, and as such,
+we expect contributors to be respectful, patient and positive in their communications as well.  Let's be friends and learn
+from each other for a free and awesome web!
+
+[Mozilla Committing Rules and Responsibilities](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Committing_Rules_and_Responsibilities)
+
+## Git Commit Guidelines ##
+
+We loosely follow the [Angular commit guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#type) of `<type>(<scope>): <subject>` where `type` must be one of:
+
+* **feat**: A new feature
+* **fix**: A bug fix
+* **docs**: Documentation only changes
+* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
+  semi-colons, etc)
+* **refactor**: A code change that neither fixes a bug or adds a feature
+* **perf**: A code change that improves performance
+* **test**: Adding missing tests
+* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
+  generation
+
+### Scope
+The scope could be anything specifying place of the commit change. For example `timeline`,
+`metadata`, `reporting`, `experiments` etc...
+
+### Subject
+The subject contains succinct description of the change:
+
+* use the imperative, present tense: "change" not "changed" nor "changes"
+* don't capitalize first letter
+* no dot (.) at the end
+
+### Body
+In order to maintain a reference to the context of the commit, add
+`fixes #<issue_number>` if it closes a related issue or `issue #<issue_number>`
+if it's a partial fix.
+
+You can also write a detailed description of the commit:
+Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes"
+It should include the motivation for the change and contrast this with previous behavior.
+
+###Footer
+The footer should contain any information about **Breaking Changes** and is also the place to
+reference GitHub issues that this commit **Closes**.
+
+## Milestones ##
+
+All work on Activity Stream is broken into two week iterations, which we map into a GitHub [Milestone](https://github.com/mozilla/activity-stream/milestones).  At the beginning of the iteration, we prioritize and estimate tickets
+into the milestone, attempting to figure out how much progress we can make during the iteration.  
+
+## Priorities ##
+
+All tickets that have been [triaged](#triage) will have a priority tag of either `P1`, `P2`, `P3`, or `P4` which are highest to lowest
+priorities of tickets in Activity Stream. We love ticket tags and you might also see `Blocked`, `Critical` or `Chemspill` tags, which
+indicate our level of anxiety about that particular ticket.  
+
+## Triage ##
+
+The project team meets weekly (in a closed meeting, for the time being), to discuss project priorities, to triage new tickets, and to
+redistribute the work amongst team members.  Any contributors tickets or PRs are carefully considered, prioritized, and if needed,
+assigned a reviewer.  The project's GitHub [Milestone page](https://github.com/mozilla/activity-stream/milestones) is the best
+place to look for up-to-date information on project priorities and current workload.
+
+## License
+
+MPL 2.0
--- a/browser/extensions/activity-stream/data/content/activity-stream.bundle.js
+++ b/browser/extensions/activity-stream/data/content/activity-stream.bundle.js
@@ -441,20 +441,20 @@ const MIN_CORNER_FAVICON_SIZE = 16;
 
 
 /***/ }),
 /* 6 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 
-// EXTERNAL MODULE: ./system-addon/common/Actions.jsm
+// EXTERNAL MODULE: ./common/Actions.jsm
 var Actions = __webpack_require__(1);
 
-// CONCATENATED MODULE: ./system-addon/common/Dedupe.jsm
+// CONCATENATED MODULE: ./common/Dedupe.jsm
 class Dedupe {
   constructor(createKey) {
     this.createKey = createKey || this.defaultCreateKey;
   }
 
   defaultCreateKey(item) {
     return item;
   }
@@ -477,17 +477,17 @@ class Dedupe {
         }
       }
       result.push(valueMap);
       valueMap.forEach((value, key) => globalKeys.add(key));
     }
     return result.map(m => Array.from(m.values()));
   }
 }
-// CONCATENATED MODULE: ./system-addon/common/Reducers.jsm
+// CONCATENATED MODULE: ./common/Reducers.jsm
 /* unused harmony export insertPinned */
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return reducers; });
 /* 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/. */
 
 
 
@@ -3418,17 +3418,17 @@ ImpressionsWrapper.defaultProps = {
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 
 // EXTERNAL MODULE: external "React"
 var external__React_ = __webpack_require__(0);
 var external__React__default = /*#__PURE__*/__webpack_require__.n(external__React_);
 
-// CONCATENATED MODULE: ./system-addon/content-src/asrouter/components/ModalOverlay/ModalOverlay.jsx
+// CONCATENATED MODULE: ./content-src/asrouter/components/ModalOverlay/ModalOverlay.jsx
 
 
 class ModalOverlay_ModalOverlay extends external__React__default.a.PureComponent {
   componentWillMount() {
     this.setState({ active: true });
     document.body.classList.add("modal-open");
   }
 
@@ -3465,17 +3465,17 @@ class ModalOverlay_ModalOverlay extends 
             button_label,
             " "
           )
         )
       )
     );
   }
 }
-// CONCATENATED MODULE: ./system-addon/content-src/asrouter/templates/OnboardingMessage/OnboardingMessage.jsx
+// CONCATENATED MODULE: ./content-src/asrouter/templates/OnboardingMessage/OnboardingMessage.jsx
 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; };
 
 
 
 
 class OnboardingMessage_OnboardingCard extends external__React__default.a.PureComponent {
   constructor(props) {
     super(props);
@@ -3557,29 +3557,29 @@ class OnboardingMessage_OnboardingMessag
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 
 // EXTERNAL MODULE: external "React"
 var external__React_ = __webpack_require__(0);
 var external__React__default = /*#__PURE__*/__webpack_require__.n(external__React_);
 
-// CONCATENATED MODULE: ./system-addon/content-src/asrouter/template-utils.js
+// CONCATENATED MODULE: ./content-src/asrouter/template-utils.js
 function safeURI(url) {
   if (!url) {
     return "";
   }
   const { protocol } = new URL(url);
   const isAllowed = ["http:", "https:", "data:", "resource:", "chrome:"].includes(protocol);
   if (!isAllowed) {
     console.warn(`The protocol ${protocol} is not allowed for template URLs.`); // eslint-disable-line no-console
   }
   return isAllowed ? url : "";
 }
-// CONCATENATED MODULE: ./system-addon/content-src/asrouter/components/Button/Button.jsx
+// CONCATENATED MODULE: ./content-src/asrouter/components/Button/Button.jsx
 
 
 
 const ALLOWED_STYLE_TAGS = ["color", "backgroundColor"];
 
 const Button = props => {
   const style = {};
 
@@ -3598,17 +3598,17 @@ const Button = props => {
     "a",
     { href: safeURI(props.url),
       onClick: props.onClick,
       className: props.className || "ASRouterButton",
       style: style },
     props.children
   );
 };
-// CONCATENATED MODULE: ./system-addon/content-src/asrouter/components/SnippetBase/SnippetBase.jsx
+// CONCATENATED MODULE: ./content-src/asrouter/components/SnippetBase/SnippetBase.jsx
 
 
 class SnippetBase_SnippetBase extends external__React__default.a.PureComponent {
   constructor(props) {
     super(props);
     this.onBlockClicked = this.onBlockClicked.bind(this);
   }
 
@@ -3629,17 +3629,17 @@ class SnippetBase_SnippetBase extends ex
         "div",
         { className: "innerWrapper" },
         props.children
       ),
       external__React__default.a.createElement("button", { className: "blockButton", onClick: this.onBlockClicked })
     );
   }
 }
-// CONCATENATED MODULE: ./system-addon/content-src/asrouter/templates/SimpleSnippet/SimpleSnippet.jsx
+// CONCATENATED MODULE: ./content-src/asrouter/templates/SimpleSnippet/SimpleSnippet.jsx
 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; };
 
 
 
 
 
 
 const DEFAULT_ICON_PATH = "chrome://branding/content/icon64.png";
@@ -5494,31 +5494,31 @@ const TopSites = Object(__WEBPACK_IMPORT
 /* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(3)))
 
 /***/ }),
 /* 38 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 
-// EXTERNAL MODULE: ./system-addon/common/Actions.jsm
+// EXTERNAL MODULE: ./common/Actions.jsm
 var Actions = __webpack_require__(1);
 
 // EXTERNAL MODULE: external "ReactIntl"
 var external__ReactIntl_ = __webpack_require__(2);
 var external__ReactIntl__default = /*#__PURE__*/__webpack_require__.n(external__ReactIntl_);
 
 // EXTERNAL MODULE: external "React"
 var external__React_ = __webpack_require__(0);
 var external__React__default = /*#__PURE__*/__webpack_require__.n(external__React_);
 
-// EXTERNAL MODULE: ./system-addon/content-src/components/TopSites/TopSitesConstants.js
+// EXTERNAL MODULE: ./content-src/components/TopSites/TopSitesConstants.js
 var TopSitesConstants = __webpack_require__(5);
 
-// CONCATENATED MODULE: ./system-addon/content-src/components/TopSites/TopSiteFormInput.jsx
+// CONCATENATED MODULE: ./content-src/components/TopSites/TopSiteFormInput.jsx
 
 
 
 class TopSiteFormInput_TopSiteFormInput extends external__React__default.a.PureComponent {
   constructor(props) {
     super(props);
     this.state = { validationError: this.props.validationError };
     this.onChange = this.onChange.bind(this);
@@ -5583,20 +5583,20 @@ class TopSiteFormInput_TopSiteFormInput 
   }
 }
 
 TopSiteFormInput_TopSiteFormInput.defaultProps = {
   showClearButton: false,
   value: "",
   validationError: false
 };
-// EXTERNAL MODULE: ./system-addon/content-src/components/TopSites/TopSite.jsx
+// EXTERNAL MODULE: ./content-src/components/TopSites/TopSite.jsx
 var TopSite = __webpack_require__(18);
 
-// CONCATENATED MODULE: ./system-addon/content-src/components/TopSites/TopSiteForm.jsx
+// CONCATENATED MODULE: ./content-src/components/TopSites/TopSiteForm.jsx
 
 
 
 
 
 
 
 class TopSiteForm_TopSiteForm extends external__React__default.a.PureComponent {
--- a/browser/extensions/activity-stream/data/content/activity-stream.bundle.js.map
+++ b/browser/extensions/activity-stream/data/content/activity-stream.bundle.js.map
@@ -1,1 +1,1 @@
-{"version":3,"sources":["webpack:///webpack/bootstrap f7d8f61f69ada03ad1f6","webpack:///external \"React\"","webpack:///./system-addon/common/Actions.jsm","webpack:///external \"ReactIntl\"","webpack:///(webpack)/buildin/global.js","webpack:///external \"ReactRedux\"","webpack:///./system-addon/content-src/components/TopSites/TopSitesConstants.js","webpack:///./system-addon/common/Dedupe.jsm","webpack:///./system-addon/common/Reducers.jsm","webpack:///./system-addon/content-src/asrouter/asrouter-content.jsx","webpack:///./system-addon/content-src/lib/init-store.js","webpack:///external \"ReactDOM\"","webpack:///./system-addon/content-src/components/ErrorBoundary/ErrorBoundary.jsx","webpack:///./system-addon/content-src/lib/link-menu-options.js","webpack:///./system-addon/content-src/components/LinkMenu/LinkMenu.jsx","webpack:///./system-addon/content-src/components/ContextMenu/ContextMenu.jsx","webpack:///./system-addon/content-src/components/CollapsibleSection/CollapsibleSection.jsx","webpack:///./system-addon/content-src/lib/section-menu-options.js","webpack:///./system-addon/content-src/components/ComponentPerfTimer/ComponentPerfTimer.jsx","webpack:///./system-addon/common/PerfService.jsm","webpack:///./system-addon/content-src/components/TopSites/TopSite.jsx","webpack:///./system-addon/content-src/activity-stream.jsx","webpack:///./system-addon/content-src/lib/snippets.js","webpack:///external \"Redux\"","webpack:///./system-addon/content-src/asrouter/components/ImpressionsWrapper/ImpressionsWrapper.jsx","webpack:///./system-addon/content-src/asrouter/components/ModalOverlay/ModalOverlay.jsx","webpack:///./system-addon/content-src/asrouter/templates/OnboardingMessage/OnboardingMessage.jsx","webpack:///./system-addon/content-src/asrouter/template-utils.js","webpack:///./system-addon/content-src/asrouter/components/Button/Button.jsx","webpack:///./system-addon/content-src/asrouter/components/SnippetBase/SnippetBase.jsx","webpack:///./system-addon/content-src/asrouter/templates/SimpleSnippet/SimpleSnippet.jsx","webpack:///./system-addon/content-src/components/Base/Base.jsx","webpack:///./system-addon/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx","webpack:///./system-addon/content-src/components/ConfirmDialog/ConfirmDialog.jsx","webpack:///./system-addon/content-src/components/ManualMigration/ManualMigration.jsx","webpack:///./system-addon/common/PrerenderData.jsm","webpack:///./system-addon/content-src/components/Search/Search.jsx","webpack:///./system-addon/content-src/lib/constants.js","webpack:///./system-addon/content-src/components/Sections/Sections.jsx","webpack:///./system-addon/content-src/components/Card/Card.jsx","webpack:///./system-addon/content-src/components/Card/types.js","webpack:///./system-addon/content-src/components/SectionMenu/SectionMenu.jsx","webpack:///./system-addon/content-src/components/Topics/Topics.jsx","webpack:///./system-addon/content-src/components/TopSites/TopSites.jsx","webpack:///./system-addon/content-src/components/TopSites/TopSiteFormInput.jsx","webpack:///./system-addon/content-src/components/TopSites/TopSiteForm.jsx","webpack:///./system-addon/content-src/components/StartupOverlay/StartupOverlay.jsx","webpack:///./system-addon/content-src/lib/detect-user-session-start.js"],"names":["globalImportContext","Window","BACKGROUND_PROCESS","UI_CODE","actionTypes","type","ASRouterActions","_RouteMessage","action","options","meta","from","to","Error","forEach","o","AlsoToMain","fromTarget","skipLocal","CONTENT_MESSAGE_TYPE","MAIN_MESSAGE_TYPE","OnlyToMain","BroadcastToContent","AlsoToOneContent","target","skipMain","toTarget","OnlyToOneContent","AlsoToPreloaded","PRELOAD_MESSAGE_TYPE","UserEvent","data","TELEMETRY_USER_EVENT","ASRouterUserEvent","AS_ROUTER_TELEMETRY_USER_EVENT","UndesiredEvent","importContext","TELEMETRY_UNDESIRED_EVENT","PerfEvent","TELEMETRY_PERFORMANCE_EVENT","ImpressionStats","TELEMETRY_IMPRESSION_STATS","SetPref","name","value","SET_PREF","WebExtEvent","source","isSendToMain","isBroadcastToContent","isSendToOneContent","isSendToPreloaded","isFromMain","getPortIdOfSender","TOP_SITES_SOURCE","TOP_SITES_CONTEXT_MENU_OPTIONS","MIN_RICH_FAVICON_SIZE","MIN_CORNER_FAVICON_SIZE","Dedupe","constructor","createKey","defaultCreateKey","item","group","groups","globalKeys","Set","result","values","valueMap","Map","key","has","set","push","add","map","m","Array","TOP_SITES_DEFAULT_ROWS","TOP_SITES_MAX_SITES_PER_ROW","dedupe","site","url","INITIAL_STATE","App","initialized","version","Snippets","TopSites","rows","editForm","Prefs","Theme","className","Dialog","visible","Sections","prevState","at","INIT","Object","assign","insertPinned","links","pinned","pinnedUrls","link","newLinks","filter","includes","isPinned","pinIndex","val","index","length","splice","hasMatch","newRows","TOP_SITES_UPDATED","pref","TOP_SITES_PREFS_UPDATED","TOP_SITES_EDIT","previewResponse","TOP_SITES_CANCEL_EDIT","PREVIEW_RESPONSE","previewUrl","preview","PREVIEW_REQUEST","PREVIEW_REQUEST_CANCEL","SCREENSHOT_UPDATED","row","screenshot","PLACES_BOOKMARK_ADDED","bookmarkGuid","bookmarkTitle","dateAdded","bookmarkDateCreated","PLACES_BOOKMARK_REMOVED","newSite","PLACES_LINK_DELETED","DIALOG_OPEN","DIALOG_CANCEL","DELETE_HISTORY_URL","newValues","PREFS_INITIAL_VALUES","PREF_CHANGED","newState","SECTION_DEREGISTER","section","id","SECTION_REGISTER","title","enabled","SECTION_UPDATE","find","card","dedupeConfigurations","dedupeConf","dedupedRows","dedupeFrom","reduce","dedupeSectionId","dedupeSection","s","SECTION_UPDATE_CARD","PLACES_SAVED_TO_POCKET","open_url","pocket_id","PLACES_LINK_BLOCKED","DELETE_FROM_POCKET","ARCHIVE_FROM_POCKET","SNIPPETS_DATA","SNIPPET_BLOCKED","blockList","concat","SNIPPETS_BLOCKLIST_CLEARED","SNIPPETS_RESET","THEME_UPDATE","INCOMING_MESSAGE_NAME","OUTGOING_MESSAGE_NAME","ASRouterUtils","addListener","listener","global","addMessageListener","removeListener","removeMessageListener","sendMessage","sendAsyncMessage","blockById","blockBundle","bundle","executeAction","button_action","button_action_params","unblockById","unblockBundle","getNextMessage","overrideMessage","sendTelemetry","ping","payload","ac","shouldSendImpressionOnUpdate","nextProps","prevProps","message","ASRouterUISurface","React","PureComponent","props","onMessageFromParent","bind","sendImpression","sendUserActionTelemetry","state","extraProps","message_id","eventType","provider","event","onBlockById","clearBundle","setState","componentWillMount","componentWillUnmount","renderSnippets","document","renderOnboarding","render","template","defaultProps","ASRouterContent","containerElement","_mount","getElementById","ReactDOM","_unmount","unmountComponentAtNode","init","uninit","MERGE_STORE_ACTION","EARLY_QUEUED_ACTIONS","SAVE_SESSION_PERF_DATA","PAGE_PRERENDERED","mergeStateReducer","mainReducer","messageMiddleware","store","next","au","rehydrationMiddleware","_didRehydrate","isMergeStoreAction","isRehydrationRequest","NEW_TAB_STATE_REQUEST","_didRequestInitialState","queueEarlyMessageMiddleware","_receivedFromMain","_earlyActionQueue","initStore","reducers","initialState","createStore","combineReducers","applyMiddleware","msg","dispatch","ex","console","error","dump","JSON","stringify","stack","ErrorBoundaryFallback","windowObj","window","onClick","location","reload","defaultClass","ErrorBoundary","hasError","componentDidCatch","info","children","FallbackComponent","_OpenInPrivateWindow","icon","OPEN_PRIVATE_WINDOW","referrer","userEvent","GetPlatformString","platform","LinkMenuOptions","Separator","EmptyItem","RemoveBookmark","DELETE_BOOKMARK_BY_ID","AddBookmark","BOOKMARK_URL","OpenInNewWindow","OPEN_NEW_WINDOW","typedBonus","BlockUrl","eventSource","BLOCK_URL","impression","block","tiles","guid","pos","WebExtDismiss","string_id","WEBEXT_DISMISS","action_position","DeleteUrl","isEnabled","siteInfo","onConfirm","forceBlock","body_string_id","confirm_button_string_id","cancel_button_string_id","ShowFile","SHOW_DOWNLOAD_FILE","OpenFile","OPEN_DOWNLOAD_FILE","CopyDownloadLink","COPY_DOWNLOAD_LINK","GoToDownloadPage","OPEN_LINK","disabled","RemoveDownload","REMOVE_DOWNLOAD_FILE","PinTopSite","TOP_SITES_PIN","UnpinTopSite","TOP_SITES_UNPIN","SaveToPocket","SAVE_TO_POCKET","pocket","DeleteFromPocket","ArchiveFromPocket","EditTopSite","CheckBookmark","CheckPinTopSite","CheckSavedToPocket","CheckBookmarkOrArchive","OpenInPrivateWindow","DEFAULT_SITE_MENU_OPTIONS","_LinkMenu","getOptions","isPrivateBrowsingEnabled","propOptions","isDefault","option","label","intl","formatMessage","userEventData","shouldSendImpressionStats","first","last","onUpdate","getState","LinkMenu","connect","injectIntl","ContextMenu","hideContext","componentDidMount","setTimeout","addEventListener","removeEventListener","stopPropagation","i","ContextMenuItem","onKeyDown","shiftKey","VISIBLE","VISIBILITY_CHANGE_EVENT","getFormattedMessage","Disclaimer","onAcknowledge","disclaimerPref","disclaimer","text","href","button","DisclaimerIntl","_CollapsibleSection","onBodyMount","onHeaderClick","onTransitionEnd","enableOrDisableAnimation","onMenuButtonClick","onMenuButtonMouseEnter","onMenuButtonMouseLeave","onMenuUpdate","enableAnimation","isAnimating","menuButtonHover","showContextMenu","componentWillUpdate","collapsed","sectionBody","scrollHeight","visibilityState","node","undefined","maxHeight","SectionMenuOptions","CheckCollapsed","currentTarget","renderIcon","startsWith","backgroundImage","preventDefault","isCollapsible","extraMenuOptions","showPrefName","privacyNoticeURL","isFirst","isLast","isWebExtension","needsDisclaimer","active","CollapsibleSection","MoveUp","SECTION_MOVE","direction","MoveDown","RemoveSection","CollapseSection","UPDATE_SECTION_PREFS","ExpandSection","ManageSection","SETTINGS_OPEN","ManageWebExtension","OPEN_WEBEXT_SETTINGS","AddTopSite","PrivacyNotice","RECORDED_SECTIONS","ComponentPerfTimer","Component","perfSvc","_sendBadStateEvent","_sendPaintedEvent","_reportMissingData","_timestampHandled","_recordedFirstRender","_maybeSendPaintedEvent","componentDidUpdate","_afterFramePaint","callback","requestAnimationFrame","_maybeSendBadStateEvent","_ensureFirstRenderTsRecorded","mark","dataReadyKey","firstRenderKey","parseInt","getMostRecentAbsMarkStartByName","ChromeUtils","import","usablePerfObj","Services","appShell","hiddenDOMWindow","performance","now","_PerfService","performanceObj","_perf","prototype","str","getEntriesByName","timeOrigin","absNow","entries","mostRecentEntry","startTime","TopSiteLink","onDragEvent","_allowDrop","e","dataTransfer","types","dragged","effectAllowed","setData","blur","defaultStyle","isDraggable","topSiteOuterClassName","isDragged","tippyTopIcon","faviconSize","letterFallback","imageClassName","imageStyle","showSmallFavicon","smallFaviconStyle","smallFaviconFallback","customScreenshotURL","backgroundColor","favicon","draggableProps","onDragEnd","onDragStart","onMouseDown","TopSite","onLinkClick","_getTelemetryInfo","icon_type","iconType","card_type","altKey","ctrlKey","metaKey","onActivate","isContextMenuOpen","activeIndex","hostname","TopSitePlaceholder","onEditButtonClick","_TopSiteList","DEFAULT_STATE","draggedIndex","draggedSite","draggedTitle","topSitesPreview","componentWillReceiveProps","prevTopSites","newTopSites","dropped","_makeTopSitesPreview","TOP_SITES_INSERT","draggedFromIndex","_getTopSites","topSites","slice","TopSitesRows","pinnedOnly","unpinned","siteToInsert","holeIndex","indexStep","shiftingStep","nextIndex","shift","topSitesUI","commonProps","maxNarrowVisibleIndex","l","topSiteIconType","slotProps","TopSiteList","gActivityStreamPrerenderedState","sendEventOrAddListener","hydrate","documentElement","lang","gActivityStreamStrings","addSnippetsSubscriber","DATABASE_NAME","DATABASE_VERSION","SNIPPETS_OBJECTSTORE_NAME","SNIPPETS_UPDATE_INTERVAL_MS","SNIPPETS_ENABLED_EVENT","SNIPPETS_DISABLED_EVENT","SnippetsMap","_db","_dispatch","_dbTransaction","db","put","delete","clear","get","blockSnippetById","SNIPPETS_BLOCKLIST_UPDATED","disableOnboarding","DISABLE_ONBOARDING","showFirefoxAccounts","SHOW_FIREFOX_ACCOUNTS","getTotalBookmarksCount","Promise","resolve","TOTAL_BOOKMARKS_REQUEST","onMessage","TOTAL_BOOKMARKS_RESPONSE","getAddonsInfo","ADDONS_INFO_REQUEST","ADDONS_INFO_RESPONSE","_openDB","_restoreFromDb","modifier","reject","transaction","objectStore","onsuccess","onerror","openRequest","indexedDB","open","deleteDatabase","onupgradeneeded","objectStoreNames","contains","createObjectStore","err","onversionchange","versionChangeEvent","close","cursorRequest","openCursor","cursor","continue","SnippetsProvider","gSnippetsMap","_onAction","snippetsMap","_refreshSnippets","cachedVersion","appData","lastUpdate","needsUpdate","Date","snippetsURL","response","fetch","status","_noSnippetFallback","_forceOnboardingVisibility","shouldBeVisible","onboardingEl","style","display","_showRemoteSnippets","snippetsEl","elementId","innerHTML","scriptEl","getElementsByTagName","relocatedScript","createElement","parentNode","replaceChild","keys","dispatchEvent","Event","snippets","asrouterContent","initializing","subscribe","asrouterExperimentEnabled","disableSnippets","ImpressionsWrapper","sendImpressionOrAddListener","_onVisibilityChange","sendOnMount","body","classList","remove","button_label","onDoneButton","UISurface","onAction","content","safeURI","protocol","URL","isAllowed","warn","ALLOWED_STYLE_TAGS","Button","tag","border","onBlockClicked","onBlock","containerClassName","DEFAULT_ICON_PATH","onButtonClick","renderTitle","renderTitleIcon","titleIcon","title_icon","renderButton","button_url","button_color","button_background_color","hasLink","button_type","hasButton","tall","PrefsButton","addLocaleDataForReactIntl","locale","addLocaleData","parentLocale","_Base","updateTheme","sendNewTabRehydrated","isPrerendered","bodyClassName","isFirstrun","v","join","renderNotified","NEW_TAB_REHYDRATED","strings","hash","BaseContent","openPreferences","prefs","shouldBeFixedToTop","PrerenderData","arePrefsValid","outerClassName","showSearch","migrationExpired","Base","ASRouterAdmin","findOtherBundledMessagesOfSameTemplate","messages","bundled","handleBlock","handleUnblock","handleOverride","renderMessageItem","isCurrent","lastMessageId","isBlocked","itemClassName","renderMessages","renderProviders","providers","_ConfirmDialog","_handleCancelBtn","_handleConfirmBtn","_renderModalMessage","message_body","ConfirmDialog","_ManualMigration","onLaunchTour","onCancelTour","MIGRATION_START","MIGRATION_CANCEL","ManualMigration","_PrerenderData","initialPrefs","initialSections","_setValidation","validation","_validation","invalidatingPrefs","_invalidatingPrefs","oneOf","getPref","indexedDBPrefs","some","anyModifiedPrefs","prefName","order","_Search","onInputMount","handleEvent","detail","gContentSearchController","search","input","healthReportKey","IS_NEWTAB","searchSource","ContentSearchUIController","Search","documentURI","CARDS_PER_ROW_DEFAULT","CARDS_PER_ROW_COMPACT_WIDE","Section","numRows","rowsPref","maxRows","_dispatchImpressionStats","cardsPerRow","compactCards","matchMedia","matches","maxCards","cards","needsImpressionStats","impressionCardGuids","sendImpressionStatsOrAddListener","isCollapsed","wasCollapsed","emptyState","contextMenuOptions","maxCardsPerRow","maxCardsOnNarrow","shouldShowTopics","topics","realRows","shouldShowEmptyState","sectionClassName","feed","padding","read_more_endpoint","SectionIntl","_Sections","renderSections","sections","enabledSections","sectionOrder","showTopSites","expectedCount","sectionId","split","gImageLoading","_Card","activeCard","imageLoaded","cardImage","maybeLoadImage","imageUrl","loaderPromise","loader","Image","src","catch","then","isImageInState","image","isLocalImageObject","path","getNextStateFromProps","imageInState","nextState","maybeRevokeImageBlob","createObjectURL","revokeObjectURL","WEBEXT_CLICK","click","intlID","cardContextTypes","hasImage","placeholder","description","context","Card","PlaceholderCard","history","bookmark","trending","download","DEFAULT_SECTION_MENU_OPTIONS","WEBEXT_SECTION_MENU_OPTIONS","_SectionMenu","extraOptions","SectionMenu","Topic","Topics","t","faviconRef","countTopSitesIconsTypes","countTopSitesTypes","acc","_TopSites","onFormClose","_dispatchTopSitesStats","_getVisibleTopSites","topSitesIconsStats","topSitesPinned","topsites_icon_stats","topsites_pinned","sitesPerRow","topSitesRows","validationError","onChange","onMount","shouldFocus","focus","ev","showClearButton","onClear","typeUrl","titleId","loading","placeholderId","errorMessageId","TopSiteFormInput","customScreenshotUrl","showCustomScreenshotForm","onClearScreenshotInput","onLabelChange","onUrlChange","onCancelButtonClick","onClearUrlClick","onDoneButtonClick","onCustomScreenshotUrlChange","onPreviewButtonClick","onEnableScreenshotUrlForm","validateUrl","_updateCustomScreenshotInput","onClose","validateForm","cleanUrl","_tryParseUrl","validProtocols","urlObj","validateCustomScreenshotUrl","validate","_renderCustomScreenshotInput","requestFailed","isLoading","showAsAdd","previous","changed","previewMode","previewLink","TopSiteForm","_StartupOverlay","onInputChange","onSubmit","clickSkip","initScene","removeOverlay","emailInput","show","termsLink","privacyLink","terms","privacy","StartupOverlay","DetectUserSessionStart","_store","_perfService","perfService","_sendEvent","visibility_event_rcvd_ts"],"mappings":"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","file":"activity-stream.bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 19);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap f7d8f61f69ada03ad1f6","module.exports = React;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"React\"\n// module id = 0\n// module chunks = 0","/* 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\"use strict\";\n\nthis.MAIN_MESSAGE_TYPE = \"ActivityStream:Main\";\nthis.CONTENT_MESSAGE_TYPE = \"ActivityStream:Content\";\nthis.PRELOAD_MESSAGE_TYPE = \"ActivityStream:PreloadedBrowser\";\nthis.UI_CODE = 1;\nthis.BACKGROUND_PROCESS = 2;\n\n/**\n * globalImportContext - Are we in UI code (i.e. react, a dom) or some kind of background process?\n *                       Use this in action creators if you need different logic\n *                       for ui/background processes.\n */\nconst globalImportContext = typeof Window === \"undefined\" ? BACKGROUND_PROCESS : UI_CODE;\n// Export for tests\nthis.globalImportContext = globalImportContext;\n\n// Create an object that avoids accidental differing key/value pairs:\n// {\n//   INIT: \"INIT\",\n//   UNINIT: \"UNINIT\"\n// }\nconst actionTypes = {};\nfor (const type of [\n  \"ADDONS_INFO_REQUEST\",\n  \"ADDONS_INFO_RESPONSE\",\n  \"ARCHIVE_FROM_POCKET\",\n  \"AS_ROUTER_TELEMETRY_USER_EVENT\",\n  \"BLOCK_URL\",\n  \"BOOKMARK_URL\",\n  \"COPY_DOWNLOAD_LINK\",\n  \"DELETE_BOOKMARK_BY_ID\",\n  \"DELETE_FROM_POCKET\",\n  \"DELETE_HISTORY_URL\",\n  \"DIALOG_CANCEL\",\n  \"DIALOG_OPEN\",\n  \"DISABLE_ONBOARDING\",\n  \"DOWNLOAD_CHANGED\",\n  \"INIT\",\n  \"MIGRATION_CANCEL\",\n  \"MIGRATION_COMPLETED\",\n  \"MIGRATION_START\",\n  \"NEW_TAB_INIT\",\n  \"NEW_TAB_INITIAL_STATE\",\n  \"NEW_TAB_LOAD\",\n  \"NEW_TAB_REHYDRATED\",\n  \"NEW_TAB_STATE_REQUEST\",\n  \"NEW_TAB_UNLOAD\",\n  \"OPEN_DOWNLOAD_FILE\",\n  \"OPEN_LINK\",\n  \"OPEN_NEW_WINDOW\",\n  \"OPEN_PRIVATE_WINDOW\",\n  \"OPEN_WEBEXT_SETTINGS\",\n  \"PAGE_PRERENDERED\",\n  \"PLACES_BOOKMARK_ADDED\",\n  \"PLACES_BOOKMARK_REMOVED\",\n  \"PLACES_HISTORY_CLEARED\",\n  \"PLACES_LINKS_CHANGED\",\n  \"PLACES_LINK_BLOCKED\",\n  \"PLACES_LINK_DELETED\",\n  \"PLACES_SAVED_TO_POCKET\",\n  \"PREFS_INITIAL_VALUES\",\n  \"PREF_CHANGED\",\n  \"PREVIEW_REQUEST\",\n  \"PREVIEW_REQUEST_CANCEL\",\n  \"PREVIEW_RESPONSE\",\n  \"REMOVE_DOWNLOAD_FILE\",\n  \"RICH_ICON_MISSING\",\n  \"SAVE_SESSION_PERF_DATA\",\n  \"SAVE_TO_POCKET\",\n  \"SCREENSHOT_UPDATED\",\n  \"SECTION_DEREGISTER\",\n  \"SECTION_DISABLE\",\n  \"SECTION_ENABLE\",\n  \"SECTION_MOVE\",\n  \"SECTION_OPTIONS_CHANGED\",\n  \"SECTION_REGISTER\",\n  \"SECTION_UPDATE\",\n  \"SECTION_UPDATE_CARD\",\n  \"SETTINGS_CLOSE\",\n  \"SETTINGS_OPEN\",\n  \"SET_PREF\",\n  \"SHOW_DOWNLOAD_FILE\",\n  \"SHOW_FIREFOX_ACCOUNTS\",\n  \"SKIPPED_SIGNIN\",\n  \"SNIPPETS_BLOCKLIST_CLEARED\",\n  \"SNIPPETS_BLOCKLIST_UPDATED\",\n  \"SNIPPETS_DATA\",\n  \"SNIPPETS_RESET\",\n  \"SNIPPET_BLOCKED\",\n  \"SUBMIT_EMAIL\",\n  \"SYSTEM_TICK\",\n  \"TELEMETRY_IMPRESSION_STATS\",\n  \"TELEMETRY_PERFORMANCE_EVENT\",\n  \"TELEMETRY_UNDESIRED_EVENT\",\n  \"TELEMETRY_USER_EVENT\",\n  \"THEME_UPDATE\",\n  \"TOP_SITES_CANCEL_EDIT\",\n  \"TOP_SITES_EDIT\",\n  \"TOP_SITES_INSERT\",\n  \"TOP_SITES_PIN\",\n  \"TOP_SITES_PREFS_UPDATED\",\n  \"TOP_SITES_UNPIN\",\n  \"TOP_SITES_UPDATED\",\n  \"TOTAL_BOOKMARKS_REQUEST\",\n  \"TOTAL_BOOKMARKS_RESPONSE\",\n  \"UNINIT\",\n  \"UPDATE_SECTION_PREFS\",\n  \"WEBEXT_CLICK\",\n  \"WEBEXT_DISMISS\"\n]) {\n  actionTypes[type] = type;\n}\n\n// These are acceptable actions for AS Router messages to have. They can show up\n// as call-to-action buttons in snippets, onboarding tour, etc.\nconst ASRouterActions = {};\nfor (const type of [\n  \"OPEN_PRIVATE_BROWSER_WINDOW\",\n  \"OPEN_URL\",\n  \"OPEN_ABOUT_PAGE\"\n]) {\n  ASRouterActions[type] = type;\n}\n\n// Helper function for creating routed actions between content and main\n// Not intended to be used by consumers\nfunction _RouteMessage(action, options) {\n  const meta = action.meta ? {...action.meta} : {};\n  if (!options || !options.from || !options.to) {\n    throw new Error(\"Routed Messages must have options as the second parameter, and must at least include a .from and .to property.\");\n  }\n  // For each of these fields, if they are passed as an option,\n  // add them to the action. If they are not defined, remove them.\n  [\"from\", \"to\", \"toTarget\", \"fromTarget\", \"skipMain\", \"skipLocal\"].forEach(o => {\n    if (typeof options[o] !== \"undefined\") {\n      meta[o] = options[o];\n    } else if (meta[o]) {\n      delete meta[o];\n    }\n  });\n  return {...action, meta};\n}\n\n/**\n * AlsoToMain - Creates a message that will be dispatched locally and also sent to the Main process.\n *\n * @param  {object} action Any redux action (required)\n * @param  {object} options\n * @param  {bool}   skipLocal Used by OnlyToMain to skip the main reducer\n * @param  {string} fromTarget The id of the content port from which the action originated. (optional)\n * @return {object} An action with added .meta properties\n */\nfunction AlsoToMain(action, fromTarget, skipLocal) {\n  return _RouteMessage(action, {\n    from: CONTENT_MESSAGE_TYPE,\n    to: MAIN_MESSAGE_TYPE,\n    fromTarget,\n    skipLocal\n  });\n}\n\n/**\n * OnlyToMain - Creates a message that will be sent to the Main process and skip the local reducer.\n *\n * @param  {object} action Any redux action (required)\n * @param  {object} options\n * @param  {string} fromTarget The id of the content port from which the action originated. (optional)\n * @return {object} An action with added .meta properties\n */\nfunction OnlyToMain(action, fromTarget) {\n  return AlsoToMain(action, fromTarget, true);\n}\n\n/**\n * BroadcastToContent - Creates a message that will be dispatched to main and sent to ALL content processes.\n *\n * @param  {object} action Any redux action (required)\n * @return {object} An action with added .meta properties\n */\nfunction BroadcastToContent(action) {\n  return _RouteMessage(action, {\n    from: MAIN_MESSAGE_TYPE,\n    to: CONTENT_MESSAGE_TYPE\n  });\n}\n\n/**\n * AlsoToOneContent - Creates a message that will be will be dispatched to the main store\n *                    and also sent to a particular Content process.\n *\n * @param  {object} action Any redux action (required)\n * @param  {string} target The id of a content port\n * @param  {bool} skipMain Used by OnlyToOneContent to skip the main process\n * @return {object} An action with added .meta properties\n */\nfunction AlsoToOneContent(action, target, skipMain) {\n  if (!target) {\n    throw new Error(\"You must provide a target ID as the second parameter of AlsoToOneContent. If you want to send to all content processes, use BroadcastToContent\");\n  }\n  return _RouteMessage(action, {\n    from: MAIN_MESSAGE_TYPE,\n    to: CONTENT_MESSAGE_TYPE,\n    toTarget: target,\n    skipMain\n  });\n}\n\n/**\n * OnlyToOneContent - Creates a message that will be sent to a particular Content process\n *                    and skip the main reducer.\n *\n * @param  {object} action Any redux action (required)\n * @param  {string} target The id of a content port\n * @return {object} An action with added .meta properties\n */\nfunction OnlyToOneContent(action, target) {\n  return AlsoToOneContent(action, target, true);\n}\n\n/**\n * AlsoToPreloaded - Creates a message that dispatched to the main reducer and also sent to the preloaded tab.\n *\n * @param  {object} action Any redux action (required)\n * @return {object} An action with added .meta properties\n */\nfunction AlsoToPreloaded(action) {\n  return _RouteMessage(action, {\n    from: MAIN_MESSAGE_TYPE,\n    to: PRELOAD_MESSAGE_TYPE\n  });\n}\n\n/**\n * UserEvent - A telemetry ping indicating a user action. This should only\n *                   be sent from the UI during a user session.\n *\n * @param  {object} data Fields to include in the ping (source, etc.)\n * @return {object} An AlsoToMain action\n */\nfunction UserEvent(data) {\n  return AlsoToMain({\n    type: actionTypes.TELEMETRY_USER_EVENT,\n    data\n  });\n}\n\n/**\n * ASRouterUserEvent - A telemetry ping indicating a user action from AS router. This should only\n *                     be sent from the UI during a user session.\n *\n * @param  {object} data Fields to include in the ping (source, etc.)\n * @return {object} An AlsoToMain action\n */\nfunction ASRouterUserEvent(data) {\n  return AlsoToMain({\n    type: actionTypes.AS_ROUTER_TELEMETRY_USER_EVENT,\n    data\n  });\n}\n\n/**\n * UndesiredEvent - A telemetry ping indicating an undesired state.\n *\n * @param  {object} data Fields to include in the ping (value, etc.)\n * @param  {int} importContext (For testing) Override the import context for testing.\n * @return {object} An action. For UI code, a AlsoToMain action.\n */\nfunction UndesiredEvent(data, importContext = globalImportContext) {\n  const action = {\n    type: actionTypes.TELEMETRY_UNDESIRED_EVENT,\n    data\n  };\n  return importContext === UI_CODE ? AlsoToMain(action) : action;\n}\n\n/**\n * PerfEvent - A telemetry ping indicating a performance-related event.\n *\n * @param  {object} data Fields to include in the ping (value, etc.)\n * @param  {int} importContext (For testing) Override the import context for testing.\n * @return {object} An action. For UI code, a AlsoToMain action.\n */\nfunction PerfEvent(data, importContext = globalImportContext) {\n  const action = {\n    type: actionTypes.TELEMETRY_PERFORMANCE_EVENT,\n    data\n  };\n  return importContext === UI_CODE ? AlsoToMain(action) : action;\n}\n\n/**\n * ImpressionStats - A telemetry ping indicating an impression stats.\n *\n * @param  {object} data Fields to include in the ping\n * @param  {int} importContext (For testing) Override the import context for testing.\n * #return {object} An action. For UI code, a AlsoToMain action.\n */\nfunction ImpressionStats(data, importContext = globalImportContext) {\n  const action = {\n    type: actionTypes.TELEMETRY_IMPRESSION_STATS,\n    data\n  };\n  return importContext === UI_CODE ? AlsoToMain(action) : action;\n}\n\nfunction SetPref(name, value, importContext = globalImportContext) {\n  const action = {type: actionTypes.SET_PREF, data: {name, value}};\n  return importContext === UI_CODE ? AlsoToMain(action) : action;\n}\n\nfunction WebExtEvent(type, data, importContext = globalImportContext) {\n  if (!data || !data.source) {\n    throw new Error(\"WebExtEvent actions should include a property \\\"source\\\", the id of the webextension that should receive the event.\");\n  }\n  const action = {type, data};\n  return importContext === UI_CODE ? AlsoToMain(action) : action;\n}\n\nthis.actionTypes = actionTypes;\nthis.ASRouterActions = ASRouterActions;\n\nthis.actionCreators = {\n  BroadcastToContent,\n  UserEvent,\n  ASRouterUserEvent,\n  UndesiredEvent,\n  PerfEvent,\n  ImpressionStats,\n  AlsoToOneContent,\n  OnlyToOneContent,\n  AlsoToMain,\n  OnlyToMain,\n  AlsoToPreloaded,\n  SetPref,\n  WebExtEvent\n};\n\n// These are helpers to test for certain kinds of actions\nthis.actionUtils = {\n  isSendToMain(action) {\n    if (!action.meta) {\n      return false;\n    }\n    return action.meta.to === MAIN_MESSAGE_TYPE && action.meta.from === CONTENT_MESSAGE_TYPE;\n  },\n  isBroadcastToContent(action) {\n    if (!action.meta) {\n      return false;\n    }\n    if (action.meta.to === CONTENT_MESSAGE_TYPE && !action.meta.toTarget) {\n      return true;\n    }\n    return false;\n  },\n  isSendToOneContent(action) {\n    if (!action.meta) {\n      return false;\n    }\n    if (action.meta.to === CONTENT_MESSAGE_TYPE && action.meta.toTarget) {\n      return true;\n    }\n    return false;\n  },\n  isSendToPreloaded(action) {\n    if (!action.meta) {\n      return false;\n    }\n    return action.meta.to === PRELOAD_MESSAGE_TYPE &&\n      action.meta.from === MAIN_MESSAGE_TYPE;\n  },\n  isFromMain(action) {\n    if (!action.meta) {\n      return false;\n    }\n    return action.meta.from === MAIN_MESSAGE_TYPE &&\n      action.meta.to === CONTENT_MESSAGE_TYPE;\n  },\n  getPortIdOfSender(action) {\n    return (action.meta && action.meta.fromTarget) || null;\n  },\n  _RouteMessage\n};\n\nconst EXPORTED_SYMBOLS = [\n  \"actionTypes\",\n  \"actionCreators\",\n  \"actionUtils\",\n  \"ASRouterActions\",\n  \"globalImportContext\",\n  \"UI_CODE\",\n  \"BACKGROUND_PROCESS\",\n  \"MAIN_MESSAGE_TYPE\",\n  \"CONTENT_MESSAGE_TYPE\",\n  \"PRELOAD_MESSAGE_TYPE\"\n];\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/common/Actions.jsm","module.exports = ReactIntl;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"ReactIntl\"\n// module id = 2\n// module chunks = 0","var g;\r\n\r\n// This works in non-strict mode\r\ng = (function() {\r\n\treturn this;\r\n})();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === \"object\")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it's\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/global.js\n// module id = 3\n// module chunks = 0","module.exports = ReactRedux;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"ReactRedux\"\n// module id = 4\n// module chunks = 0","export const TOP_SITES_SOURCE = \"TOP_SITES\";\nexport const TOP_SITES_CONTEXT_MENU_OPTIONS = [\"CheckPinTopSite\", \"EditTopSite\", \"Separator\",\n  \"OpenInNewWindow\", \"OpenInPrivateWindow\", \"Separator\", \"BlockUrl\", \"DeleteUrl\"];\n// minimum size necessary to show a rich icon instead of a screenshot\nexport const MIN_RICH_FAVICON_SIZE = 96;\n// minimum size necessary to show any icon in the top left corner with a screenshot\nexport const MIN_CORNER_FAVICON_SIZE = 16;\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/TopSites/TopSitesConstants.js","this.Dedupe = class Dedupe {\n  constructor(createKey) {\n    this.createKey = createKey || this.defaultCreateKey;\n  }\n\n  defaultCreateKey(item) {\n    return item;\n  }\n\n  /**\n   * Dedupe any number of grouped elements favoring those from earlier groups.\n   *\n   * @param {Array} groups Contains an arbitrary number of arrays of elements.\n   * @returns {Array} A matching array of each provided group deduped.\n   */\n  group(...groups) {\n    const globalKeys = new Set();\n    const result = [];\n    for (const values of groups) {\n      const valueMap = new Map();\n      for (const value of values) {\n        const key = this.createKey(value);\n        if (!globalKeys.has(key) && !valueMap.has(key)) {\n          valueMap.set(key, value);\n        }\n      }\n      result.push(valueMap);\n      valueMap.forEach((value, key) => globalKeys.add(key));\n    }\n    return result.map(m => Array.from(m.values()));\n  }\n};\n\nconst EXPORTED_SYMBOLS = [\"Dedupe\"];\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/common/Dedupe.jsm","/* 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\"use strict\";\n\nconst {actionTypes: at} = ChromeUtils.import(\"resource://activity-stream/common/Actions.jsm\", {});\nconst {Dedupe} = ChromeUtils.import(\"resource://activity-stream/common/Dedupe.jsm\", {});\n\nconst TOP_SITES_DEFAULT_ROWS = 1;\nconst TOP_SITES_MAX_SITES_PER_ROW = 8;\n\nconst dedupe = new Dedupe(site => site && site.url);\n\nconst INITIAL_STATE = {\n  App: {\n    // Have we received real data from the app yet?\n    initialized: false,\n    // The version of the system-addon\n    version: null\n  },\n  Snippets: {initialized: false},\n  TopSites: {\n    // Have we received real data from history yet?\n    initialized: false,\n    // The history (and possibly default) links\n    rows: [],\n    // Used in content only to dispatch action to TopSiteForm.\n    editForm: null\n  },\n  Prefs: {\n    initialized: false,\n    values: {}\n  },\n  Theme: {className: \"\"},\n  Dialog: {\n    visible: false,\n    data: {}\n  },\n  Sections: []\n};\n\nfunction App(prevState = INITIAL_STATE.App, action) {\n  switch (action.type) {\n    case at.INIT:\n      return Object.assign({}, prevState, action.data || {}, {initialized: true});\n    default:\n      return prevState;\n  }\n}\n\n/**\n * insertPinned - Inserts pinned links in their specified slots\n *\n * @param {array} a list of links\n * @param {array} a list of pinned links\n * @return {array} resulting list of links with pinned links inserted\n */\nfunction insertPinned(links, pinned) {\n  // Remove any pinned links\n  const pinnedUrls = pinned.map(link => link && link.url);\n  let newLinks = links.filter(link => (link ? !pinnedUrls.includes(link.url) : false));\n  newLinks = newLinks.map(link => {\n    if (link && link.isPinned) {\n      delete link.isPinned;\n      delete link.pinIndex;\n    }\n    return link;\n  });\n\n  // Then insert them in their specified location\n  pinned.forEach((val, index) => {\n    if (!val) { return; }\n    let link = Object.assign({}, val, {isPinned: true, pinIndex: index});\n    if (index > newLinks.length) {\n      newLinks[index] = link;\n    } else {\n      newLinks.splice(index, 0, link);\n    }\n  });\n\n  return newLinks;\n}\n\nfunction TopSites(prevState = INITIAL_STATE.TopSites, action) {\n  let hasMatch;\n  let newRows;\n  switch (action.type) {\n    case at.TOP_SITES_UPDATED:\n      if (!action.data || !action.data.links) {\n        return prevState;\n      }\n      return Object.assign({}, prevState, {initialized: true, rows: action.data.links}, action.data.pref ? {pref: action.data.pref} : {});\n    case at.TOP_SITES_PREFS_UPDATED:\n      return Object.assign({}, prevState, {pref: action.data.pref});\n    case at.TOP_SITES_EDIT:\n      return Object.assign({}, prevState, {\n        editForm: {\n          index: action.data.index,\n          previewResponse: null\n        }\n      });\n    case at.TOP_SITES_CANCEL_EDIT:\n      return Object.assign({}, prevState, {editForm: null});\n    case at.PREVIEW_RESPONSE:\n      if (!prevState.editForm || action.data.url !== prevState.editForm.previewUrl) {\n        return prevState;\n      }\n      return Object.assign({}, prevState, {\n        editForm: {\n          index: prevState.editForm.index,\n          previewResponse: action.data.preview,\n          previewUrl: action.data.url\n        }\n      });\n    case at.PREVIEW_REQUEST:\n      if (!prevState.editForm) {\n        return prevState;\n      }\n      return Object.assign({}, prevState, {\n        editForm: {\n          index: prevState.editForm.index,\n          previewResponse: null,\n          previewUrl: action.data.url\n        }\n      });\n    case at.PREVIEW_REQUEST_CANCEL:\n      if (!prevState.editForm) {\n        return prevState;\n      }\n      return Object.assign({}, prevState, {\n        editForm: {\n          index: prevState.editForm.index,\n          previewResponse: null\n        }\n      });\n    case at.SCREENSHOT_UPDATED:\n      newRows = prevState.rows.map(row => {\n        if (row && row.url === action.data.url) {\n          hasMatch = true;\n          return Object.assign({}, row, {screenshot: action.data.screenshot});\n        }\n        return row;\n      });\n      return hasMatch ? Object.assign({}, prevState, {rows: newRows}) : prevState;\n    case at.PLACES_BOOKMARK_ADDED:\n      if (!action.data) {\n        return prevState;\n      }\n      newRows = prevState.rows.map(site => {\n        if (site && site.url === action.data.url) {\n          const {bookmarkGuid, bookmarkTitle, dateAdded} = action.data;\n          return Object.assign({}, site, {bookmarkGuid, bookmarkTitle, bookmarkDateCreated: dateAdded});\n        }\n        return site;\n      });\n      return Object.assign({}, prevState, {rows: newRows});\n    case at.PLACES_BOOKMARK_REMOVED:\n      if (!action.data) {\n        return prevState;\n      }\n      newRows = prevState.rows.map(site => {\n        if (site && site.url === action.data.url) {\n          const newSite = Object.assign({}, site);\n          delete newSite.bookmarkGuid;\n          delete newSite.bookmarkTitle;\n          delete newSite.bookmarkDateCreated;\n          return newSite;\n        }\n        return site;\n      });\n      return Object.assign({}, prevState, {rows: newRows});\n    case at.PLACES_LINK_DELETED:\n      if (!action.data) {\n        return prevState;\n      }\n      newRows = prevState.rows.filter(site => action.data.url !== site.url);\n      return Object.assign({}, prevState, {rows: newRows});\n    default:\n      return prevState;\n  }\n}\n\nfunction Dialog(prevState = INITIAL_STATE.Dialog, action) {\n  switch (action.type) {\n    case at.DIALOG_OPEN:\n      return Object.assign({}, prevState, {visible: true, data: action.data});\n    case at.DIALOG_CANCEL:\n      return Object.assign({}, prevState, {visible: false});\n    case at.DELETE_HISTORY_URL:\n      return Object.assign({}, INITIAL_STATE.Dialog);\n    default:\n      return prevState;\n  }\n}\n\nfunction Prefs(prevState = INITIAL_STATE.Prefs, action) {\n  let newValues;\n  switch (action.type) {\n    case at.PREFS_INITIAL_VALUES:\n      return Object.assign({}, prevState, {initialized: true, values: action.data});\n    case at.PREF_CHANGED:\n      newValues = Object.assign({}, prevState.values);\n      newValues[action.data.name] = action.data.value;\n      return Object.assign({}, prevState, {values: newValues});\n    default:\n      return prevState;\n  }\n}\n\nfunction Sections(prevState = INITIAL_STATE.Sections, action) {\n  let hasMatch;\n  let newState;\n  switch (action.type) {\n    case at.SECTION_DEREGISTER:\n      return prevState.filter(section => section.id !== action.data);\n    case at.SECTION_REGISTER:\n      // If section exists in prevState, update it\n      newState = prevState.map(section => {\n        if (section && section.id === action.data.id) {\n          hasMatch = true;\n          return Object.assign({}, section, action.data);\n        }\n        return section;\n      });\n      // Otherwise, append it\n      if (!hasMatch) {\n        const initialized = !!(action.data.rows && action.data.rows.length > 0);\n        const section = Object.assign({title: \"\", rows: [], enabled: false}, action.data, {initialized});\n        newState.push(section);\n      }\n      return newState;\n    case at.SECTION_UPDATE:\n      newState = prevState.map(section => {\n        if (section && section.id === action.data.id) {\n          // If the action is updating rows, we should consider initialized to be true.\n          // This can be overridden if initialized is defined in the action.data\n          const initialized = action.data.rows ? {initialized: true} : {};\n\n          // Make sure pinned cards stay at their current position when rows are updated.\n          // Disabling a section (SECTION_UPDATE with empty rows) does not retain pinned cards.\n          if (action.data.rows && action.data.rows.length > 0 && section.rows.find(card => card.pinned)) {\n            const rows = Array.from(action.data.rows);\n            section.rows.forEach((card, index) => {\n              if (card.pinned) {\n                rows.splice(index, 0, card);\n              }\n            });\n            return Object.assign({}, section, initialized, Object.assign({}, action.data, {rows}));\n          }\n\n          return Object.assign({}, section, initialized, action.data);\n        }\n        return section;\n      });\n\n      if (!action.data.dedupeConfigurations) {\n        return newState;\n      }\n\n      action.data.dedupeConfigurations.forEach(dedupeConf => {\n        newState = newState.map(section => {\n          if (section.id === dedupeConf.id) {\n            const dedupedRows = dedupeConf.dedupeFrom.reduce((rows, dedupeSectionId) => {\n              const dedupeSection = newState.find(s => s.id === dedupeSectionId);\n              const [, newRows] = dedupe.group(dedupeSection.rows, rows);\n              return newRows;\n            }, section.rows);\n\n            return Object.assign({}, section, {rows: dedupedRows});\n          }\n\n          return section;\n        });\n      });\n\n      return newState;\n    case at.SECTION_UPDATE_CARD:\n      return prevState.map(section => {\n        if (section && section.id === action.data.id && section.rows) {\n          const newRows = section.rows.map(card => {\n            if (card.url === action.data.url) {\n              return Object.assign({}, card, action.data.options);\n            }\n            return card;\n          });\n          return Object.assign({}, section, {rows: newRows});\n        }\n        return section;\n      });\n    case at.PLACES_BOOKMARK_ADDED:\n      if (!action.data) {\n        return prevState;\n      }\n      return prevState.map(section => Object.assign({}, section, {\n        rows: section.rows.map(item => {\n          // find the item within the rows that is attempted to be bookmarked\n          if (item.url === action.data.url) {\n            const {bookmarkGuid, bookmarkTitle, dateAdded} = action.data;\n            return Object.assign({}, item, {\n              bookmarkGuid,\n              bookmarkTitle,\n              bookmarkDateCreated: dateAdded,\n              type: \"bookmark\"\n            });\n          }\n          return item;\n        })\n      }));\n    case at.PLACES_SAVED_TO_POCKET:\n      if (!action.data) {\n        return prevState;\n      }\n      return prevState.map(section => Object.assign({}, section, {\n        rows: section.rows.map(item => {\n          if (item.url === action.data.url) {\n            return Object.assign({}, item, {\n              open_url: action.data.open_url,\n              pocket_id: action.data.pocket_id,\n              title: action.data.title,\n              type: \"pocket\"\n            });\n          }\n          return item;\n        })\n      }));\n    case at.PLACES_BOOKMARK_REMOVED:\n      if (!action.data) {\n        return prevState;\n      }\n      return prevState.map(section => Object.assign({}, section, {\n        rows: section.rows.map(item => {\n          // find the bookmark within the rows that is attempted to be removed\n          if (item.url === action.data.url) {\n            const newSite = Object.assign({}, item);\n            delete newSite.bookmarkGuid;\n            delete newSite.bookmarkTitle;\n            delete newSite.bookmarkDateCreated;\n            if (!newSite.type || newSite.type === \"bookmark\") {\n              newSite.type = \"history\";\n            }\n            return newSite;\n          }\n          return item;\n        })\n      }));\n    case at.PLACES_LINK_DELETED:\n    case at.PLACES_LINK_BLOCKED:\n      if (!action.data) {\n        return prevState;\n      }\n      return prevState.map(section =>\n        Object.assign({}, section, {rows: section.rows.filter(site => site.url !== action.data.url)}));\n    case at.DELETE_FROM_POCKET:\n    case at.ARCHIVE_FROM_POCKET:\n      return prevState.map(section =>\n        Object.assign({}, section, {rows: section.rows.filter(site => site.pocket_id !== action.data.pocket_id)}));\n    default:\n      return prevState;\n  }\n}\n\nfunction Snippets(prevState = INITIAL_STATE.Snippets, action) {\n  switch (action.type) {\n    case at.SNIPPETS_DATA:\n      return Object.assign({}, prevState, {initialized: true}, action.data);\n    case at.SNIPPET_BLOCKED:\n      return Object.assign({}, prevState, {blockList: prevState.blockList.concat(action.data)});\n    case at.SNIPPETS_BLOCKLIST_CLEARED:\n      return Object.assign({}, prevState, {blockList: []});\n    case at.SNIPPETS_RESET:\n      return INITIAL_STATE.Snippets;\n    default:\n      return prevState;\n  }\n}\n\nfunction Theme(prevState = INITIAL_STATE.Theme, action) {\n  switch (action.type) {\n    case at.THEME_UPDATE:\n      return Object.assign({}, prevState, action.data);\n    default:\n      return prevState;\n  }\n}\n\nthis.INITIAL_STATE = INITIAL_STATE;\nthis.TOP_SITES_DEFAULT_ROWS = TOP_SITES_DEFAULT_ROWS;\nthis.TOP_SITES_MAX_SITES_PER_ROW = TOP_SITES_MAX_SITES_PER_ROW;\n\nthis.reducers = {TopSites, App, Snippets, Prefs, Dialog, Sections, Theme};\n\nconst EXPORTED_SYMBOLS = [\"reducers\", \"INITIAL_STATE\", \"insertPinned\", \"TOP_SITES_DEFAULT_ROWS\", \"TOP_SITES_MAX_SITES_PER_ROW\"];\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/common/Reducers.jsm","import {actionCreators as ac, ASRouterActions as ra} from \"common/Actions.jsm\";\nimport {OUTGOING_MESSAGE_NAME as AS_GENERAL_OUTGOING_MESSAGE_NAME} from \"content-src/lib/init-store\";\nimport {ImpressionsWrapper} from \"./components/ImpressionsWrapper/ImpressionsWrapper\";\nimport {OnboardingMessage} from \"./templates/OnboardingMessage/OnboardingMessage\";\nimport React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport {SimpleSnippet} from \"./templates/SimpleSnippet/SimpleSnippet\";\n\nconst INCOMING_MESSAGE_NAME = \"ASRouter:parent-to-child\";\nconst OUTGOING_MESSAGE_NAME = \"ASRouter:child-to-parent\";\n\nexport const ASRouterUtils = {\n  addListener(listener) {\n    global.addMessageListener(INCOMING_MESSAGE_NAME, listener);\n  },\n  removeListener(listener) {\n    global.removeMessageListener(INCOMING_MESSAGE_NAME, listener);\n  },\n  sendMessage(action) {\n    global.sendAsyncMessage(OUTGOING_MESSAGE_NAME, action);\n  },\n  blockById(id) {\n    ASRouterUtils.sendMessage({type: \"BLOCK_MESSAGE_BY_ID\", data: {id}});\n  },\n  blockBundle(bundle) {\n    ASRouterUtils.sendMessage({type: \"BLOCK_BUNDLE\", data: {bundle}});\n  },\n  executeAction({button_action, button_action_params}) {\n    if (button_action in ra) {\n      ASRouterUtils.sendMessage({type: button_action, data: {button_action_params}});\n    }\n  },\n  unblockById(id) {\n    ASRouterUtils.sendMessage({type: \"UNBLOCK_MESSAGE_BY_ID\", data: {id}});\n  },\n  unblockBundle(bundle) {\n    ASRouterUtils.sendMessage({type: \"UNBLOCK_BUNDLE\", data: {bundle}});\n  },\n  getNextMessage() {\n    ASRouterUtils.sendMessage({type: \"GET_NEXT_MESSAGE\"});\n  },\n  overrideMessage(id) {\n    ASRouterUtils.sendMessage({type: \"OVERRIDE_MESSAGE\", data: {id}});\n  },\n  sendTelemetry(ping) {\n    const payload = ac.ASRouterUserEvent(ping);\n    global.sendAsyncMessage(AS_GENERAL_OUTGOING_MESSAGE_NAME, payload);\n  }\n};\n\n// Note: nextProps/prevProps refer to props passed to <ImpressionsWrapper />, not <ASRouterUISurface />\nfunction shouldSendImpressionOnUpdate(nextProps, prevProps) {\n  return (nextProps.message.id && (!prevProps.message || prevProps.message.id !== nextProps.message.id));\n}\n\nexport class ASRouterUISurface extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onMessageFromParent = this.onMessageFromParent.bind(this);\n    this.sendImpression = this.sendImpression.bind(this);\n    this.sendUserActionTelemetry = this.sendUserActionTelemetry.bind(this);\n    this.state = {message: {}, bundle: {}};\n  }\n\n  sendUserActionTelemetry(extraProps = {}) {\n    const {message, bundle} = this.state;\n    if (!message && !extraProps.message_id) {\n      throw new Error(`You must provide a message_id for bundled messages`);\n    }\n    const eventType = `${message.provider || bundle.provider}_user_event`;\n    ASRouterUtils.sendTelemetry({\n      message_id: message.id || extraProps.message_id,\n      source: extraProps.id,\n      action: eventType,\n      ...extraProps\n    });\n  }\n\n  sendImpression(extraProps) {\n    this.sendUserActionTelemetry({event: \"IMPRESSION\", ...extraProps});\n  }\n\n  onBlockById(id) {\n    return () => ASRouterUtils.blockById(id);\n  }\n\n  clearBundle(bundle) {\n    return () => ASRouterUtils.blockBundle(bundle);\n  }\n\n  onMessageFromParent({data: action}) {\n    switch (action.type) {\n      case \"SET_MESSAGE\":\n        this.setState({message: action.data});\n        break;\n      case \"SET_BUNDLED_MESSAGES\":\n        this.setState({bundle: action.data});\n        break;\n      case \"CLEAR_MESSAGE\":\n        if (action.data.id === this.state.message.id) {\n          this.setState({message: {}});\n        }\n        break;\n      case \"CLEAR_BUNDLE\":\n        if (this.state.bundle.bundle) {\n          this.setState({bundle: {}});\n        }\n        break;\n      case \"CLEAR_ALL\":\n        this.setState({message: {}, bundle: {}});\n    }\n  }\n\n  componentWillMount() {\n    ASRouterUtils.addListener(this.onMessageFromParent);\n    ASRouterUtils.sendMessage({type: \"CONNECT_UI_REQUEST\"});\n  }\n\n  componentWillUnmount() {\n    ASRouterUtils.removeListener(this.onMessageFromParent);\n  }\n\n  renderSnippets() {\n    return (\n      <ImpressionsWrapper\n        id=\"NEWTAB_FOOTER_BAR\"\n        message={this.state.message}\n        sendImpression={this.sendImpression}\n        shouldSendImpressionOnUpdate={shouldSendImpressionOnUpdate}\n        // This helps with testing\n        document={this.props.document}>\n          <SimpleSnippet\n            {...this.state.message}\n            UISurface=\"NEWTAB_FOOTER_BAR\"\n            getNextMessage={ASRouterUtils.getNextMessage}\n            onBlock={this.onBlockById(this.state.message.id)}\n            sendUserActionTelemetry={this.sendUserActionTelemetry} />\n      </ImpressionsWrapper>);\n  }\n\n  renderOnboarding() {\n    return (\n      <OnboardingMessage\n        {...this.state.bundle}\n        UISurface=\"NEWTAB_OVERLAY\"\n        onAction={ASRouterUtils.executeAction}\n        onDoneButton={this.clearBundle(this.state.bundle.bundle)}\n        getNextMessage={ASRouterUtils.getNextMessage}\n        sendUserActionTelemetry={this.sendUserActionTelemetry} />);\n  }\n\n  render() {\n    const {message, bundle} = this.state;\n    if (!message.id && !bundle.template) { return null; }\n    if (bundle.template === \"onboarding\") { return this.renderOnboarding(); }\n    return this.renderSnippets();\n  }\n}\n\nASRouterUISurface.defaultProps = {document: global.document};\n\nexport class ASRouterContent {\n  constructor() {\n    this.initialized = false;\n    this.containerElement = null;\n  }\n\n  _mount() {\n    this.containerElement = global.document.getElementById(\"snippets-container\");\n    ReactDOM.render(<ASRouterUISurface />, this.containerElement);\n  }\n\n  _unmount() {\n    ReactDOM.unmountComponentAtNode(this.containerElement);\n  }\n\n  init() {\n    this._mount();\n    this.initialized = true;\n  }\n\n  uninit() {\n    if (this.initialized) {\n      this._unmount();\n      this.initialized = false;\n    }\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/asrouter/asrouter-content.jsx","/* eslint-env mozilla/frame-script */\n\nimport {actionCreators as ac, actionTypes as at, actionUtils as au} from \"common/Actions.jsm\";\nimport {applyMiddleware, combineReducers, createStore} from \"redux\";\n\nexport const MERGE_STORE_ACTION = \"NEW_TAB_INITIAL_STATE\";\nexport const OUTGOING_MESSAGE_NAME = \"ActivityStream:ContentToMain\";\nexport const INCOMING_MESSAGE_NAME = \"ActivityStream:MainToContent\";\nexport const EARLY_QUEUED_ACTIONS = [at.SAVE_SESSION_PERF_DATA, at.PAGE_PRERENDERED];\n\n/**\n * A higher-order function which returns a reducer that, on MERGE_STORE action,\n * will return the action.data object merged into the previous state.\n *\n * For all other actions, it merely calls mainReducer.\n *\n * Because we want this to merge the entire state object, it's written as a\n * higher order function which takes the main reducer (itself often a call to\n * combineReducers) as a parameter.\n *\n * @param  {function} mainReducer reducer to call if action != MERGE_STORE_ACTION\n * @return {function}             a reducer that, on MERGE_STORE_ACTION action,\n *                                will return the action.data object merged\n *                                into the previous state, and the result\n *                                of calling mainReducer otherwise.\n */\nfunction mergeStateReducer(mainReducer) {\n  return (prevState, action) => {\n    if (action.type === MERGE_STORE_ACTION) {\n      return {...prevState, ...action.data};\n    }\n\n    return mainReducer(prevState, action);\n  };\n}\n\n/**\n * messageMiddleware - Middleware that looks for SentToMain type actions, and sends them if necessary\n */\nconst messageMiddleware = store => next => action => {\n  const skipLocal = action.meta && action.meta.skipLocal;\n  if (au.isSendToMain(action)) {\n    sendAsyncMessage(OUTGOING_MESSAGE_NAME, action);\n  }\n  if (!skipLocal) {\n    next(action);\n  }\n};\n\nexport const rehydrationMiddleware = store => next => action => {\n  if (store._didRehydrate) {\n    return next(action);\n  }\n\n  const isMergeStoreAction = action.type === MERGE_STORE_ACTION;\n  const isRehydrationRequest = action.type === at.NEW_TAB_STATE_REQUEST;\n\n  if (isRehydrationRequest) {\n    store._didRequestInitialState = true;\n    return next(action);\n  }\n\n  if (isMergeStoreAction) {\n    store._didRehydrate = true;\n    return next(action);\n  }\n\n  // If init happened after our request was made, we need to re-request\n  if (store._didRequestInitialState && action.type === at.INIT) {\n    return next(ac.AlsoToMain({type: at.NEW_TAB_STATE_REQUEST}));\n  }\n\n  if (au.isBroadcastToContent(action) || au.isSendToOneContent(action) || au.isSendToPreloaded(action)) {\n    // Note that actions received before didRehydrate will not be dispatched\n    // because this could negatively affect preloading and the the state\n    // will be replaced by rehydration anyway.\n    return null;\n  }\n\n  return next(action);\n};\n\n/**\n * This middleware queues up all the EARLY_QUEUED_ACTIONS until it receives\n * the first action from main. This is useful for those actions for main which\n * require higher reliability, i.e. the action will not be lost in the case\n * that it gets sent before the main is ready to receive it. Conversely, any\n * actions allowed early are accepted to be ignorable or re-sendable.\n */\nexport const queueEarlyMessageMiddleware = store => next => action => {\n  if (store._receivedFromMain) {\n    next(action);\n  } else if (au.isFromMain(action)) {\n    next(action);\n    store._receivedFromMain = true;\n    // Sending out all the early actions as main is ready now\n    if (store._earlyActionQueue) {\n      store._earlyActionQueue.forEach(next);\n      store._earlyActionQueue = [];\n    }\n  } else if (EARLY_QUEUED_ACTIONS.includes(action.type)) {\n    store._earlyActionQueue = store._earlyActionQueue || [];\n    store._earlyActionQueue.push(action);\n  } else {\n    // Let any other type of action go through\n    next(action);\n  }\n};\n\n/**\n * initStore - Create a store and listen for incoming actions\n *\n * @param  {object} reducers An object containing Redux reducers\n * @param  {object} intialState (optional) The initial state of the store, if desired\n * @return {object}          A redux store\n */\nexport function initStore(reducers, initialState) {\n  const store = createStore(\n    mergeStateReducer(combineReducers(reducers)),\n    initialState,\n    global.addMessageListener && applyMiddleware(rehydrationMiddleware, queueEarlyMessageMiddleware, messageMiddleware)\n  );\n\n  store._didRehydrate = false;\n  store._didRequestInitialState = false;\n\n  if (global.addMessageListener) {\n    global.addMessageListener(INCOMING_MESSAGE_NAME, msg => {\n      try {\n        store.dispatch(msg.data);\n      } catch (ex) {\n        console.error(\"Content msg:\", msg, \"Dispatch error: \", ex); // eslint-disable-line no-console\n        dump(`Content msg: ${JSON.stringify(msg)}\\nDispatch error: ${ex}\\n${ex.stack}`);\n      }\n    });\n  }\n\n  return store;\n}\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/lib/init-store.js","module.exports = ReactDOM;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"ReactDOM\"\n// module id = 9\n// module chunks = 0","import {FormattedMessage} from \"react-intl\";\nimport React from \"react\";\n\nexport class ErrorBoundaryFallback extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.windowObj = this.props.windowObj || window;\n    this.onClick = this.onClick.bind(this);\n  }\n\n  /**\n   * Since we only get here if part of the page has crashed, do a\n   * forced reload to give us the best chance at recovering.\n   */\n  onClick() {\n    this.windowObj.location.reload(true);\n  }\n\n  render() {\n    const defaultClass = \"as-error-fallback\";\n    let className;\n    if (\"className\" in this.props) {\n      className = `${this.props.className} ${defaultClass}`;\n    } else {\n      className = defaultClass;\n    }\n\n    // href=\"#\" to force normal link styling stuff (eg cursor on hover)\n    return (\n      <div className={className}>\n        <div>\n          <FormattedMessage\n            defaultMessage=\"Oops, something went wrong loading this content.\"\n            id=\"error_fallback_default_info\" />\n        </div>\n        <span>\n          <a href=\"#\" className=\"reload-button\" onClick={this.onClick}>\n            <FormattedMessage\n              defaultMessage=\"Refresh page to try again.\"\n              id=\"error_fallback_default_refresh_suggestion\" />\n          </a>\n        </span>\n      </div>\n    );\n  }\n}\nErrorBoundaryFallback.defaultProps = {className: \"as-error-fallback\"};\n\nexport class ErrorBoundary extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.state = {hasError: false};\n  }\n\n  componentDidCatch(error, info) {\n    this.setState({hasError: true});\n  }\n\n  render() {\n    if (!this.state.hasError) {\n      return (this.props.children);\n    }\n\n    return <this.props.FallbackComponent className={this.props.className} />;\n  }\n}\n\nErrorBoundary.defaultProps = {FallbackComponent: ErrorBoundaryFallback};\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/ErrorBoundary/ErrorBoundary.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\n\nconst _OpenInPrivateWindow = site => ({\n  id: \"menu_action_open_private_window\",\n  icon: \"new-window-private\",\n  action: ac.OnlyToMain({\n    type: at.OPEN_PRIVATE_WINDOW,\n    data: {url: site.url, referrer: site.referrer}\n  }),\n  userEvent: \"OPEN_PRIVATE_WINDOW\"\n});\n\nexport const GetPlatformString = platform => {\n  switch (platform) {\n    case \"win\":\n      return \"menu_action_show_file_windows\";\n    case \"macosx\":\n      return \"menu_action_show_file_mac_os\";\n    case \"linux\":\n      return \"menu_action_show_file_linux\";\n    default:\n      return \"menu_action_show_file_default\";\n  }\n};\n\n/**\n * List of functions that return items that can be included as menu options in a\n * LinkMenu. All functions take the site as the first parameter, and optionally\n * the index of the site.\n */\nexport const LinkMenuOptions = {\n  Separator: () => ({type: \"separator\"}),\n  EmptyItem: () => ({type: \"empty\"}),\n  RemoveBookmark: site => ({\n    id: \"menu_action_remove_bookmark\",\n    icon: \"bookmark-added\",\n    action: ac.AlsoToMain({\n      type: at.DELETE_BOOKMARK_BY_ID,\n      data: site.bookmarkGuid\n    }),\n    userEvent: \"BOOKMARK_DELETE\"\n  }),\n  AddBookmark: site => ({\n    id: \"menu_action_bookmark\",\n    icon: \"bookmark-hollow\",\n    action: ac.AlsoToMain({\n      type: at.BOOKMARK_URL,\n      data: {url: site.url, title: site.title, type: site.type}\n    }),\n    userEvent: \"BOOKMARK_ADD\"\n  }),\n  OpenInNewWindow: site => ({\n    id: \"menu_action_open_new_window\",\n    icon: \"new-window\",\n    action: ac.AlsoToMain({\n      type: at.OPEN_NEW_WINDOW,\n      data: {\n        referrer: site.referrer,\n        typedBonus: site.typedBonus,\n        url: site.url\n      }\n    }),\n    userEvent: \"OPEN_NEW_WINDOW\"\n  }),\n  BlockUrl: (site, index, eventSource) => ({\n    id: \"menu_action_dismiss\",\n    icon: \"dismiss\",\n    action: ac.AlsoToMain({\n      type: at.BLOCK_URL,\n      data: {url: site.url, pocket_id: site.pocket_id}\n    }),\n    impression: ac.ImpressionStats({\n      source: eventSource,\n      block: 0,\n      tiles: [{id: site.guid, pos: index}]\n    }),\n    userEvent: \"BLOCK\"\n  }),\n\n  // This is an option for web extentions which will result in remove items from\n  // memory and notify the web extenion, rather than using the built-in block list.\n  WebExtDismiss: (site, index, eventSource) => ({\n    id: \"menu_action_webext_dismiss\",\n    string_id: \"menu_action_dismiss\",\n    icon: \"dismiss\",\n    action: ac.WebExtEvent(at.WEBEXT_DISMISS, {\n      source: eventSource,\n      url: site.url,\n      action_position: index\n    })\n  }),\n  DeleteUrl: (site, index, eventSource, isEnabled, siteInfo) => ({\n    id: \"menu_action_delete\",\n    icon: \"delete\",\n    action: {\n      type: at.DIALOG_OPEN,\n      data: {\n        onConfirm: [\n          ac.AlsoToMain({type: at.DELETE_HISTORY_URL, data: {url: site.url, pocket_id: site.pocket_id, forceBlock: site.bookmarkGuid}}),\n          ac.UserEvent(Object.assign({event: \"DELETE\", source: eventSource, action_position: index}, siteInfo))\n        ],\n        eventSource,\n        body_string_id: [\"confirm_history_delete_p1\", \"confirm_history_delete_notice_p2\"],\n        confirm_button_string_id: \"menu_action_delete\",\n        cancel_button_string_id: \"topsites_form_cancel_button\",\n        icon: \"modal-delete\"\n      }\n    },\n    userEvent: \"DIALOG_OPEN\"\n  }),\n  ShowFile: (site, index, eventSource, isEnabled, siteInfo, platform) => ({\n    id: GetPlatformString(platform),\n    icon: \"search\",\n    action: ac.OnlyToMain({\n      type: at.SHOW_DOWNLOAD_FILE,\n      data: {url: site.url}\n    })\n  }),\n  OpenFile: site => ({\n    id: \"menu_action_open_file\",\n    icon: \"open-file\",\n    action: ac.OnlyToMain({\n      type: at.OPEN_DOWNLOAD_FILE,\n      data: {url: site.url}\n    })\n  }),\n  CopyDownloadLink: site => ({\n    id: \"menu_action_copy_download_link\",\n    icon: \"copy\",\n    action: ac.OnlyToMain({\n      type: at.COPY_DOWNLOAD_LINK,\n      data: {url: site.url}\n    })\n  }),\n  GoToDownloadPage: site => ({\n    id: \"menu_action_go_to_download_page\",\n    icon: \"download\",\n    action: ac.OnlyToMain({\n      type: at.OPEN_LINK,\n      data: {url: site.referrer}\n    }),\n    disabled: !site.referrer\n  }),\n  RemoveDownload: site => ({\n    id: \"menu_action_remove_download\",\n    icon: \"delete\",\n    action: ac.OnlyToMain({\n      type: at.REMOVE_DOWNLOAD_FILE,\n      data: {url: site.url}\n    })\n  }),\n  PinTopSite: (site, index) => ({\n    id: \"menu_action_pin\",\n    icon: \"pin\",\n    action: ac.AlsoToMain({\n      type: at.TOP_SITES_PIN,\n      data: {site: {url: site.url}, index}\n    }),\n    userEvent: \"PIN\"\n  }),\n  UnpinTopSite: site => ({\n    id: \"menu_action_unpin\",\n    icon: \"unpin\",\n    action: ac.AlsoToMain({\n      type: at.TOP_SITES_UNPIN,\n      data: {site: {url: site.url}}\n    }),\n    userEvent: \"UNPIN\"\n  }),\n  SaveToPocket: (site, index, eventSource) => ({\n    id: \"menu_action_save_to_pocket\",\n    icon: \"pocket\",\n    action: ac.AlsoToMain({\n      type: at.SAVE_TO_POCKET,\n      data: {site: {url: site.url, title: site.title}}\n    }),\n    impression: ac.ImpressionStats({\n      source: eventSource,\n      pocket: 0,\n      tiles: [{id: site.guid, pos: index}]\n    }),\n    userEvent: \"SAVE_TO_POCKET\"\n  }),\n  DeleteFromPocket: site => ({\n    id: \"menu_action_delete_pocket\",\n    icon: \"delete\",\n    action: ac.AlsoToMain({\n      type: at.DELETE_FROM_POCKET,\n      data: {pocket_id: site.pocket_id}\n    }),\n    userEvent: \"DELETE_FROM_POCKET\"\n  }),\n  ArchiveFromPocket: site => ({\n    id: \"menu_action_archive_pocket\",\n    icon: \"check\",\n    action: ac.AlsoToMain({\n      type: at.ARCHIVE_FROM_POCKET,\n      data: {pocket_id: site.pocket_id}\n    }),\n    userEvent: \"ARCHIVE_FROM_POCKET\"\n  }),\n  EditTopSite: (site, index) => ({\n    id: \"edit_topsites_button_text\",\n    icon: \"edit\",\n    action: {\n      type: at.TOP_SITES_EDIT,\n      data: {index}\n    }\n  }),\n  CheckBookmark: site => (site.bookmarkGuid ? LinkMenuOptions.RemoveBookmark(site) : LinkMenuOptions.AddBookmark(site)),\n  CheckPinTopSite: (site, index) => (site.isPinned ? LinkMenuOptions.UnpinTopSite(site) : LinkMenuOptions.PinTopSite(site, index)),\n  CheckSavedToPocket: (site, index) => (site.pocket_id ? LinkMenuOptions.DeleteFromPocket(site) : LinkMenuOptions.SaveToPocket(site, index)),\n  CheckBookmarkOrArchive: site => (site.pocket_id ? LinkMenuOptions.ArchiveFromPocket(site) : LinkMenuOptions.CheckBookmark(site)),\n  OpenInPrivateWindow: (site, index, eventSource, isEnabled) => (isEnabled ? _OpenInPrivateWindow(site) : LinkMenuOptions.EmptyItem())\n};\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/lib/link-menu-options.js","import {actionCreators as ac} from \"common/Actions.jsm\";\nimport {connect} from \"react-redux\";\nimport {ContextMenu} from \"content-src/components/ContextMenu/ContextMenu\";\nimport {injectIntl} from \"react-intl\";\nimport {LinkMenuOptions} from \"content-src/lib/link-menu-options\";\nimport React from \"react\";\n\nconst DEFAULT_SITE_MENU_OPTIONS = [\"CheckPinTopSite\", \"EditTopSite\", \"Separator\", \"OpenInNewWindow\", \"OpenInPrivateWindow\", \"Separator\", \"BlockUrl\"];\n\nexport class _LinkMenu extends React.PureComponent {\n  getOptions() {\n    const {props} = this;\n    const {site, index, source, isPrivateBrowsingEnabled, siteInfo, platform} = props;\n\n    // Handle special case of default site\n    const propOptions = !site.isDefault ? props.options : DEFAULT_SITE_MENU_OPTIONS;\n\n    const options = propOptions.map(o => LinkMenuOptions[o](site, index, source, isPrivateBrowsingEnabled, siteInfo, platform)).map(option => {\n      const {action, impression, id, string_id, type, userEvent} = option;\n      if (!type && id) {\n        option.label = props.intl.formatMessage({id: string_id || id});\n        option.onClick = () => {\n          props.dispatch(action);\n          if (userEvent) {\n            const userEventData = Object.assign({\n              event: userEvent,\n              source,\n              action_position: index\n            }, siteInfo);\n            props.dispatch(ac.UserEvent(userEventData));\n          }\n          if (impression && props.shouldSendImpressionStats) {\n            props.dispatch(impression);\n          }\n        };\n      }\n      return option;\n    });\n\n    // This is for accessibility to support making each item tabbable.\n    // We want to know which item is the first and which item\n    // is the last, so we can close the context menu accordingly.\n    options[0].first = true;\n    options[options.length - 1].last = true;\n    return options;\n  }\n\n  render() {\n    return (<ContextMenu\n      onUpdate={this.props.onUpdate}\n      options={this.getOptions()} />);\n  }\n}\n\nconst getState = state => ({isPrivateBrowsingEnabled: state.Prefs.values.isPrivateBrowsingEnabled, platform: state.Prefs.values.platform});\nexport const LinkMenu = connect(getState)(injectIntl(_LinkMenu));\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/LinkMenu/LinkMenu.jsx","import React from \"react\";\n\nexport class ContextMenu extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.hideContext = this.hideContext.bind(this);\n    this.onClick = this.onClick.bind(this);\n  }\n\n  hideContext() {\n    this.props.onUpdate(false);\n  }\n\n  componentDidMount() {\n    setTimeout(() => {\n      global.addEventListener(\"click\", this.hideContext);\n    }, 0);\n  }\n\n  componentWillUnmount() {\n    global.removeEventListener(\"click\", this.hideContext);\n  }\n\n  onClick(event) {\n    // Eat all clicks on the context menu so they don't bubble up to window.\n    // This prevents the context menu from closing when clicking disabled items\n    // or the separators.\n    event.stopPropagation();\n  }\n\n  render() {\n    return (<span className=\"context-menu\" onClick={this.onClick}>\n      <ul role=\"menu\" className=\"context-menu-list\">\n        {this.props.options.map((option, i) => (option.type === \"separator\" ?\n          (<li key={i} className=\"separator\" />) :\n          (option.type !== \"empty\" && <ContextMenuItem key={i} option={option} hideContext={this.hideContext} />)\n        ))}\n      </ul>\n    </span>);\n  }\n}\n\nexport class ContextMenuItem extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onClick = this.onClick.bind(this);\n    this.onKeyDown = this.onKeyDown.bind(this);\n  }\n\n  onClick() {\n    this.props.hideContext();\n    this.props.option.onClick();\n  }\n\n  onKeyDown(event) {\n    const {option} = this.props;\n    switch (event.key) {\n      case \"Tab\":\n        // tab goes down in context menu, shift + tab goes up in context menu\n        // if we're on the last item, one more tab will close the context menu\n        // similarly, if we're on the first item, one more shift + tab will close it\n        if ((event.shiftKey && option.first) || (!event.shiftKey && option.last)) {\n          this.props.hideContext();\n        }\n        break;\n      case \"Enter\":\n        this.props.hideContext();\n        option.onClick();\n        break;\n    }\n  }\n\n  render() {\n    const {option} = this.props;\n    return (\n      <li role=\"menuitem\" className=\"context-menu-item\">\n        <a onClick={this.onClick} onKeyDown={this.onKeyDown} tabIndex=\"0\" className={option.disabled ? \"disabled\" : \"\"}>\n          {option.icon && <span className={`icon icon-spacer icon-${option.icon}`} />}\n          {option.label}\n        </a>\n      </li>);\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/ContextMenu/ContextMenu.jsx","import {FormattedMessage, injectIntl} from \"react-intl\";\nimport {actionCreators as ac} from \"common/Actions.jsm\";\nimport {ErrorBoundary} from \"content-src/components/ErrorBoundary/ErrorBoundary\";\nimport React from \"react\";\nimport {SectionMenu} from \"content-src/components/SectionMenu/SectionMenu\";\nimport {SectionMenuOptions} from \"content-src/lib/section-menu-options\";\n\nconst VISIBLE = \"visible\";\nconst VISIBILITY_CHANGE_EVENT = \"visibilitychange\";\n\nfunction getFormattedMessage(message) {\n  return typeof message === \"string\" ? <span>{message}</span> : <FormattedMessage {...message} />;\n}\n\nexport class Disclaimer extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onAcknowledge = this.onAcknowledge.bind(this);\n  }\n\n  onAcknowledge() {\n    this.props.dispatch(ac.SetPref(this.props.disclaimerPref, false));\n    this.props.dispatch(ac.UserEvent({event: \"DISCLAIMER_ACKED\", source: this.props.eventSource}));\n  }\n\n  render() {\n    const {disclaimer} = this.props;\n    return (\n      <div className=\"section-disclaimer\">\n          <div className=\"section-disclaimer-text\">\n            {getFormattedMessage(disclaimer.text)}\n            {disclaimer.link &&\n              <a href={disclaimer.link.href} target=\"_blank\" rel=\"noopener noreferrer\">\n                {getFormattedMessage(disclaimer.link.title || disclaimer.link)}\n              </a>\n            }\n          </div>\n\n          <button onClick={this.onAcknowledge}>\n            {getFormattedMessage(disclaimer.button)}\n          </button>\n      </div>\n    );\n  }\n}\n\nexport const DisclaimerIntl = injectIntl(Disclaimer);\n\nexport class _CollapsibleSection extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onBodyMount = this.onBodyMount.bind(this);\n    this.onHeaderClick = this.onHeaderClick.bind(this);\n    this.onTransitionEnd = this.onTransitionEnd.bind(this);\n    this.enableOrDisableAnimation = this.enableOrDisableAnimation.bind(this);\n    this.onMenuButtonClick = this.onMenuButtonClick.bind(this);\n    this.onMenuButtonMouseEnter = this.onMenuButtonMouseEnter.bind(this);\n    this.onMenuButtonMouseLeave = this.onMenuButtonMouseLeave.bind(this);\n    this.onMenuUpdate = this.onMenuUpdate.bind(this);\n    this.state = {enableAnimation: true, isAnimating: false, menuButtonHover: false, showContextMenu: false};\n  }\n\n  componentWillMount() {\n    this.props.document.addEventListener(VISIBILITY_CHANGE_EVENT, this.enableOrDisableAnimation);\n  }\n\n  componentWillUpdate(nextProps) {\n    // Check if we're about to go from expanded to collapsed\n    if (!this.props.collapsed && nextProps.collapsed) {\n      // This next line forces a layout flush of the section body, which has a\n      // max-height style set, so that the upcoming collapse animation can\n      // animate from that height to the collapsed height. Without this, the\n      // update is coalesced and there's no animation from no-max-height to 0.\n      this.sectionBody.scrollHeight; // eslint-disable-line no-unused-expressions\n    }\n  }\n\n  componentWillUnmount() {\n    this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this.enableOrDisableAnimation);\n  }\n\n  enableOrDisableAnimation() {\n    // Only animate the collapse/expand for visible tabs.\n    const visible = this.props.document.visibilityState === VISIBLE;\n    if (this.state.enableAnimation !== visible) {\n      this.setState({enableAnimation: visible});\n    }\n  }\n\n  onBodyMount(node) {\n    this.sectionBody = node;\n  }\n\n  onHeaderClick() {\n    // If this.sectionBody is unset, it means that we're in some sort of error\n    // state, probably displaying the error fallback, so we won't be able to\n    // compute the height, and we don't want to persist the preference.\n    // If props.collapsed is undefined handler shouldn't do anything.\n    if (!this.sectionBody || this.props.collapsed === undefined) {\n      return;\n    }\n\n    // Get the current height of the body so max-height transitions can work\n    this.setState({\n      isAnimating: true,\n      maxHeight: `${this.sectionBody.scrollHeight}px`\n    });\n    const {action, userEvent} = SectionMenuOptions.CheckCollapsed(this.props);\n    this.props.dispatch(action);\n    this.props.dispatch(ac.UserEvent({\n      event: userEvent,\n      source: this.props.source\n    }));\n  }\n\n  onTransitionEnd(event) {\n    // Only update the animating state for our own transition (not a child's)\n    if (event.target === event.currentTarget) {\n      this.setState({isAnimating: false});\n    }\n  }\n\n  renderIcon() {\n    const {icon} = this.props;\n    if (icon && icon.startsWith(\"moz-extension://\")) {\n      return <span className=\"icon icon-small-spacer\" style={{backgroundImage: `url('${icon}')`}} />;\n    }\n    return <span className={`icon icon-small-spacer icon-${icon || \"webextension\"}`} />;\n  }\n\n  onMenuButtonClick(event) {\n    event.preventDefault();\n    this.setState({showContextMenu: true});\n  }\n\n  onMenuButtonMouseEnter() {\n    this.setState({menuButtonHover: true});\n  }\n\n  onMenuButtonMouseLeave() {\n    this.setState({menuButtonHover: false});\n  }\n\n  onMenuUpdate(showContextMenu) {\n    this.setState({showContextMenu});\n  }\n\n  render() {\n    const isCollapsible = this.props.collapsed !== undefined;\n    const {enableAnimation, isAnimating, maxHeight, menuButtonHover, showContextMenu} = this.state;\n    const {id, eventSource, collapsed, disclaimer, title, extraMenuOptions, showPrefName, privacyNoticeURL, dispatch, isFirst, isLast, isWebExtension} = this.props;\n    const disclaimerPref = `section.${id}.showDisclaimer`;\n    const needsDisclaimer = disclaimer && this.props.Prefs.values[disclaimerPref];\n    const active = menuButtonHover || showContextMenu;\n    return (\n      <section\n        className={`collapsible-section ${this.props.className}${enableAnimation ? \" animation-enabled\" : \"\"}${collapsed ? \" collapsed\" : \"\"}${active ? \" active\" : \"\"}`}\n        // Note: data-section-id is used for web extension api tests in mozilla central\n        data-section-id={id}>\n        <div className=\"section-top-bar\">\n          <h3 className=\"section-title\">\n            <span className=\"click-target\" onClick={this.onHeaderClick}>\n              {this.renderIcon()}\n              {getFormattedMessage(title)}\n              {isCollapsible && <span className={`collapsible-arrow icon ${collapsed ? \"icon-arrowhead-forward-small\" : \"icon-arrowhead-down-small\"}`} />}\n            </span>\n          </h3>\n          <div>\n            <button\n              className=\"context-menu-button icon\"\n              onClick={this.onMenuButtonClick}\n              onMouseEnter={this.onMenuButtonMouseEnter}\n              onMouseLeave={this.onMenuButtonMouseLeave}>\n              <span className=\"sr-only\">\n                <FormattedMessage id=\"section_context_menu_button_sr\" />\n              </span>\n            </button>\n            {showContextMenu &&\n              <SectionMenu\n                id={id}\n                extraOptions={extraMenuOptions}\n                eventSource={eventSource}\n                showPrefName={showPrefName}\n                privacyNoticeURL={privacyNoticeURL}\n                collapsed={collapsed}\n                onUpdate={this.onMenuUpdate}\n                isFirst={isFirst}\n                isLast={isLast}\n                dispatch={dispatch}\n                isWebExtension={isWebExtension} />\n            }\n          </div>\n        </div>\n        <ErrorBoundary className=\"section-body-fallback\">\n          <div\n            className={`section-body${isAnimating ? \" animating\" : \"\"}`}\n            onTransitionEnd={this.onTransitionEnd}\n            ref={this.onBodyMount}\n            style={isAnimating && !collapsed ? {maxHeight} : null}>\n            {needsDisclaimer && <DisclaimerIntl disclaimerPref={disclaimerPref} disclaimer={disclaimer} eventSource={eventSource} dispatch={this.props.dispatch} />}\n            {this.props.children}\n          </div>\n        </ErrorBoundary>\n      </section>\n    );\n  }\n}\n\n_CollapsibleSection.defaultProps = {\n  document: global.document || {\n    addEventListener: () => {},\n    removeEventListener: () => {},\n    visibilityState: \"hidden\"\n  },\n  Prefs: {values: {}}\n};\n\nexport const CollapsibleSection = injectIntl(_CollapsibleSection);\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/CollapsibleSection/CollapsibleSection.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\n\n/**\n * List of functions that return items that can be included as menu options in a\n * SectionMenu. All functions take the section as the only parameter.\n */\nexport const SectionMenuOptions = {\n  Separator: () => ({type: \"separator\"}),\n  MoveUp: section => ({\n    id: \"section_menu_action_move_up\",\n    icon: \"arrowhead-up\",\n    action: ac.OnlyToMain({\n      type: at.SECTION_MOVE,\n      data: {id: section.id, direction: -1}\n    }),\n    userEvent: \"MENU_MOVE_UP\",\n    disabled: !!section.isFirst\n  }),\n  MoveDown: section => ({\n    id: \"section_menu_action_move_down\",\n    icon: \"arrowhead-down\",\n    action: ac.OnlyToMain({\n      type: at.SECTION_MOVE,\n      data: {id: section.id, direction: +1}\n    }),\n    userEvent: \"MENU_MOVE_DOWN\",\n    disabled: !!section.isLast\n  }),\n  RemoveSection: section => ({\n    id: \"section_menu_action_remove_section\",\n    icon: \"dismiss\",\n    action: ac.SetPref(section.showPrefName, false),\n    userEvent: \"MENU_REMOVE\"\n  }),\n  CollapseSection: section => ({\n    id: \"section_menu_action_collapse_section\",\n    icon: \"minimize\",\n    action: ac.OnlyToMain({type: at.UPDATE_SECTION_PREFS, data: {id: section.id, value: {collapsed: true}}}),\n    userEvent: \"MENU_COLLAPSE\"\n  }),\n  ExpandSection: section => ({\n    id: \"section_menu_action_expand_section\",\n    icon: \"maximize\",\n    action: ac.OnlyToMain({type: at.UPDATE_SECTION_PREFS, data: {id: section.id, value: {collapsed: false}}}),\n    userEvent: \"MENU_EXPAND\"\n  }),\n  ManageSection: section => ({\n    id: \"section_menu_action_manage_section\",\n    icon: \"settings\",\n    action: ac.OnlyToMain({type: at.SETTINGS_OPEN}),\n    userEvent: \"MENU_MANAGE\"\n  }),\n  ManageWebExtension: section => ({\n    id: \"section_menu_action_manage_webext\",\n    icon: \"settings\",\n    action: ac.OnlyToMain({type: at.OPEN_WEBEXT_SETTINGS, data: section.id})\n  }),\n  AddTopSite: section => ({\n    id: \"section_menu_action_add_topsite\",\n    icon: \"add\",\n    action: {type: at.TOP_SITES_EDIT, data: {index: -1}},\n    userEvent: \"MENU_ADD_TOPSITE\"\n  }),\n  PrivacyNotice: section => ({\n    id: \"section_menu_action_privacy_notice\",\n    icon: \"info\",\n    action: ac.OnlyToMain({\n      type: at.OPEN_LINK,\n      data: {url: section.privacyNoticeURL}\n    }),\n    userEvent: \"MENU_PRIVACY_NOTICE\"\n  }),\n  CheckCollapsed: section => (section.collapsed ? SectionMenuOptions.ExpandSection(section) : SectionMenuOptions.CollapseSection(section))\n};\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/lib/section-menu-options.js","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {perfService as perfSvc} from \"common/PerfService.jsm\";\nimport React from \"react\";\n\n// Currently record only a fixed set of sections. This will prevent data\n// from custom sections from showing up or from topstories.\nconst RECORDED_SECTIONS = [\"highlights\", \"topsites\"];\n\nexport class ComponentPerfTimer extends React.Component {\n  constructor(props) {\n    super(props);\n    // Just for test dependency injection:\n    this.perfSvc = this.props.perfSvc || perfSvc;\n\n    this._sendBadStateEvent = this._sendBadStateEvent.bind(this);\n    this._sendPaintedEvent = this._sendPaintedEvent.bind(this);\n    this._reportMissingData = false;\n    this._timestampHandled = false;\n    this._recordedFirstRender = false;\n  }\n\n  componentDidMount() {\n    if (!RECORDED_SECTIONS.includes(this.props.id)) {\n      return;\n    }\n\n    this._maybeSendPaintedEvent();\n  }\n\n  componentDidUpdate() {\n    if (!RECORDED_SECTIONS.includes(this.props.id)) {\n      return;\n    }\n\n    this._maybeSendPaintedEvent();\n  }\n\n  /**\n   * Call the given callback after the upcoming frame paints.\n   *\n   * @note Both setTimeout and requestAnimationFrame are throttled when the page\n   * is hidden, so this callback may get called up to a second or so after the\n   * requestAnimationFrame \"paint\" for hidden tabs.\n   *\n   * Newtabs hidden while loading will presumably be fairly rare (other than\n   * preloaded tabs, which we will be filtering out on the server side), so such\n   * cases should get lost in the noise.\n   *\n   * If we decide that it's important to find out when something that's hidden\n   * has \"painted\", however, another option is to post a message to this window.\n   * That should happen even faster than setTimeout, and, at least as of this\n   * writing, it's not throttled in hidden windows in Firefox.\n   *\n   * @param {Function} callback\n   *\n   * @returns void\n   */\n  _afterFramePaint(callback) {\n    requestAnimationFrame(() => setTimeout(callback, 0));\n  }\n\n  _maybeSendBadStateEvent() {\n    // Follow up bugs:\n    // https://github.com/mozilla/activity-stream/issues/3691\n    if (!this.props.initialized) {\n      // Remember to report back when data is available.\n      this._reportMissingData = true;\n    } else if (this._reportMissingData) {\n      this._reportMissingData = false;\n      // Report how long it took for component to become initialized.\n      this._sendBadStateEvent();\n    }\n  }\n\n  _maybeSendPaintedEvent() {\n    // If we've already handled a timestamp, don't do it again.\n    if (this._timestampHandled || !this.props.initialized) {\n      return;\n    }\n\n    // And if we haven't, we're doing so now, so remember that. Even if\n    // something goes wrong in the callback, we can't try again, as we'd be\n    // sending back the wrong data, and we have to do it here, so that other\n    // calls to this method while waiting for the next frame won't also try to\n    // handle it.\n    this._timestampHandled = true;\n    this._afterFramePaint(this._sendPaintedEvent);\n  }\n\n  /**\n   * Triggered by call to render. Only first call goes through due to\n   * `_recordedFirstRender`.\n   */\n  _ensureFirstRenderTsRecorded() {\n    // Used as t0 for recording how long component took to initialize.\n    if (!this._recordedFirstRender) {\n      this._recordedFirstRender = true;\n      // topsites_first_render_ts, highlights_first_render_ts.\n      const key = `${this.props.id}_first_render_ts`;\n      this.perfSvc.mark(key);\n    }\n  }\n\n  /**\n   * Creates `TELEMETRY_UNDESIRED_EVENT` with timestamp in ms\n   * of how much longer the data took to be ready for display than it would\n   * have been the ideal case.\n   * https://github.com/mozilla/ping-centre/issues/98\n   */\n  _sendBadStateEvent() {\n    // highlights_data_ready_ts, topsites_data_ready_ts.\n    const dataReadyKey = `${this.props.id}_data_ready_ts`;\n    this.perfSvc.mark(dataReadyKey);\n\n    try {\n      const firstRenderKey = `${this.props.id}_first_render_ts`;\n      // value has to be Int32.\n      const value = parseInt(this.perfSvc.getMostRecentAbsMarkStartByName(dataReadyKey) -\n                             this.perfSvc.getMostRecentAbsMarkStartByName(firstRenderKey), 10);\n      this.props.dispatch(ac.OnlyToMain({\n        type: at.SAVE_SESSION_PERF_DATA,\n        // highlights_data_late_by_ms, topsites_data_late_by_ms.\n        data: {[`${this.props.id}_data_late_by_ms`]: value}\n      }));\n    } catch (ex) {\n      // If this failed, it's likely because the `privacy.resistFingerprinting`\n      // pref is true.\n    }\n  }\n\n  _sendPaintedEvent() {\n    // Record first_painted event but only send if topsites.\n    if (this.props.id !== \"topsites\") {\n      return;\n    }\n\n    // topsites_first_painted_ts.\n    const key = `${this.props.id}_first_painted_ts`;\n    this.perfSvc.mark(key);\n\n    try {\n      const data = {};\n      data[key] = this.perfSvc.getMostRecentAbsMarkStartByName(key);\n\n      this.props.dispatch(ac.OnlyToMain({\n        type: at.SAVE_SESSION_PERF_DATA,\n        data\n      }));\n    } catch (ex) {\n      // If this failed, it's likely because the `privacy.resistFingerprinting`\n      // pref is true.  We should at least not blow up, and should continue\n      // to set this._timestampHandled to avoid going through this again.\n    }\n  }\n\n  render() {\n    if (RECORDED_SECTIONS.includes(this.props.id)) {\n      this._ensureFirstRenderTsRecorded();\n      this._maybeSendBadStateEvent();\n    }\n    return this.props.children;\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/ComponentPerfTimer/ComponentPerfTimer.jsx","/* globals Services */\n\"use strict\";\n\n/* istanbul ignore if */\nif (typeof ChromeUtils !== \"undefined\") {\n  ChromeUtils.import(\"resource://gre/modules/Services.jsm\");\n}\n\nlet usablePerfObj;\n\n/* istanbul ignore if */\n/* istanbul ignore else */\nif (typeof Services !== \"undefined\") {\n  // Borrow the high-resolution timer from the hidden window....\n  usablePerfObj = Services.appShell.hiddenDOMWindow.performance;\n} else if (typeof performance !== \"undefined\") {\n  // we must be running in content space\n  // eslint-disable-next-line no-undef\n  usablePerfObj = performance;\n} else {\n  // This is a dummy object so this file doesn't crash in the node prerendering\n  // task.\n  usablePerfObj = {\n    now() {},\n    mark() {}\n  };\n}\n\nfunction _PerfService(options) {\n  // For testing, so that we can use a fake Window.performance object with\n  // known state.\n  if (options && options.performanceObj) {\n    this._perf = options.performanceObj;\n  } else {\n    this._perf = usablePerfObj;\n  }\n}\n\n_PerfService.prototype = {\n  /**\n   * Calls the underlying mark() method on the appropriate Window.performance\n   * object to add a mark with the given name to the appropriate performance\n   * timeline.\n   *\n   * @param  {String} name  the name to give the current mark\n   * @return {void}\n   */\n  mark: function mark(str) {\n    this._perf.mark(str);\n  },\n\n  /**\n   * Calls the underlying getEntriesByName on the appropriate Window.performance\n   * object.\n   *\n   * @param  {String} name\n   * @param  {String} type eg \"mark\"\n   * @return {Array}       Performance* objects\n   */\n  getEntriesByName: function getEntriesByName(name, type) {\n    return this._perf.getEntriesByName(name, type);\n  },\n\n  /**\n   * The timeOrigin property from the appropriate performance object.\n   * Used to ensure that timestamps from the add-on code and the content code\n   * are comparable.\n   *\n   * @note If this is called from a context without a window\n   * (eg a JSM in chrome), it will return the timeOrigin of the XUL hidden\n   * window, which appears to be the first created window (and thus\n   * timeOrigin) in the browser.  Note also, however, there is also a private\n   * hidden window, presumably for private browsing, which appears to be\n   * created dynamically later.  Exactly how/when that shows up needs to be\n   * investigated.\n   *\n   * @return {Number} A double of milliseconds with a precision of 0.5us.\n   */\n  get timeOrigin() {\n    return this._perf.timeOrigin;\n  },\n\n  /**\n   * Returns the \"absolute\" version of performance.now(), i.e. one that\n   * should ([bug 1401406](https://bugzilla.mozilla.org/show_bug.cgi?id=1401406)\n   * be comparable across both chrome and content.\n   *\n   * @return {Number}\n   */\n  absNow: function absNow() {\n    return this.timeOrigin + this._perf.now();\n  },\n\n  /**\n   * This returns the absolute startTime from the most recent performance.mark()\n   * with the given name.\n   *\n   * @param  {String} name  the name to lookup the start time for\n   *\n   * @return {Number}       the returned start time, as a DOMHighResTimeStamp\n   *\n   * @throws {Error}        \"No Marks with the name ...\" if none are available\n   *\n   * @note Always surround calls to this by try/catch.  Otherwise your code\n   * may fail when the `privacy.resistFingerprinting` pref is true.  When\n   * this pref is set, all attempts to get marks will likely fail, which will\n   * cause this method to throw.\n   *\n   * See [bug 1369303](https://bugzilla.mozilla.org/show_bug.cgi?id=1369303)\n   * for more info.\n   */\n  getMostRecentAbsMarkStartByName(name) {\n    let entries = this.getEntriesByName(name, \"mark\");\n\n    if (!entries.length) {\n      throw new Error(`No marks with the name ${name}`);\n    }\n\n    let mostRecentEntry = entries[entries.length - 1];\n    return this._perf.timeOrigin + mostRecentEntry.startTime;\n  }\n};\n\nthis.perfService = new _PerfService();\nconst EXPORTED_SYMBOLS = [\"_PerfService\", \"perfService\"];\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/common/PerfService.jsm","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {FormattedMessage, injectIntl} from \"react-intl\";\nimport {\n  MIN_CORNER_FAVICON_SIZE,\n  MIN_RICH_FAVICON_SIZE,\n  TOP_SITES_CONTEXT_MENU_OPTIONS,\n  TOP_SITES_SOURCE\n} from \"./TopSitesConstants\";\nimport {LinkMenu} from \"content-src/components/LinkMenu/LinkMenu\";\nimport React from \"react\";\nimport {TOP_SITES_MAX_SITES_PER_ROW} from \"common/Reducers.jsm\";\n\nexport class TopSiteLink extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onDragEvent = this.onDragEvent.bind(this);\n  }\n\n  /*\n   * Helper to determine whether the drop zone should allow a drop. We only allow\n   * dropping top sites for now.\n   */\n  _allowDrop(e) {\n    return e.dataTransfer.types.includes(\"text/topsite-index\");\n  }\n\n  onDragEvent(event) {\n    switch (event.type) {\n      case \"click\":\n        // Stop any link clicks if we started any dragging\n        if (this.dragged) {\n          event.preventDefault();\n        }\n        break;\n      case \"dragstart\":\n        this.dragged = true;\n        event.dataTransfer.effectAllowed = \"move\";\n        event.dataTransfer.setData(\"text/topsite-index\", this.props.index);\n        event.target.blur();\n        this.props.onDragEvent(event, this.props.index, this.props.link, this.props.title);\n        break;\n      case \"dragend\":\n        this.props.onDragEvent(event);\n        break;\n      case \"dragenter\":\n      case \"dragover\":\n      case \"drop\":\n        if (this._allowDrop(event)) {\n          event.preventDefault();\n          this.props.onDragEvent(event, this.props.index);\n        }\n        break;\n      case \"mousedown\":\n        // Reset at the first mouse event of a potential drag\n        this.dragged = false;\n        break;\n    }\n  }\n\n  render() {\n    const {children, className, defaultStyle, isDraggable, link, onClick, title} = this.props;\n    const topSiteOuterClassName = `top-site-outer${className ? ` ${className}` : \"\"}${link.isDragged ? \" dragged\" : \"\"}`;\n    const {tippyTopIcon, faviconSize} = link;\n    const [letterFallback] = title;\n    let imageClassName;\n    let imageStyle;\n    let showSmallFavicon = false;\n    let smallFaviconStyle;\n    let smallFaviconFallback;\n    if (defaultStyle) { // force no styles (letter fallback) even if the link has imagery\n      smallFaviconFallback = false;\n    } else if (link.customScreenshotURL) {\n      // assume high quality custom screenshot and use rich icon styles and class names\n      imageClassName = \"top-site-icon rich-icon\";\n      imageStyle = {\n        backgroundColor: link.backgroundColor,\n        backgroundImage: `url(${link.screenshot})`\n      };\n    } else if (tippyTopIcon || faviconSize >= MIN_RICH_FAVICON_SIZE) {\n      // styles and class names for top sites with rich icons\n      imageClassName = \"top-site-icon rich-icon\";\n      imageStyle = {\n        backgroundColor: link.backgroundColor,\n        backgroundImage: `url(${tippyTopIcon || link.favicon})`\n      };\n    } else {\n      // styles and class names for top sites with screenshot + small icon in top left corner\n      imageClassName = `screenshot${link.screenshot ? \" active\" : \"\"}`;\n      imageStyle = {backgroundImage: link.screenshot ? `url(${link.screenshot})` : \"none\"};\n\n      // only show a favicon in top left if it's greater than 16x16\n      if (faviconSize >= MIN_CORNER_FAVICON_SIZE) {\n        showSmallFavicon = true;\n        smallFaviconStyle = {backgroundImage:  `url(${link.favicon})`};\n      } else if (link.screenshot) {\n        // Don't show a small favicon if there is no screenshot, because that\n        // would result in two fallback icons\n        showSmallFavicon = true;\n        smallFaviconFallback = true;\n      }\n    }\n    let draggableProps = {};\n    if (isDraggable) {\n      draggableProps = {\n        onClick: this.onDragEvent,\n        onDragEnd: this.onDragEvent,\n        onDragStart: this.onDragEvent,\n        onMouseDown: this.onDragEvent\n      };\n    }\n    return (<li className={topSiteOuterClassName} onDrop={this.onDragEvent} onDragOver={this.onDragEvent} onDragEnter={this.onDragEvent} onDragLeave={this.onDragEvent} {...draggableProps}>\n      <div className=\"top-site-inner\">\n         <a href={link.url} onClick={onClick}>\n            <div className=\"tile\" aria-hidden={true} data-fallback={letterFallback}>\n              <div className={imageClassName} style={imageStyle} />\n              {showSmallFavicon && <div\n                className=\"top-site-icon default-icon\"\n                data-fallback={smallFaviconFallback && letterFallback}\n                style={smallFaviconStyle} />}\n           </div>\n           <div className={`title ${link.isPinned ? \"pinned\" : \"\"}`}>\n             {link.isPinned && <div className=\"icon icon-pin-small\" />}\n              <span dir=\"auto\">{title}</span>\n           </div>\n         </a>\n         {children}\n      </div>\n    </li>);\n  }\n}\nTopSiteLink.defaultProps = {\n  title: \"\",\n  link: {},\n  isDraggable: true\n};\n\nexport class TopSite extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.state = {showContextMenu: false};\n    this.onLinkClick = this.onLinkClick.bind(this);\n    this.onMenuButtonClick = this.onMenuButtonClick.bind(this);\n    this.onMenuUpdate = this.onMenuUpdate.bind(this);\n  }\n\n  /**\n   * Report to telemetry additional information about the item.\n   */\n  _getTelemetryInfo() {\n    const value = {icon_type: this.props.link.iconType};\n    // Filter out \"not_pinned\" type for being the default\n    if (this.props.link.isPinned) {\n      value.card_type = \"pinned\";\n    }\n    return {value};\n  }\n\n  userEvent(event) {\n    this.props.dispatch(ac.UserEvent(Object.assign({\n      event,\n      source: TOP_SITES_SOURCE,\n      action_position: this.props.index\n    }, this._getTelemetryInfo())));\n  }\n\n  onLinkClick(event) {\n    this.userEvent(\"CLICK\");\n\n    // Specially handle a top site link click for \"typed\" frecency bonus as\n    // specified as a property on the link.\n    event.preventDefault();\n    const {altKey, button, ctrlKey, metaKey, shiftKey} = event;\n    this.props.dispatch(ac.OnlyToMain({\n      type: at.OPEN_LINK,\n      data: Object.assign(this.props.link, {event: {altKey, button, ctrlKey, metaKey, shiftKey}})\n    }));\n  }\n\n  onMenuButtonClick(event) {\n    event.preventDefault();\n    this.props.onActivate(this.props.index);\n    this.setState({showContextMenu: true});\n  }\n\n  onMenuUpdate(showContextMenu) {\n    this.setState({showContextMenu});\n  }\n\n  render() {\n    const {props} = this;\n    const {link} = props;\n    const isContextMenuOpen = this.state.showContextMenu && props.activeIndex === props.index;\n    const title = link.label || link.hostname;\n    return (<TopSiteLink {...props} onClick={this.onLinkClick} onDragEvent={this.props.onDragEvent} className={`${props.className || \"\"}${isContextMenuOpen ? \" active\" : \"\"}`} title={title}>\n        <div>\n          <button className=\"context-menu-button icon\" onClick={this.onMenuButtonClick}>\n            <span className=\"sr-only\">\n              <FormattedMessage id=\"context_menu_button_sr\" values={{title}} />\n            </span>\n          </button>\n          {isContextMenuOpen &&\n            <LinkMenu\n              dispatch={props.dispatch}\n              index={props.index}\n              onUpdate={this.onMenuUpdate}\n              options={TOP_SITES_CONTEXT_MENU_OPTIONS}\n              site={link}\n              siteInfo={this._getTelemetryInfo()}\n              source={TOP_SITES_SOURCE} />\n          }\n        </div>\n    </TopSiteLink>);\n  }\n}\nTopSite.defaultProps = {\n  link: {},\n  onActivate() {}\n};\n\nexport class TopSitePlaceholder extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onEditButtonClick = this.onEditButtonClick.bind(this);\n  }\n\n  onEditButtonClick() {\n    this.props.dispatch(\n      {type: at.TOP_SITES_EDIT, data: {index: this.props.index}});\n  }\n\n  render() {\n    return (<TopSiteLink {...this.props} className={`placeholder ${this.props.className || \"\"}`} isDraggable={false}>\n      <button className=\"context-menu-button edit-button icon\"\n       title={this.props.intl.formatMessage({id: \"edit_topsites_edit_button\"})}\n       onClick={this.onEditButtonClick} />\n    </TopSiteLink>);\n  }\n}\n\nexport class _TopSiteList extends React.PureComponent {\n  static get DEFAULT_STATE() {\n    return {\n      activeIndex: null,\n      draggedIndex: null,\n      draggedSite: null,\n      draggedTitle: null,\n      topSitesPreview: null\n    };\n  }\n\n  constructor(props) {\n    super(props);\n    this.state = _TopSiteList.DEFAULT_STATE;\n    this.onDragEvent = this.onDragEvent.bind(this);\n    this.onActivate = this.onActivate.bind(this);\n  }\n\n  componentWillReceiveProps(nextProps) {\n    if (this.state.draggedSite) {\n      const prevTopSites = this.props.TopSites && this.props.TopSites.rows;\n      const newTopSites = nextProps.TopSites && nextProps.TopSites.rows;\n      if (prevTopSites && prevTopSites[this.state.draggedIndex] &&\n        prevTopSites[this.state.draggedIndex].url === this.state.draggedSite.url &&\n        (!newTopSites[this.state.draggedIndex] || newTopSites[this.state.draggedIndex].url !== this.state.draggedSite.url)) {\n        // We got the new order from the redux store via props. We can clear state now.\n        this.setState(_TopSiteList.DEFAULT_STATE);\n      }\n    }\n  }\n\n  userEvent(event, index) {\n    this.props.dispatch(ac.UserEvent({\n      event,\n      source: TOP_SITES_SOURCE,\n      action_position: index\n    }));\n  }\n\n  onDragEvent(event, index, link, title) {\n    switch (event.type) {\n      case \"dragstart\":\n        this.dropped = false;\n        this.setState({\n          draggedIndex: index,\n          draggedSite: link,\n          draggedTitle: title,\n          activeIndex: null\n        });\n        this.userEvent(\"DRAG\", index);\n        break;\n      case \"dragend\":\n        if (!this.dropped) {\n          // If there was no drop event, reset the state to the default.\n          this.setState(_TopSiteList.DEFAULT_STATE);\n        }\n        break;\n      case \"dragenter\":\n        if (index === this.state.draggedIndex) {\n          this.setState({topSitesPreview: null});\n        } else {\n          this.setState({topSitesPreview: this._makeTopSitesPreview(index)});\n        }\n        break;\n      case \"drop\":\n        if (index !== this.state.draggedIndex) {\n          this.dropped = true;\n          this.props.dispatch(ac.AlsoToMain({\n            type: at.TOP_SITES_INSERT,\n            data: {\n              site: {\n                url: this.state.draggedSite.url,\n                label: this.state.draggedTitle,\n                customScreenshotURL: this.state.draggedSite.customScreenshotURL\n              },\n              index,\n              draggedFromIndex: this.state.draggedIndex\n            }\n          }));\n          this.userEvent(\"DROP\", index);\n        }\n        break;\n    }\n  }\n\n  _getTopSites() {\n    // Make a copy of the sites to truncate or extend to desired length\n    let topSites = this.props.TopSites.rows.slice();\n    topSites.length = this.props.TopSitesRows * TOP_SITES_MAX_SITES_PER_ROW;\n    return topSites;\n  }\n\n  /**\n   * Make a preview of the topsites that will be the result of dropping the currently\n   * dragged site at the specified index.\n   */\n  _makeTopSitesPreview(index) {\n    const topSites = this._getTopSites();\n    topSites[this.state.draggedIndex] = null;\n    const pinnedOnly = topSites.map(site => ((site && site.isPinned) ? site : null));\n    const unpinned = topSites.filter(site => site && !site.isPinned);\n    const siteToInsert = Object.assign({}, this.state.draggedSite, {isPinned: true, isDragged: true});\n    if (!pinnedOnly[index]) {\n      pinnedOnly[index] = siteToInsert;\n    } else {\n      // Find the hole to shift the pinned site(s) towards. We shift towards the\n      // hole left by the site being dragged.\n      let holeIndex = index;\n      const indexStep = index > this.state.draggedIndex ? -1 : 1;\n      while (pinnedOnly[holeIndex]) {\n        holeIndex += indexStep;\n      }\n\n      // Shift towards the hole.\n      const shiftingStep = index > this.state.draggedIndex ? 1 : -1;\n      while (holeIndex !== index) {\n        const nextIndex = holeIndex + shiftingStep;\n        pinnedOnly[holeIndex] = pinnedOnly[nextIndex];\n        holeIndex = nextIndex;\n      }\n      pinnedOnly[index] = siteToInsert;\n    }\n\n    // Fill in the remaining holes with unpinned sites.\n    const preview = pinnedOnly;\n    for (let i = 0; i < preview.length; i++) {\n      if (!preview[i]) {\n        preview[i] = unpinned.shift() || null;\n      }\n    }\n\n    return preview;\n  }\n\n  onActivate(index) {\n    this.setState({activeIndex: index});\n  }\n\n  render() {\n    const {props} = this;\n    const topSites = this.state.topSitesPreview || this._getTopSites();\n    const topSitesUI = [];\n    const commonProps = {\n      onDragEvent: this.onDragEvent,\n      dispatch: props.dispatch,\n      intl: props.intl\n    };\n    // We assign a key to each placeholder slot. We need it to be independent\n    // of the slot index (i below) so that the keys used stay the same during\n    // drag and drop reordering and the underlying DOM nodes are reused.\n    // This mostly (only?) affects linux so be sure to test on linux before changing.\n    let holeIndex = 0;\n\n    // On narrow viewports, we only show 6 sites per row. We'll mark the rest as\n    // .hide-for-narrow to hide in CSS via @media query.\n    const maxNarrowVisibleIndex = props.TopSitesRows * 6;\n\n    for (let i = 0, l = topSites.length; i < l; i++) {\n      const link = topSites[i] && Object.assign({}, topSites[i], {iconType: this.props.topSiteIconType(topSites[i])});\n      const slotProps = {\n        key: link ? link.url : holeIndex++,\n        index: i\n      };\n      if (i >= maxNarrowVisibleIndex) {\n        slotProps.className = \"hide-for-narrow\";\n      }\n      topSitesUI.push(!link ? (\n        <TopSitePlaceholder\n          {...slotProps}\n          {...commonProps} />\n      ) : (\n        <TopSite\n          link={link}\n          activeIndex={this.state.activeIndex}\n          onActivate={this.onActivate}\n          {...slotProps}\n          {...commonProps} />\n      ));\n    }\n    return (<ul className={`top-sites-list${this.state.draggedSite ? \" dnd-active\" : \"\"}`}>\n      {topSitesUI}\n    </ul>);\n  }\n}\n\nexport const TopSiteList = injectIntl(_TopSiteList);\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/TopSites/TopSite.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {addSnippetsSubscriber} from \"content-src/lib/snippets\";\nimport {Base} from \"content-src/components/Base/Base\";\nimport {DetectUserSessionStart} from \"content-src/lib/detect-user-session-start\";\nimport {initStore} from \"content-src/lib/init-store\";\nimport {Provider} from \"react-redux\";\nimport React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport {reducers} from \"common/Reducers.jsm\";\n\nconst store = initStore(reducers, global.gActivityStreamPrerenderedState);\n\nnew DetectUserSessionStart(store).sendEventOrAddListener();\n\n// If we are starting in a prerendered state, we must wait until the first render\n// to request state rehydration (see Base.jsx). If we are NOT in a prerendered state,\n// we can request it immedately.\nif (!global.gActivityStreamPrerenderedState) {\n  store.dispatch(ac.AlsoToMain({type: at.NEW_TAB_STATE_REQUEST}));\n}\n\nReactDOM.hydrate(<Provider store={store}>\n  <Base\n    isFirstrun={global.document.location.href === \"about:welcome\"}\n    isPrerendered={!!global.gActivityStreamPrerenderedState}\n    locale={global.document.documentElement.lang}\n    strings={global.gActivityStreamStrings} />\n</Provider>, document.getElementById(\"root\"));\n\naddSnippetsSubscriber(store);\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/activity-stream.jsx","const DATABASE_NAME = \"snippets_db\";\nconst DATABASE_VERSION = 1;\nconst SNIPPETS_OBJECTSTORE_NAME = \"snippets\";\nexport const SNIPPETS_UPDATE_INTERVAL_MS = 14400000; // 4 hours.\n\nconst SNIPPETS_ENABLED_EVENT = \"Snippets:Enabled\";\nconst SNIPPETS_DISABLED_EVENT = \"Snippets:Disabled\";\n\nimport {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {ASRouterContent} from \"content-src/asrouter/asrouter-content\";\n\n/**\n * SnippetsMap - A utility for cacheing values related to the snippet. It has\n *               the same interface as a Map, but is optionally backed by\n *               indexedDB for persistent storage.\n *               Call .connect() to open a database connection and restore any\n *               previously cached data, if necessary.\n *\n */\nexport class SnippetsMap extends Map {\n  constructor(dispatch) {\n    super();\n    this._db = null;\n    this._dispatch = dispatch;\n  }\n\n  set(key, value) {\n    super.set(key, value);\n    return this._dbTransaction(db => db.put(value, key));\n  }\n\n  delete(key) {\n    super.delete(key);\n    return this._dbTransaction(db => db.delete(key));\n  }\n\n  clear() {\n    super.clear();\n    this._dispatch(ac.OnlyToMain({type: at.SNIPPETS_BLOCKLIST_CLEARED}));\n    return this._dbTransaction(db => db.clear());\n  }\n\n  get blockList() {\n    return this.get(\"blockList\") || [];\n  }\n\n  /**\n   * blockSnippetById - Blocks a snippet given an id\n   *\n   * @param  {str|int} id   The id of the snippet\n   * @return {Promise}      Resolves when the id has been written to indexedDB,\n   *                        or immediately if the snippetMap is not connected\n   */\n  async blockSnippetById(id) {\n    if (!id) {\n      return;\n    }\n    const {blockList} = this;\n    if (!blockList.includes(id)) {\n      blockList.push(id);\n      this._dispatch(ac.AlsoToMain({type: at.SNIPPETS_BLOCKLIST_UPDATED, data: id}));\n      await this.set(\"blockList\", blockList);\n    }\n  }\n\n  disableOnboarding() {\n    this._dispatch(ac.AlsoToMain({type: at.DISABLE_ONBOARDING}));\n  }\n\n  showFirefoxAccounts() {\n    this._dispatch(ac.AlsoToMain({type: at.SHOW_FIREFOX_ACCOUNTS}));\n  }\n\n  getTotalBookmarksCount() {\n    return new Promise(resolve => {\n      this._dispatch(ac.OnlyToMain({type: at.TOTAL_BOOKMARKS_REQUEST}));\n      global.addMessageListener(\"ActivityStream:MainToContent\", function onMessage({data: action}) {\n        if (action.type === at.TOTAL_BOOKMARKS_RESPONSE) {\n          resolve(action.data);\n          global.removeMessageListener(\"ActivityStream:MainToContent\", onMessage);\n        }\n      });\n    });\n  }\n\n  getAddonsInfo() {\n    return new Promise(resolve => {\n      this._dispatch(ac.OnlyToMain({type: at.ADDONS_INFO_REQUEST}));\n      global.addMessageListener(\"ActivityStream:MainToContent\", function onMessage({data: action}) {\n        if (action.type === at.ADDONS_INFO_RESPONSE) {\n          resolve(action.data);\n          global.removeMessageListener(\"ActivityStream:MainToContent\", onMessage);\n        }\n      });\n    });\n  }\n\n  /**\n   * connect - Attaches an indexedDB back-end to the Map so that any set values\n   *           are also cached in a store. It also restores any existing values\n   *           that are already stored in the indexedDB store.\n   *\n   * @return {type}  description\n   */\n  async connect() {\n    // Open the connection\n    const db = await this._openDB();\n\n    // Restore any existing values\n    await this._restoreFromDb(db);\n\n    // Attach a reference to the db\n    this._db = db;\n  }\n\n  /**\n   * _dbTransaction - Returns a db transaction wrapped with the given modifier\n   *                  function as a Promise. If the db has not been connected,\n   *                  it resolves immediately.\n   *\n   * @param  {func} modifier A function to call with the transaction\n   * @return {obj}           A Promise that resolves when the transaction has\n   *                         completed or errored\n   */\n  _dbTransaction(modifier) {\n    if (!this._db) {\n      return Promise.resolve();\n    }\n    return new Promise((resolve, reject) => {\n      const transaction = modifier(\n        this._db\n          .transaction(SNIPPETS_OBJECTSTORE_NAME, \"readwrite\")\n          .objectStore(SNIPPETS_OBJECTSTORE_NAME)\n      );\n      transaction.onsuccess = event => resolve();\n\n      /* istanbul ignore next */\n      transaction.onerror = event => reject(transaction.error);\n    });\n  }\n\n  _openDB() {\n    return new Promise((resolve, reject) => {\n      const openRequest = indexedDB.open(DATABASE_NAME, DATABASE_VERSION);\n\n      /* istanbul ignore next */\n      openRequest.onerror = event => {\n        // Try to delete the old database so that we can start this process over\n        // next time.\n        indexedDB.deleteDatabase(DATABASE_NAME);\n        reject(event);\n      };\n\n      openRequest.onupgradeneeded = event => {\n        const db = event.target.result;\n        if (!db.objectStoreNames.contains(SNIPPETS_OBJECTSTORE_NAME)) {\n          db.createObjectStore(SNIPPETS_OBJECTSTORE_NAME);\n        }\n      };\n\n      openRequest.onsuccess = event => {\n        let db = event.target.result;\n\n        /* istanbul ignore next */\n        db.onerror = err => console.error(err); // eslint-disable-line no-console\n        /* istanbul ignore next */\n        db.onversionchange = versionChangeEvent => versionChangeEvent.target.close();\n\n        resolve(db);\n      };\n    });\n  }\n\n  _restoreFromDb(db) {\n    return new Promise((resolve, reject) => {\n      let cursorRequest;\n      try {\n        cursorRequest = db.transaction(SNIPPETS_OBJECTSTORE_NAME)\n          .objectStore(SNIPPETS_OBJECTSTORE_NAME).openCursor();\n      } catch (err) {\n        // istanbul ignore next\n        reject(err);\n        // istanbul ignore next\n        return;\n      }\n\n      /* istanbul ignore next */\n      cursorRequest.onerror = event => reject(event);\n\n      cursorRequest.onsuccess = event => {\n        let cursor = event.target.result;\n        // Populate the cache from the persistent storage.\n        if (cursor) {\n          if (cursor.value !== \"blockList\") {\n            this.set(cursor.key, cursor.value);\n          }\n          cursor.continue();\n        } else {\n          // We are done.\n          resolve();\n        }\n      };\n    });\n  }\n}\n\n/**\n * SnippetsProvider - Initializes a SnippetsMap and loads snippets from a\n *                    remote location, or else default snippets if the remote\n *                    snippets cannot be retrieved.\n */\nexport class SnippetsProvider {\n  constructor(dispatch) {\n    // Initialize the Snippets Map and attaches it to a global so that\n    // the snippet payload can interact with it.\n    global.gSnippetsMap = new SnippetsMap(dispatch);\n    this._onAction = this._onAction.bind(this);\n  }\n\n  get snippetsMap() {\n    return global.gSnippetsMap;\n  }\n\n  async _refreshSnippets() {\n    // Check if the cached version of of the snippets in snippetsMap. If it's too\n    // old, blow away the entire snippetsMap.\n    const cachedVersion = this.snippetsMap.get(\"snippets-cached-version\");\n\n    if (cachedVersion !== this.appData.version) {\n      this.snippetsMap.clear();\n    }\n\n    // Has enough time passed for us to require an update?\n    const lastUpdate = this.snippetsMap.get(\"snippets-last-update\");\n    const needsUpdate = !(lastUpdate >= 0) || Date.now() - lastUpdate > SNIPPETS_UPDATE_INTERVAL_MS;\n\n    if (needsUpdate && this.appData.snippetsURL) {\n      this.snippetsMap.set(\"snippets-last-update\", Date.now());\n      try {\n        const response = await fetch(this.appData.snippetsURL);\n        if (response.status === 200) {\n          const payload = await response.text();\n\n          this.snippetsMap.set(\"snippets\", payload);\n          this.snippetsMap.set(\"snippets-cached-version\", this.appData.version);\n        }\n      } catch (e) {\n        console.error(e); // eslint-disable-line no-console\n      }\n    }\n  }\n\n  _noSnippetFallback() {\n    // TODO\n  }\n\n  _forceOnboardingVisibility(shouldBeVisible) {\n    const onboardingEl = document.getElementById(\"onboarding-notification-bar\");\n\n    if (onboardingEl) {\n      onboardingEl.style.display = shouldBeVisible ? \"\" : \"none\";\n    }\n  }\n\n  _showRemoteSnippets() {\n    const snippetsEl = document.getElementById(this.elementId);\n    const payload = this.snippetsMap.get(\"snippets\");\n\n    if (!snippetsEl) {\n      throw new Error(`No element was found with id '${this.elementId}'.`);\n    }\n\n    // This could happen if fetching failed\n    if (!payload) {\n      throw new Error(\"No remote snippets were found in gSnippetsMap.\");\n    }\n\n    if (typeof payload !== \"string\") {\n      throw new Error(\"Snippet payload was incorrectly formatted\");\n    }\n\n    // Note that injecting snippets can throw if they're invalid XML.\n    // eslint-disable-next-line no-unsanitized/property\n    snippetsEl.innerHTML = payload;\n\n    // Scripts injected by innerHTML are inactive, so we have to relocate them\n    // through DOM manipulation to activate their contents.\n    for (const scriptEl of snippetsEl.getElementsByTagName(\"script\")) {\n      const relocatedScript = document.createElement(\"script\");\n      relocatedScript.text = scriptEl.text;\n      scriptEl.parentNode.replaceChild(relocatedScript, scriptEl);\n    }\n  }\n\n  _onAction(msg) {\n    if (msg.data.type === at.SNIPPET_BLOCKED) {\n      if (!this.snippetsMap.blockList.includes(msg.data.data)) {\n        this.snippetsMap.set(\"blockList\", this.snippetsMap.blockList.concat(msg.data.data));\n        document.getElementById(\"snippets-container\").style.display = \"none\";\n      }\n    }\n  }\n\n  /**\n   * init - Fetch the snippet payload and show snippets\n   *\n   * @param  {obj} options\n   * @param  {str} options.appData.snippetsURL  The URL from which we fetch snippets\n   * @param  {int} options.appData.version  The current snippets version\n   * @param  {str} options.elementId  The id of the element in which to inject snippets\n   * @param  {bool} options.connect  Should gSnippetsMap connect to indexedDB?\n   */\n  async init(options) {\n    Object.assign(this, {\n      appData: {},\n      elementId: \"snippets\",\n      connect: true\n    }, options);\n\n    // Add listener so we know when snippets are blocked on other pages\n    if (global.addMessageListener) {\n      global.addMessageListener(\"ActivityStream:MainToContent\", this._onAction);\n    }\n\n    // TODO: Requires enabling indexedDB on newtab\n    // Restore the snippets map from indexedDB\n    if (this.connect) {\n      try {\n        await this.snippetsMap.connect();\n      } catch (e) {\n        console.error(e); // eslint-disable-line no-console\n      }\n    }\n\n    // Cache app data values so they can be accessible from gSnippetsMap\n    for (const key of Object.keys(this.appData)) {\n      if (key === \"blockList\") {\n        this.snippetsMap.set(\"blockList\", this.appData[key]);\n      } else {\n        this.snippetsMap.set(`appData.${key}`, this.appData[key]);\n      }\n    }\n\n    // Refresh snippets, if enough time has passed.\n    await this._refreshSnippets();\n\n    // Try showing remote snippets, falling back to defaults if necessary.\n    try {\n      this._showRemoteSnippets();\n    } catch (e) {\n      this._noSnippetFallback(e);\n    }\n\n    window.dispatchEvent(new Event(SNIPPETS_ENABLED_EVENT));\n\n    this._forceOnboardingVisibility(true);\n    this.initialized = true;\n  }\n\n  uninit() {\n    window.dispatchEvent(new Event(SNIPPETS_DISABLED_EVENT));\n    this._forceOnboardingVisibility(false);\n    if (global.removeMessageListener) {\n      global.removeMessageListener(\"ActivityStream:MainToContent\", this._onAction);\n    }\n    this.initialized = false;\n  }\n}\n\n/**\n * addSnippetsSubscriber - Creates a SnippetsProvider that Initializes\n *                         when the store has received the appropriate\n *                         Snippet data.\n *\n * @param  {obj} store   The redux store\n * @return {obj}         Returns the snippets instance, asrouterContent instance and unsubscribe function\n */\nexport function addSnippetsSubscriber(store) {\n  const snippets = new SnippetsProvider(store.dispatch);\n  const asrouterContent = new ASRouterContent();\n\n  let initializing = false;\n\n  store.subscribe(async () => {\n    const state = store.getState();\n    // state.Prefs.values[\"feeds.snippets\"]:  Should snippets be shown?\n    // state.Snippets.initialized             Is the snippets data initialized?\n    // snippets.initialized:                  Is SnippetsProvider currently initialised?\n    if (state.Prefs.values[\"feeds.snippets\"] &&\n      // If the message center experiment is enabled, don't show snippets\n      !state.Prefs.values.asrouterExperimentEnabled &&\n      !state.Prefs.values.disableSnippets &&\n      state.Snippets.initialized &&\n      !snippets.initialized &&\n      // Don't call init multiple times\n      !initializing &&\n      location.href !== \"about:welcome\"\n    ) {\n      initializing = true;\n      await snippets.init({appData: state.Snippets});\n      initializing = false;\n    } else if (\n      (state.Prefs.values[\"feeds.snippets\"] === false ||\n        state.Prefs.values.disableSnippets === true) &&\n      snippets.initialized\n    ) {\n      snippets.uninit();\n    }\n\n    // Turn on AS Router snippets if the experiment is enabled and the snippets pref is on;\n    // otherwise, turn it off.\n    if (\n      state.Prefs.values.asrouterExperimentEnabled &&\n      state.Prefs.values[\"feeds.snippets\"] &&\n      !asrouterContent.initialized) {\n      asrouterContent.init();\n    } else if (\n      (!state.Prefs.values.asrouterExperimentEnabled || !state.Prefs.values[\"feeds.snippets\"]) &&\n      asrouterContent.initialized\n    ) {\n      asrouterContent.uninit();\n    }\n  });\n\n  // These values are returned for testing purposes\n  return {snippets, asrouterContent};\n}\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/lib/snippets.js","module.exports = Redux;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"Redux\"\n// module id = 21\n// module chunks = 0","import React from \"react\";\n\nexport const VISIBLE = \"visible\";\nexport const VISIBILITY_CHANGE_EVENT = \"visibilitychange\";\n\n/**\n * Component wrapper used to send telemetry pings on every impression.\n */\nexport class ImpressionsWrapper extends React.PureComponent {\n  // This sends an event when a user sees a set of new content. If content\n  // changes while the page is hidden (i.e. preloaded or on a hidden tab),\n  // only send the event if the page becomes visible again.\n  sendImpressionOrAddListener() {\n    if (this.props.document.visibilityState === VISIBLE) {\n      this.props.sendImpression({id: this.props.id});\n    } else {\n      // We should only ever send the latest impression stats ping, so remove any\n      // older listeners.\n      if (this._onVisibilityChange) {\n        this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n      }\n\n      // When the page becomes visible, send the impression stats ping if the section isn't collapsed.\n      this._onVisibilityChange = () => {\n        if (this.props.document.visibilityState === VISIBLE) {\n          this.props.sendImpression({id: this.props.id});\n          this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n        }\n      };\n      this.props.document.addEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n    }\n  }\n\n  componentWillUnmount() {\n    if (this._onVisibilityChange) {\n      this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n    }\n  }\n\n  componentDidMount() {\n    if (this.props.sendOnMount) {\n      this.sendImpressionOrAddListener();\n    }\n  }\n\n  componentDidUpdate(prevProps) {\n    if (this.props.shouldSendImpressionOnUpdate(this.props, prevProps)) {\n      this.sendImpressionOrAddListener();\n    }\n  }\n\n  render() {\n    return this.props.children;\n  }\n}\n\nImpressionsWrapper.defaultProps = {\n  document: global.document,\n  sendOnMount: true\n};\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/asrouter/components/ImpressionsWrapper/ImpressionsWrapper.jsx","import React from \"react\";\n\nexport class ModalOverlay extends React.PureComponent {\n  componentWillMount() {\n    this.setState({active: true});\n    document.body.classList.add(\"modal-open\");\n  }\n\n  componentWillUnmount() {\n    document.body.classList.remove(\"modal-open\");\n    this.setState({active: false});\n  }\n\n  render() {\n    const {active} = this.state;\n    const {title, button_label} = this.props;\n    return (\n      <div>\n        <div className={`modalOverlayOuter ${active ? \"active\" : \"\"}`} />\n        <div className={`modalOverlayInner ${active ? \"active\" : \"\"}`}>\n          <h2> {title} </h2>\n          {this.props.children}\n          <div className=\"footer\">\n            <button onClick={this.props.onDoneButton} className=\"button primary modalButton\"> {button_label} </button>\n          </div>\n        </div>\n      </div>\n    );\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/asrouter/components/ModalOverlay/ModalOverlay.jsx","import {ModalOverlay} from \"../../components/ModalOverlay/ModalOverlay\";\nimport React from \"react\";\n\nclass OnboardingCard extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onClick = this.onClick.bind(this);\n  }\n\n  onClick() {\n    const {props} = this;\n    props.sendUserActionTelemetry({event: \"CLICK_BUTTON\", message_id: props.id, id: props.UISurface});\n    props.onAction(props.content);\n  }\n\n  render() {\n    const {content} = this.props;\n    return (\n      <div className=\"onboardingMessage\">\n        <div className={`onboardingMessageImage ${content.icon}`} />\n        <div className=\"onboardingContent\">\n          <span>\n            <h3> {content.title} </h3>\n            <p> {content.text} </p>\n          </span>\n          <span>\n            <button className=\"button onboardingButton\" onClick={this.onClick}> {content.button_label} </button>\n          </span>\n        </div>\n      </div>\n    );\n  }\n}\n\nexport class OnboardingMessage extends React.PureComponent {\n  render() {\n    const {props} = this;\n    return (\n      <ModalOverlay {...props} button_label={\"Start Browsing\"} title={\"Welcome to Firefox\"}>\n        <div className=\"onboardingMessageContainer\">\n          {props.bundle.map(message => (\n            <OnboardingCard key={message.id}\n              sendUserActionTelemetry={props.sendUserActionTelemetry}\n              onAction={props.onAction}\n              UISurface={props.UISurface}\n              {...message} />\n          ))}\n        </div>\n      </ModalOverlay>\n    );\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/asrouter/templates/OnboardingMessage/OnboardingMessage.jsx","export function safeURI(url) {\n  if (!url) {\n    return \"\";\n  }\n  const {protocol} = new URL(url);\n  const isAllowed = [\n    \"http:\",\n    \"https:\",\n    \"data:\",\n    \"resource:\",\n    \"chrome:\"\n  ].includes(protocol);\n  if (!isAllowed) {\n    console.warn(`The protocol ${protocol} is not allowed for template URLs.`); // eslint-disable-line no-console\n  }\n  return isAllowed ? url : \"\";\n}\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/asrouter/template-utils.js","import React from \"react\";\nimport {safeURI} from \"../../template-utils\";\n\nconst ALLOWED_STYLE_TAGS = [\"color\", \"backgroundColor\"];\n\nexport const Button = props => {\n  const style = {};\n\n  // Add allowed style tags from props, e.g. props.color becomes style={color: props.color}\n  for (const tag of ALLOWED_STYLE_TAGS) {\n    if (typeof props[tag] !== \"undefined\") {\n      style[tag] = props[tag];\n    }\n  }\n  // remove border if bg is set to something custom\n  if (style.backgroundColor) {\n    style.border = \"0\";\n  }\n\n  return (<a href={safeURI(props.url)}\n    onClick={props.onClick}\n    className={props.className || \"ASRouterButton\"}\n    style={style}>\n    {props.children}\n  </a>);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/asrouter/components/Button/Button.jsx","import React from \"react\";\n\nexport class SnippetBase extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onBlockClicked = this.onBlockClicked.bind(this);\n  }\n\n  onBlockClicked() {\n    this.props.sendUserActionTelemetry({event: \"BLOCK\", id: this.props.UISurface});\n    this.props.onBlock();\n  }\n\n  render() {\n    const {props} = this;\n\n    const containerClassName = `SnippetBaseContainer${props.className ? ` ${props.className}` : \"\"}`;\n\n    return (<div className={containerClassName}>\n      <div className=\"innerWrapper\">\n        {props.children}\n      </div>\n      <button className=\"blockButton\" onClick={this.onBlockClicked} />\n    </div>);\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/asrouter/components/SnippetBase/SnippetBase.jsx","import {Button} from \"../../components/Button/Button\";\nimport React from \"react\";\nimport {safeURI} from \"../../template-utils\";\nimport {SnippetBase} from \"../../components/SnippetBase/SnippetBase\";\n\nconst DEFAULT_ICON_PATH = \"chrome://branding/content/icon64.png\";\n\nexport class SimpleSnippet extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onButtonClick = this.onButtonClick.bind(this);\n  }\n\n  onButtonClick() {\n    this.props.sendUserActionTelemetry({event: \"CLICK_BUTTON\", id: this.props.UISurface});\n  }\n\n  renderTitle() {\n    const {title} = this.props.content;\n    return title ? <h3 className=\"title\">{title}</h3> : null;\n  }\n\n  renderTitleIcon() {\n    const titleIcon = safeURI(this.props.content.title_icon);\n    return titleIcon ? <span className=\"titleIcon\" style={{backgroundImage: `url(\"${titleIcon}\")`}} /> : null;\n  }\n\n  renderButton(className) {\n    const {props} = this;\n    return (<Button\n      className={className}\n      onClick={this.onButtonClick}\n      url={props.content.button_url}\n      color={props.content.button_color}\n      backgroundColor={props.content.button_background_color}>\n      {props.content.button_label}\n    </Button>);\n  }\n\n  render() {\n    const {props} = this;\n    const hasLink = props.content.button_url && props.content.button_type === \"anchor\";\n    const hasButton = props.content.button_url && !props.content.button_type;\n    const className = `SimpleSnippet${props.content.tall ? \" tall\" : \"\"}`;\n    return (<SnippetBase {...props} className={className}>\n      <img src={safeURI(props.content.icon) || DEFAULT_ICON_PATH} className=\"icon\" />\n      <div>\n        {this.renderTitleIcon()} {this.renderTitle()} <p className=\"body\">{props.content.text}</p> {hasLink ? this.renderButton(\"ASRouterAnchor\") : null}\n      </div>\n      {hasButton ? <div>{this.renderButton()}</div> : null}\n    </SnippetBase>);\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/asrouter/templates/SimpleSnippet/SimpleSnippet.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {addLocaleData, injectIntl, IntlProvider} from \"react-intl\";\nimport {ASRouterAdmin} from \"content-src/components/ASRouterAdmin/ASRouterAdmin\";\nimport {ConfirmDialog} from \"content-src/components/ConfirmDialog/ConfirmDialog\";\nimport {connect} from \"react-redux\";\nimport {ErrorBoundary} from \"content-src/components/ErrorBoundary/ErrorBoundary\";\nimport {ManualMigration} from \"content-src/components/ManualMigration/ManualMigration\";\nimport {PrerenderData} from \"common/PrerenderData.jsm\";\nimport React from \"react\";\nimport {Search} from \"content-src/components/Search/Search\";\nimport {Sections} from \"content-src/components/Sections/Sections\";\nimport {StartupOverlay} from \"content-src/components/StartupOverlay/StartupOverlay\";\n\nconst PrefsButton = injectIntl(props => (\n  <div className=\"prefs-button\">\n    <button className=\"icon icon-settings\" onClick={props.onClick} title={props.intl.formatMessage({id: \"settings_pane_button_label\"})} />\n  </div>\n));\n\n// Add the locale data for pluralization and relative-time formatting for now,\n// this just uses english locale data. We can make this more sophisticated if\n// more features are needed.\nfunction addLocaleDataForReactIntl(locale) {\n  addLocaleData([{locale, parentLocale: \"en\"}]);\n}\n\nexport class _Base extends React.PureComponent {\n  componentWillMount() {\n    const {App, locale, Theme} = this.props;\n    if (Theme.className) {\n      this.updateTheme(Theme);\n    }\n    this.sendNewTabRehydrated(App);\n    addLocaleDataForReactIntl(locale);\n  }\n\n  componentDidMount() {\n    // Request state AFTER the first render to ensure we don't cause the\n    // prerendered DOM to be unmounted. Otherwise, NEW_TAB_STATE_REQUEST is\n    // dispatched right after the store is ready.\n    if (this.props.isPrerendered) {\n      this.props.dispatch(ac.AlsoToMain({type: at.NEW_TAB_STATE_REQUEST}));\n      this.props.dispatch(ac.AlsoToMain({type: at.PAGE_PRERENDERED}));\n    }\n  }\n\n  componentWillUnmount() {\n    this.updateTheme({className: \"\"});\n  }\n\n  componentWillUpdate({App, Theme}) {\n    this.updateTheme(Theme);\n    this.sendNewTabRehydrated(App);\n  }\n\n  updateTheme(Theme) {\n    const bodyClassName = [\n      \"activity-stream\",\n      Theme.className,\n      this.props.isFirstrun ? \"welcome\" : \"\"\n    ].filter(v => v).join(\" \");\n    global.document.body.className = bodyClassName;\n  }\n\n  // The NEW_TAB_REHYDRATED event is used to inform feeds that their\n  // data has been consumed e.g. for counting the number of tabs that\n  // have rendered that data.\n  sendNewTabRehydrated(App) {\n    if (App && App.initialized && !this.renderNotified) {\n      this.props.dispatch(ac.AlsoToMain({type: at.NEW_TAB_REHYDRATED, data: {}}));\n      this.renderNotified = true;\n    }\n  }\n\n  render() {\n    const {props} = this;\n    const {App, locale, strings} = props;\n    const {initialized} = App;\n\n    if (props.Prefs.values.asrouterExperimentEnabled && window.location.hash === \"#asrouter\") {\n      return (<ASRouterAdmin />);\n    }\n\n    if (!props.isPrerendered && !initialized) {\n      return null;\n    }\n\n    return (<IntlProvider locale={locale} messages={strings}>\n        <ErrorBoundary className=\"base-content-fallback\">\n          <BaseContent {...this.props} />\n        </ErrorBoundary>\n      </IntlProvider>);\n  }\n}\n\nexport class BaseContent extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.openPreferences = this.openPreferences.bind(this);\n  }\n\n  openPreferences() {\n    this.props.dispatch(ac.OnlyToMain({type: at.SETTINGS_OPEN}));\n    this.props.dispatch(ac.UserEvent({event: \"OPEN_NEWTAB_PREFS\"}));\n  }\n\n  render() {\n    const {props} = this;\n    const {App} = props;\n    const {initialized} = App;\n    const prefs = props.Prefs.values;\n\n    const shouldBeFixedToTop = PrerenderData.arePrefsValid(name => prefs[name]);\n\n    const outerClassName = [\n      \"outer-wrapper\",\n      shouldBeFixedToTop && \"fixed-to-top\"\n    ].filter(v => v).join(\" \");\n\n    return (\n      <div>\n        <div className={outerClassName}>\n          <main>\n            {prefs.showSearch &&\n              <div className=\"non-collapsible-section\">\n                <ErrorBoundary>\n                  <Search />\n                </ErrorBoundary>\n              </div>\n            }\n            <div className={`body-wrapper${(initialized ? \" on\" : \"\")}`}>\n              {!prefs.migrationExpired &&\n                <div className=\"non-collapsible-section\">\n                  <ManualMigration />\n                </div>\n                }\n              <Sections />\n              <PrefsButton onClick={this.openPreferences} />\n            </div>\n            <ConfirmDialog />\n          </main>\n        </div>\n        {this.props.isFirstrun && <StartupOverlay />}\n      </div>);\n  }\n}\n\nexport const Base = connect(state => ({App: state.App, Prefs: state.Prefs, Theme: state.Theme}))(_Base);\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/Base/Base.jsx","import {ASRouterUtils} from \"../../asrouter/asrouter-content\";\nimport React from \"react\";\n\nexport class ASRouterAdmin extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onMessage = this.onMessage.bind(this);\n    this.findOtherBundledMessagesOfSameTemplate = this.findOtherBundledMessagesOfSameTemplate.bind(this);\n    this.state = {};\n  }\n\n  onMessage({data: action}) {\n    if (action.type === \"ADMIN_SET_STATE\") {\n      this.setState(action.data);\n    }\n  }\n\n  componentWillMount() {\n    ASRouterUtils.sendMessage({type: \"ADMIN_CONNECT_STATE\"});\n    ASRouterUtils.addListener(this.onMessage);\n  }\n\n  componentWillUnmount() {\n    ASRouterUtils.removeListener(this.onMessage);\n  }\n\n  findOtherBundledMessagesOfSameTemplate(template) {\n    return this.state.messages.filter(msg => msg.template === template && msg.bundled);\n  }\n\n  handleBlock(msg) {\n    if (msg.bundled) {\n      // If we are blocking a message that belongs to a bundle, block all other messages that are bundled of that same template\n      let bundle = this.findOtherBundledMessagesOfSameTemplate(msg.template);\n      return () => ASRouterUtils.blockBundle(bundle);\n    }\n    return () => ASRouterUtils.blockById(msg.id);\n  }\n\n  handleUnblock(msg) {\n    if (msg.bundled) {\n      // If we are unblocking a message that belongs to a bundle, unblock all other messages that are bundled of that same template\n      let bundle = this.findOtherBundledMessagesOfSameTemplate(msg.template);\n      return () => ASRouterUtils.unblockBundle(bundle);\n    }\n    return () => ASRouterUtils.unblockById(msg.id);\n  }\n\n  handleOverride(id) {\n    return () => ASRouterUtils.overrideMessage(id);\n  }\n\n  renderMessageItem(msg) {\n    const isCurrent = msg.id === this.state.lastMessageId;\n    const isBlocked = this.state.blockList.includes(msg.id);\n\n    let itemClassName = \"message-item\";\n    if (isCurrent) { itemClassName += \" current\"; }\n    if (isBlocked) { itemClassName += \" blocked\"; }\n\n    return (<tr className={itemClassName} key={msg.id}>\n      <td className=\"message-id\"><span>{msg.id}</span></td>\n      <td>\n        <button className={`button ${(isBlocked ? \"\" : \" primary\")}`} onClick={isBlocked ? this.handleUnblock(msg) : this.handleBlock(msg)}>{isBlocked ? \"Unblock\" : \"Block\"}</button>\n       {isBlocked ? null : <button className=\"button\" onClick={this.handleOverride(msg.id)}>Show</button>}\n      </td>\n      <td className=\"message-summary\">\n        <pre>{JSON.stringify(msg, null, 2)}</pre>\n      </td>\n    </tr>);\n  }\n\n  renderMessages() {\n    if (!this.state.messages) {\n      return null;\n    }\n    return (<table><tbody>\n      {this.state.messages.map(msg => this.renderMessageItem(msg))}\n    </tbody></table>);\n  }\n\n  renderProviders() {\n    return (<table><tbody>\n      {this.state.providers.map((provider, i) => (<tr className=\"message-item\" key={i}>\n        <td>{provider.id}</td>\n        <td>{provider.type === \"remote\" ? <a target=\"_blank\" href={provider.url}>{provider.url}</a> : \"(local)\"}</td>\n      </tr>))}\n    </tbody></table>);\n  }\n\n  render() {\n    return (<div className=\"asrouter-admin outer-wrapper\">\n      <h1>AS Router Admin</h1>\n      <button className=\"button primary\" onClick={ASRouterUtils.getNextMessage}>Refresh Current Message</button>\n      <h2>Message Providers</h2>\n      {this.state.providers ? this.renderProviders() : null}\n      <h2>Messages</h2>\n      {this.renderMessages()}\n    </div>);\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx","import {actionCreators as ac, actionTypes} from \"common/Actions.jsm\";\nimport {connect} from \"react-redux\";\nimport {FormattedMessage} from \"react-intl\";\nimport React from \"react\";\n\n/**\n * ConfirmDialog component.\n * One primary action button, one cancel button.\n *\n * Content displayed is controlled by `data` prop the component receives.\n * Example:\n * data: {\n *   // Any sort of data needed to be passed around by actions.\n *   payload: site.url,\n *   // Primary button AlsoToMain action.\n *   action: \"DELETE_HISTORY_URL\",\n *   // Primary button USerEvent action.\n *   userEvent: \"DELETE\",\n *   // Array of locale ids to display.\n *   message_body: [\"confirm_history_delete_p1\", \"confirm_history_delete_notice_p2\"],\n *   // Text for primary button.\n *   confirm_button_string_id: \"menu_action_delete\"\n * },\n */\nexport class _ConfirmDialog extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this._handleCancelBtn = this._handleCancelBtn.bind(this);\n    this._handleConfirmBtn = this._handleConfirmBtn.bind(this);\n  }\n\n  _handleCancelBtn() {\n    this.props.dispatch({type: actionTypes.DIALOG_CANCEL});\n    this.props.dispatch(ac.UserEvent({event: actionTypes.DIALOG_CANCEL, source: this.props.data.eventSource}));\n  }\n\n  _handleConfirmBtn() {\n    this.props.data.onConfirm.forEach(this.props.dispatch);\n  }\n\n  _renderModalMessage() {\n    const message_body = this.props.data.body_string_id;\n\n    if (!message_body) {\n      return null;\n    }\n\n    return (<span>\n      {message_body.map(msg => <p key={msg}><FormattedMessage id={msg} /></p>)}\n    </span>);\n  }\n\n  render() {\n    if (!this.props.visible) {\n      return null;\n    }\n\n    return (<div className=\"confirmation-dialog\">\n      <div className=\"modal-overlay\" onClick={this._handleCancelBtn} />\n      <div className=\"modal\">\n        <section className=\"modal-message\">\n          {this.props.data.icon && <span className={`icon icon-spacer icon-${this.props.data.icon}`} />}\n          {this._renderModalMessage()}\n        </section>\n        <section className=\"actions\">\n          <button onClick={this._handleCancelBtn}>\n            <FormattedMessage id={this.props.data.cancel_button_string_id} />\n          </button>\n          <button className=\"done\" onClick={this._handleConfirmBtn}>\n            <FormattedMessage id={this.props.data.confirm_button_string_id} />\n          </button>\n        </section>\n      </div>\n    </div>);\n  }\n}\n\nexport const ConfirmDialog = connect(state => state.Dialog)(_ConfirmDialog);\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/ConfirmDialog/ConfirmDialog.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {connect} from \"react-redux\";\nimport {FormattedMessage} from \"react-intl\";\nimport React from \"react\";\n\n/**\n * Manual migration component used to start the profile import wizard.\n * Message is presented temporarily and will go away if:\n * 1.  User clicks \"No Thanks\"\n * 2.  User completed the data import\n * 3.  After 3 active days\n * 4.  User clicks \"Cancel\" on the import wizard (currently not implemented).\n */\nexport class _ManualMigration extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onLaunchTour = this.onLaunchTour.bind(this);\n    this.onCancelTour = this.onCancelTour.bind(this);\n  }\n\n  onLaunchTour() {\n    this.props.dispatch(ac.AlsoToMain({type: at.MIGRATION_START}));\n    this.props.dispatch(ac.UserEvent({event: at.MIGRATION_START}));\n  }\n\n  onCancelTour() {\n    this.props.dispatch(ac.AlsoToMain({type: at.MIGRATION_CANCEL}));\n    this.props.dispatch(ac.UserEvent({event: at.MIGRATION_CANCEL}));\n  }\n\n  render() {\n    return (<div className=\"manual-migration-container\">\n        <p>\n          <span className=\"icon icon-import\" />\n          <FormattedMessage id=\"manual_migration_explanation2\" />\n        </p>\n        <div className=\"manual-migration-actions actions\">\n          <button className=\"dismiss\" onClick={this.onCancelTour}>\n            <FormattedMessage id=\"manual_migration_cancel_button\" />\n          </button>\n          <button onClick={this.onLaunchTour}>\n            <FormattedMessage id=\"manual_migration_import_button\" />\n          </button>\n        </div>\n    </div>);\n  }\n}\n\nexport const ManualMigration = connect()(_ManualMigration);\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/ManualMigration/ManualMigration.jsx","class _PrerenderData {\n  constructor(options) {\n    this.initialPrefs = options.initialPrefs;\n    this.initialSections = options.initialSections;\n    this._setValidation(options.validation);\n  }\n\n  get validation() {\n    return this._validation;\n  }\n\n  set validation(value) {\n    this._setValidation(value);\n  }\n\n  get invalidatingPrefs() {\n    return this._invalidatingPrefs;\n  }\n\n    // This is needed so we can use it in the constructor\n  _setValidation(value = []) {\n    this._validation = value;\n    this._invalidatingPrefs = value.reduce((result, next) => {\n      if (typeof next === \"string\") {\n        result.push(next);\n        return result;\n      } else if (next && next.oneOf) {\n        return result.concat(next.oneOf);\n      } else if (next && next.indexedDB) {\n        return result.concat(next.indexedDB);\n      }\n      throw new Error(\"Your validation configuration is not properly configured\");\n    }, []);\n  }\n\n  arePrefsValid(getPref, indexedDBPrefs) {\n    for (const prefs of this.validation) {\n      // {oneOf: [\"foo\", \"bar\"]}\n      if (prefs && prefs.oneOf && !prefs.oneOf.some(name => getPref(name) === this.initialPrefs[name])) {\n        return false;\n\n        // {indexedDB: [\"foo\", \"bar\"]}\n      } else if (indexedDBPrefs && prefs && prefs.indexedDB) {\n        const anyModifiedPrefs = prefs.indexedDB.some(prefName => indexedDBPrefs.some(pref => pref && pref[prefName]));\n        if (anyModifiedPrefs) {\n          return false;\n        }\n        // \"foo\"\n      } else if (getPref(prefs) !== this.initialPrefs[prefs]) {\n        return false;\n      }\n    }\n    return true;\n  }\n}\n\nthis.PrerenderData = new _PrerenderData({\n  initialPrefs: {\n    \"migrationExpired\": true,\n    \"feeds.topsites\": true,\n    \"showSearch\": true,\n    \"topSitesRows\": 1,\n    \"feeds.section.topstories\": true,\n    \"feeds.section.highlights\": true,\n    \"sectionOrder\": \"topsites,topstories,highlights\",\n    \"collapsed\": false\n  },\n  // Prefs listed as invalidating will prevent the prerendered version\n  // of AS from being used if their value is something other than what is listed\n  // here. This is required because some preferences cause the page layout to be\n  // too different for the prerendered version to be used. Unfortunately, this\n  // will result in users who have modified some of their preferences not being\n  // able to get the benefits of prerendering.\n  validation: [\n    \"feeds.topsites\",\n    \"showSearch\",\n    \"topSitesRows\",\n    \"sectionOrder\",\n    // This means if either of these are set to their default values,\n    // prerendering can be used.\n    {oneOf: [\"feeds.section.topstories\", \"feeds.section.highlights\"]},\n    // If any component has the following preference set to `true` it will\n    // invalidate the prerendered version.\n    {indexedDB: [\"collapsed\"]}\n  ],\n  initialSections: [\n    {\n      enabled: true,\n      icon: \"pocket\",\n      id: \"topstories\",\n      order: 1,\n      title: {id: \"header_recommended_by\", values: {provider: \"Pocket\"}}\n    },\n    {\n      enabled: true,\n      id: \"highlights\",\n      icon: \"highlights\",\n      order: 2,\n      title: {id: \"header_highlights\"}\n    }\n  ]\n});\n\nthis._PrerenderData = _PrerenderData;\nconst EXPORTED_SYMBOLS = [\"PrerenderData\", \"_PrerenderData\"];\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/common/PrerenderData.jsm","/* globals ContentSearchUIController */\n\"use strict\";\n\nimport {FormattedMessage, injectIntl} from \"react-intl\";\nimport {actionCreators as ac} from \"common/Actions.jsm\";\nimport {connect} from \"react-redux\";\nimport {IS_NEWTAB} from \"content-src/lib/constants\";\nimport React from \"react\";\n\nexport class _Search extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onClick = this.onClick.bind(this);\n    this.onInputMount = this.onInputMount.bind(this);\n  }\n\n  handleEvent(event) {\n    // Also track search events with our own telemetry\n    if (event.detail.type === \"Search\") {\n      this.props.dispatch(ac.UserEvent({event: \"SEARCH\"}));\n    }\n  }\n\n  onClick(event) {\n    window.gContentSearchController.search(event);\n  }\n\n  componentWillUnmount() {\n    delete window.gContentSearchController;\n  }\n\n  onInputMount(input) {\n    if (input) {\n      // The \"healthReportKey\" and needs to be \"newtab\" or \"abouthome\" so that\n      // BrowserUsageTelemetry.jsm knows to handle events with this name, and\n      // can add the appropriate telemetry probes for search. Without the correct\n      // name, certain tests like browser_UsageTelemetry_content.js will fail\n      // (See github ticket #2348 for more details)\n      const healthReportKey = IS_NEWTAB ? \"newtab\" : \"abouthome\";\n\n      // The \"searchSource\" needs to be \"newtab\" or \"homepage\" and is sent with\n      // the search data and acts as context for the search request (See\n      // nsISearchEngine.getSubmission). It is necessary so that search engine\n      // plugins can correctly atribute referrals. (See github ticket #3321 for\n      // more details)\n      const searchSource = IS_NEWTAB ? \"newtab\" : \"homepage\";\n\n      // gContentSearchController needs to exist as a global so that tests for\n      // the existing about:home can find it; and so it allows these tests to pass.\n      // In the future, when activity stream is default about:home, this can be renamed\n      window.gContentSearchController = new ContentSearchUIController(input, input.parentNode,\n        healthReportKey, searchSource);\n      addEventListener(\"ContentSearchClient\", this);\n    } else {\n      window.gContentSearchController = null;\n      removeEventListener(\"ContentSearchClient\", this);\n    }\n  }\n\n  /*\n   * Do not change the ID on the input field, as legacy newtab code\n   * specifically looks for the id 'newtab-search-text' on input fields\n   * in order to execute searches in various tests\n   */\n  render() {\n    return (<div className=\"search-wrapper\">\n      <label htmlFor=\"newtab-search-text\" className=\"search-label\">\n        <span className=\"sr-only\"><FormattedMessage id=\"search_web_placeholder\" /></span>\n      </label>\n      <input\n        id=\"newtab-search-text\"\n        maxLength=\"256\"\n        placeholder={this.props.intl.formatMessage({id: \"search_web_placeholder\"})}\n        ref={this.onInputMount}\n        title={this.props.intl.formatMessage({id: \"search_web_placeholder\"})}\n        type=\"search\" />\n      <button\n        id=\"searchSubmit\"\n        className=\"search-button\"\n        onClick={this.onClick}\n        title={this.props.intl.formatMessage({id: \"search_button\"})}>\n        <span className=\"sr-only\"><FormattedMessage id=\"search_button\" /></span>\n      </button>\n    </div>);\n  }\n}\n\nexport const Search = connect()(injectIntl(_Search));\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/Search/Search.jsx","export const IS_NEWTAB = global.document && global.document.documentURI === \"about:newtab\";\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/lib/constants.js","import {Card, PlaceholderCard} from \"content-src/components/Card/Card\";\nimport {FormattedMessage, injectIntl} from \"react-intl\";\nimport {actionCreators as ac} from \"common/Actions.jsm\";\nimport {CollapsibleSection} from \"content-src/components/CollapsibleSection/CollapsibleSection\";\nimport {ComponentPerfTimer} from \"content-src/components/ComponentPerfTimer/ComponentPerfTimer\";\nimport {connect} from \"react-redux\";\nimport React from \"react\";\nimport {Topics} from \"content-src/components/Topics/Topics\";\nimport {TopSites} from \"content-src/components/TopSites/TopSites\";\n\nconst VISIBLE = \"visible\";\nconst VISIBILITY_CHANGE_EVENT = \"visibilitychange\";\nconst CARDS_PER_ROW_DEFAULT = 3;\nconst CARDS_PER_ROW_COMPACT_WIDE = 4;\n\nfunction getFormattedMessage(message) {\n  return typeof message === \"string\" ? <span>{message}</span> : <FormattedMessage {...message} />;\n}\n\nexport class Section extends React.PureComponent {\n  get numRows() {\n    const {rowsPref, maxRows, Prefs} = this.props;\n    return rowsPref ? Prefs.values[rowsPref] : maxRows;\n  }\n\n  _dispatchImpressionStats() {\n    const {props} = this;\n    let cardsPerRow = CARDS_PER_ROW_DEFAULT;\n    if (props.compactCards && global.matchMedia(`(min-width: 1072px)`).matches) {\n      // If the section has compact cards and the viewport is wide enough, we show\n      // 4 columns instead of 3.\n      // $break-point-widest = 1072px (from _variables.scss)\n      cardsPerRow = CARDS_PER_ROW_COMPACT_WIDE;\n    }\n    const maxCards = cardsPerRow * this.numRows;\n    const cards = props.rows.slice(0, maxCards);\n\n    if (this.needsImpressionStats(cards)) {\n      props.dispatch(ac.ImpressionStats({\n        source: props.eventSource,\n        tiles: cards.map(link => ({id: link.guid}))\n      }));\n      this.impressionCardGuids = cards.map(link => link.guid);\n    }\n  }\n\n  // This sends an event when a user sees a set of new content. If content\n  // changes while the page is hidden (i.e. preloaded or on a hidden tab),\n  // only send the event if the page becomes visible again.\n  sendImpressionStatsOrAddListener() {\n    const {props} = this;\n\n    if (!props.shouldSendImpressionStats || !props.dispatch) {\n      return;\n    }\n\n    if (props.document.visibilityState === VISIBLE) {\n      this._dispatchImpressionStats();\n    } else {\n      // We should only ever send the latest impression stats ping, so remove any\n      // older listeners.\n      if (this._onVisibilityChange) {\n        props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n      }\n\n      // When the page becomes visible, send the impression stats ping if the section isn't collapsed.\n      this._onVisibilityChange = () => {\n        if (props.document.visibilityState === VISIBLE) {\n          if (!this.props.pref.collapsed) {\n            this._dispatchImpressionStats();\n          }\n          props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n        }\n      };\n      props.document.addEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n    }\n  }\n\n  componentDidMount() {\n    if (this.props.rows.length && !this.props.pref.collapsed) {\n      this.sendImpressionStatsOrAddListener();\n    }\n  }\n\n  componentDidUpdate(prevProps) {\n    const {props} = this;\n    const isCollapsed = props.pref.collapsed;\n    const wasCollapsed = prevProps.pref.collapsed;\n    if (\n      // Don't send impression stats for the empty state\n      props.rows.length &&\n      (\n        // We only want to send impression stats if the content of the cards has changed\n        // and the section is not collapsed...\n        (props.rows !== prevProps.rows && !isCollapsed) ||\n        // or if we are expanding a section that was collapsed.\n        (wasCollapsed && !isCollapsed)\n      )\n    ) {\n      this.sendImpressionStatsOrAddListener();\n    }\n  }\n\n  componentWillUnmount() {\n    if (this._onVisibilityChange) {\n      this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n    }\n  }\n\n  needsImpressionStats(cards) {\n    if (!this.impressionCardGuids || (this.impressionCardGuids.length !== cards.length)) {\n      return true;\n    }\n\n    for (let i = 0; i < cards.length; i++) {\n      if (cards[i].guid !== this.impressionCardGuids[i]) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  render() {\n    const {\n      id, eventSource, title, icon, rows,\n      emptyState, dispatch, compactCards,\n      contextMenuOptions, initialized, disclaimer,\n      pref, privacyNoticeURL, isFirst, isLast\n    } = this.props;\n\n    const maxCardsPerRow = compactCards ? CARDS_PER_ROW_COMPACT_WIDE : CARDS_PER_ROW_DEFAULT;\n    const {numRows} = this;\n    const maxCards = maxCardsPerRow * numRows;\n    const maxCardsOnNarrow = CARDS_PER_ROW_DEFAULT * numRows;\n\n    // Show topics only for top stories and if it's not initialized yet (so\n    // content doesn't shift when it is loaded) or has loaded with topics\n    const shouldShowTopics = (id === \"topstories\" &&\n      (!this.props.topics || this.props.topics.length > 0));\n\n    const realRows = rows.slice(0, maxCards);\n\n    // The empty state should only be shown after we have initialized and there is no content.\n    // Otherwise, we should show placeholders.\n    const shouldShowEmptyState = initialized && !rows.length;\n\n    const cards = [];\n    if (!shouldShowEmptyState) {\n      for (let i = 0; i < maxCards; i++) {\n        const link = realRows[i];\n        // On narrow viewports, we only show 3 cards per row. We'll mark the rest as\n        // .hide-for-narrow to hide in CSS via @media query.\n        const className = (i >= maxCardsOnNarrow) ? \"hide-for-narrow\" : \"\";\n        cards.push(link ? (\n          <Card key={i}\n            index={i}\n            className={className}\n            dispatch={dispatch}\n            link={link}\n            contextMenuOptions={contextMenuOptions}\n            eventSource={eventSource}\n            shouldSendImpressionStats={this.props.shouldSendImpressionStats}\n            isWebExtension={this.props.isWebExtension} />\n        ) : (\n          <PlaceholderCard key={i} className={className} />\n        ));\n      }\n    }\n\n    const sectionClassName = [\n      \"section\",\n      compactCards ? \"compact-cards\" : \"normal-cards\"\n    ].join(\" \");\n\n    // <Section> <-- React component\n    // <section> <-- HTML5 element\n    return (<ComponentPerfTimer {...this.props}>\n      <CollapsibleSection className={sectionClassName} icon={icon}\n        title={title}\n        id={id}\n        eventSource={eventSource}\n        disclaimer={disclaimer}\n        collapsed={this.props.pref.collapsed}\n        showPrefName={(pref && pref.feed) || id}\n        privacyNoticeURL={privacyNoticeURL}\n        Prefs={this.props.Prefs}\n        isFirst={isFirst}\n        isLast={isLast}\n        dispatch={this.props.dispatch}\n        isWebExtension={this.props.isWebExtension}>\n\n        {!shouldShowEmptyState && (<ul className=\"section-list\" style={{padding: 0}}>\n          {cards}\n        </ul>)}\n        {shouldShowEmptyState &&\n          <div className=\"section-empty-state\">\n            <div className=\"empty-state\">\n              {emptyState.icon && emptyState.icon.startsWith(\"moz-extension://\") ?\n                <img className=\"empty-state-icon icon\" style={{\"background-image\": `url('${emptyState.icon}')`}} /> :\n                <img className={`empty-state-icon icon icon-${emptyState.icon}`} />}\n              <p className=\"empty-state-message\">\n                {getFormattedMessage(emptyState.message)}\n              </p>\n            </div>\n          </div>}\n        {shouldShowTopics && <Topics topics={this.props.topics} read_more_endpoint={this.props.read_more_endpoint} />}\n      </CollapsibleSection>\n    </ComponentPerfTimer>);\n  }\n}\n\nSection.defaultProps = {\n  document: global.document,\n  rows: [],\n  emptyState: {},\n  pref: {},\n  title: \"\"\n};\n\nexport const SectionIntl = connect(state => ({Prefs: state.Prefs}))(injectIntl(Section));\n\nexport class _Sections extends React.PureComponent {\n  renderSections() {\n    const sections = [];\n    const enabledSections = this.props.Sections.filter(section => section.enabled);\n    const {sectionOrder, \"feeds.topsites\": showTopSites} = this.props.Prefs.values;\n    // Enabled sections doesn't include Top Sites, so we add it if enabled.\n    const expectedCount = enabledSections.length + ~~showTopSites;\n\n    for (const sectionId of sectionOrder.split(\",\")) {\n      const commonProps = {\n        key: sectionId,\n        isFirst: sections.length === 0,\n        isLast: sections.length === expectedCount - 1\n      };\n      if (sectionId === \"topsites\" && showTopSites) {\n        sections.push(<TopSites {...commonProps} />);\n      } else {\n        const section = enabledSections.find(s => s.id === sectionId);\n        if (section) {\n          sections.push(<SectionIntl {...section} {...commonProps} />);\n        }\n      }\n    }\n    return sections;\n  }\n\n  render() {\n    return (\n      <div className=\"sections-list\">\n        {this.renderSections()}\n      </div>\n    );\n  }\n}\n\nexport const Sections = connect(state => ({Sections: state.Sections, Prefs: state.Prefs}))(_Sections);\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/Sections/Sections.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {cardContextTypes} from \"./types\";\nimport {connect} from \"react-redux\";\nimport {FormattedMessage} from \"react-intl\";\nimport {GetPlatformString} from \"content-src/lib/link-menu-options\";\nimport {LinkMenu} from \"content-src/components/LinkMenu/LinkMenu\";\nimport React from \"react\";\n\n// Keep track of pending image loads to only request once\nconst gImageLoading = new Map();\n\n/**\n * Card component.\n * Cards are found within a Section component and contain information about a link such\n * as preview image, page title, page description, and some context about if the page\n * was visited, bookmarked, trending etc...\n * Each Section can make an unordered list of Cards which will create one instane of\n * this class. Each card will then get a context menu which reflects the actions that\n * can be done on this Card.\n */\nexport class _Card extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.state = {\n      activeCard: null,\n      imageLoaded: false,\n      showContextMenu: false,\n      cardImage: null\n    };\n    this.onMenuButtonClick = this.onMenuButtonClick.bind(this);\n    this.onMenuUpdate = this.onMenuUpdate.bind(this);\n    this.onLinkClick = this.onLinkClick.bind(this);\n  }\n\n  /**\n   * Helper to conditionally load an image and update state when it loads.\n   */\n  async maybeLoadImage() {\n    // No need to load if it's already loaded or no image\n    const {cardImage} = this.state;\n    if (!cardImage) {\n      return;\n    }\n\n    const imageUrl = cardImage.url;\n    if (!this.state.imageLoaded) {\n      // Initialize a promise to share a load across multiple card updates\n      if (!gImageLoading.has(imageUrl)) {\n        const loaderPromise = new Promise((resolve, reject) => {\n          const loader = new Image();\n          loader.addEventListener(\"load\", resolve);\n          loader.addEventListener(\"error\", reject);\n          loader.src = imageUrl;\n        });\n\n        // Save and remove the promise only while it's pending\n        gImageLoading.set(imageUrl, loaderPromise);\n        loaderPromise.catch(ex => ex).then(() => gImageLoading.delete(imageUrl)).catch();\n      }\n\n      // Wait for the image whether just started loading or reused promise\n      await gImageLoading.get(imageUrl);\n\n      // Only update state if we're still waiting to load the original image\n      if (_Card.isImageInState(this.state, this.props.link.image) && !this.state.imageLoaded) {\n        this.setState({imageLoaded: true});\n      }\n    }\n  }\n\n  /**\n   * Checks if `.image` property on link object is a local image with blob data.\n   * This function only works for props since state has `.url` and not `.data`.\n   *\n   * @param {obj|string} image\n   * @returns {bool} true if image is a local image object, otherwise false\n   *                 (otherwise, image will be a URL as a string)\n   */\n  static isLocalImageObject(image) {\n    return image && image.data && image.path;\n  }\n\n  /**\n   * Helper to obtain the next state based on nextProps and prevState.\n   *\n   * NOTE: Rename this method to getDerivedStateFromProps when we update React\n   *       to >= 16.3. We will need to update tests as well. We cannot rename this\n   *       method to getDerivedStateFromProps now because there is a mismatch in\n   *       the React version that we are using for both testing and production.\n   *       (i.e. react-test-render => \"16.3.2\", react => \"16.2.0\").\n   *\n   * See https://github.com/airbnb/enzyme/blob/master/packages/enzyme-adapter-react-16/package.json#L43.\n   */\n  static getNextStateFromProps(nextProps, prevState) {\n    const {image} = nextProps.link;\n    const imageInState = _Card.isImageInState(prevState, image);\n    let nextState = null;\n\n    // Image is updating.\n    if (!imageInState && nextProps.link) {\n      nextState = {imageLoaded: false};\n    }\n\n    if (imageInState) {\n      return nextState;\n    }\n\n    nextState = nextState || {};\n\n    // Since image was updated, attempt to revoke old image blob URL, if it exists.\n    _Card.maybeRevokeImageBlob(prevState);\n\n    if (!image) {\n      nextState.cardImage = null;\n    } else if (_Card.isLocalImageObject(image)) {\n      nextState.cardImage = {url: global.URL.createObjectURL(image.data), path: image.path};\n    } else {\n      nextState.cardImage = {url: image};\n    }\n\n    return nextState;\n  }\n\n  /**\n   * Helper to conditionally revoke the previous card image if it is a blob.\n   */\n  static maybeRevokeImageBlob(prevState) {\n    if (prevState.cardImage && prevState.cardImage.path) {\n      global.URL.revokeObjectURL(prevState.cardImage.url);\n    }\n  }\n\n  /**\n   * Helper to check if an image is already in state.\n   */\n  static isImageInState(state, image) {\n    const {cardImage} = state;\n\n    // Both image and cardImage are present.\n    if (image && cardImage) {\n      return _Card.isLocalImageObject(image) ?\n             cardImage.path === image.path :\n             cardImage.url === image;\n    }\n\n    // This will only handle the remaining three possible outcomes.\n    // (i.e. everything except when both image and cardImage are present)\n    return !image && !cardImage;\n  }\n\n  onMenuButtonClick(event) {\n    event.preventDefault();\n    this.setState({\n      activeCard: this.props.index,\n      showContextMenu: true\n    });\n  }\n\n  /**\n   * Report to telemetry additional information about the item.\n   */\n  _getTelemetryInfo() {\n    // Filter out \"history\" type for being the default\n    if (this.props.link.type !== \"history\") {\n      return {value: {card_type: this.props.link.type}};\n    }\n\n    return null;\n  }\n\n  onLinkClick(event) {\n    event.preventDefault();\n    if (this.props.link.type === \"download\") {\n      this.props.dispatch(ac.OnlyToMain({\n        type: at.SHOW_DOWNLOAD_FILE,\n        data: this.props.link\n      }));\n    } else {\n      const {altKey, button, ctrlKey, metaKey, shiftKey} = event;\n      this.props.dispatch(ac.OnlyToMain({\n        type: at.OPEN_LINK,\n        data: Object.assign(this.props.link, {event: {altKey, button, ctrlKey, metaKey, shiftKey}})\n      }));\n    }\n    if (this.props.isWebExtension) {\n      this.props.dispatch(ac.WebExtEvent(at.WEBEXT_CLICK, {\n        source: this.props.eventSource,\n        url: this.props.link.url,\n        action_position: this.props.index\n      }));\n    } else {\n      this.props.dispatch(ac.UserEvent(Object.assign({\n        event: \"CLICK\",\n        source: this.props.eventSource,\n        action_position: this.props.index\n      }, this._getTelemetryInfo())));\n\n      if (this.props.shouldSendImpressionStats) {\n        this.props.dispatch(ac.ImpressionStats({\n          source: this.props.eventSource,\n          click: 0,\n          tiles: [{id: this.props.link.guid, pos: this.props.index}]\n        }));\n      }\n    }\n  }\n\n  onMenuUpdate(showContextMenu) {\n    this.setState({showContextMenu});\n  }\n\n  componentDidMount() {\n    this.maybeLoadImage();\n  }\n\n  componentDidUpdate() {\n    this.maybeLoadImage();\n  }\n\n  // NOTE: Remove this function when we update React to >= 16.3 since React will\n  //       call getDerivedStateFromProps automatically. We will also need to\n  //       rename getNextStateFromProps to getDerivedStateFromProps.\n  componentWillMount() {\n    const nextState = _Card.getNextStateFromProps(this.props, this.state);\n    if (nextState) {\n      this.setState(nextState);\n    }\n  }\n\n  // NOTE: Remove this function when we update React to >= 16.3 since React will\n  //       call getDerivedStateFromProps automatically. We will also need to\n  //       rename getNextStateFromProps to getDerivedStateFromProps.\n  componentWillReceiveProps(nextProps) {\n    const nextState = _Card.getNextStateFromProps(nextProps, this.state);\n    if (nextState) {\n      this.setState(nextState);\n    }\n  }\n\n  componentWillUnmount() {\n    _Card.maybeRevokeImageBlob(this.state);\n  }\n\n  render() {\n    const {index, className, link, dispatch, contextMenuOptions, eventSource, shouldSendImpressionStats} = this.props;\n    const {props} = this;\n    const isContextMenuOpen = this.state.showContextMenu && this.state.activeCard === index;\n    // Display \"now\" as \"trending\" until we have new strings #3402\n    const {icon, intlID} = cardContextTypes[link.type === \"now\" ? \"trending\" : link.type] || {};\n    const hasImage = this.state.cardImage || link.hasImage;\n    const imageStyle = {backgroundImage: this.state.cardImage ? `url(${this.state.cardImage.url})` : \"none\"};\n    const outerClassName = [\n      \"card-outer\",\n      className,\n      isContextMenuOpen && \"active\",\n      props.placeholder && \"placeholder\"\n    ].filter(v => v).join(\" \");\n\n    return (<li className={outerClassName}>\n      <a href={link.type === \"pocket\" ? link.open_url : link.url} onClick={!props.placeholder ? this.onLinkClick : undefined}>\n        <div className=\"card\">\n          <div className=\"card-preview-image-outer\">\n            {hasImage &&\n              <div className={`card-preview-image${this.state.imageLoaded ? \" loaded\" : \"\"}`} style={imageStyle} />\n            }\n          </div>\n          <div className=\"card-details\">\n            {link.type === \"download\" && <div className=\"card-host-name alternate\"><FormattedMessage id={GetPlatformString(this.props.platform)} /></div>}\n            {link.hostname &&\n              <div className=\"card-host-name\">\n                {link.hostname.slice(0, 100)}{link.type === \"download\" && `  \\u2014 ${link.description}`}\n              </div>\n            }\n            <div className={[\n              \"card-text\",\n              icon ? \"\" : \"no-context\",\n              link.description ? \"\" : \"no-description\",\n              link.hostname ? \"\" : \"no-host-name\"\n            ].join(\" \")}>\n              <h4 className=\"card-title\" dir=\"auto\">{link.title}</h4>\n              <p className=\"card-description\" dir=\"auto\">{link.description}</p>\n            </div>\n            <div className=\"card-context\">\n              {icon && !link.context && <span className={`card-context-icon icon icon-${icon}`} />}\n              {link.icon && link.context && <span className=\"card-context-icon icon\" style={{backgroundImage: `url('${link.icon}')`}} />}\n              {intlID && !link.context && <div className=\"card-context-label\"><FormattedMessage id={intlID} defaultMessage=\"Visited\" /></div>}\n              {link.context && <div className=\"card-context-label\">{link.context}</div>}\n            </div>\n          </div>\n        </div>\n      </a>\n      {!props.placeholder && <button className=\"context-menu-button icon\"\n        onClick={this.onMenuButtonClick}>\n        <span className=\"sr-only\">{`Open context menu for ${link.title}`}</span>\n      </button>}\n      {isContextMenuOpen &&\n        <LinkMenu\n          dispatch={dispatch}\n          index={index}\n          source={eventSource}\n          onUpdate={this.onMenuUpdate}\n          options={link.contextMenuOptions || contextMenuOptions}\n          site={link}\n          siteInfo={this._getTelemetryInfo()}\n          shouldSendImpressionStats={shouldSendImpressionStats} />\n      }\n   </li>);\n  }\n}\n_Card.defaultProps = {link: {}};\nexport const Card = connect(state => ({platform: state.Prefs.values.platform}))(_Card);\nexport const PlaceholderCard = props => <Card placeholder={true} className={props.className} />;\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/Card/Card.jsx","export const cardContextTypes = {\n  history: {\n    intlID: \"type_label_visited\",\n    icon: \"history-item\"\n  },\n  bookmark: {\n    intlID: \"type_label_bookmarked\",\n    icon: \"bookmark-added\"\n  },\n  trending: {\n    intlID: \"type_label_recommended\",\n    icon: \"trending\"\n  },\n  now: {\n    intlID: \"type_label_now\",\n    icon: \"now\"\n  },\n  pocket: {\n    intlID: \"type_label_pocket\",\n    icon: \"pocket\"\n  },\n  download: {\n    intlID: \"type_label_downloaded\",\n    icon: \"download\"\n  }\n};\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/Card/types.js","import {actionCreators as ac} from \"common/Actions.jsm\";\nimport {ContextMenu} from \"content-src/components/ContextMenu/ContextMenu\";\nimport {injectIntl} from \"react-intl\";\nimport React from \"react\";\nimport {SectionMenuOptions} from \"content-src/lib/section-menu-options\";\n\nconst DEFAULT_SECTION_MENU_OPTIONS = [\"MoveUp\", \"MoveDown\", \"Separator\", \"RemoveSection\", \"CheckCollapsed\", \"Separator\", \"ManageSection\"];\nconst WEBEXT_SECTION_MENU_OPTIONS = [\"MoveUp\", \"MoveDown\", \"Separator\", \"CheckCollapsed\", \"Separator\", \"ManageWebExtension\"];\n\nexport class _SectionMenu extends React.PureComponent {\n  getOptions() {\n    const {props} = this;\n\n    const propOptions = props.isWebExtension ? [...WEBEXT_SECTION_MENU_OPTIONS] : [...DEFAULT_SECTION_MENU_OPTIONS];\n    // Prepend custom options and a separator\n    if (props.extraOptions) {\n      propOptions.splice(0, 0, ...props.extraOptions, \"Separator\");\n    }\n    // Insert privacy notice before the last option (\"ManageSection\")\n    if (props.privacyNoticeURL) {\n      propOptions.splice(-1, 0, \"PrivacyNotice\");\n    }\n\n    const options = propOptions.map(o => SectionMenuOptions[o](props)).map(option => {\n      const {action, id, type, userEvent} = option;\n      if (!type && id) {\n        option.label = props.intl.formatMessage({id});\n        option.onClick = () => {\n          props.dispatch(action);\n          if (userEvent) {\n            props.dispatch(ac.UserEvent({\n              event: userEvent,\n              source: props.source\n            }));\n          }\n        };\n      }\n      return option;\n    });\n\n    // This is for accessibility to support making each item tabbable.\n    // We want to know which item is the first and which item\n    // is the last, so we can close the context menu accordingly.\n    options[0].first = true;\n    options[options.length - 1].last = true;\n    return options;\n  }\n\n  render() {\n    return (<ContextMenu\n      onUpdate={this.props.onUpdate}\n      options={this.getOptions()} />);\n  }\n}\n\nexport const SectionMenu = injectIntl(_SectionMenu);\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/SectionMenu/SectionMenu.jsx","import {FormattedMessage} from \"react-intl\";\nimport React from \"react\";\n\nexport class Topic extends React.PureComponent {\n  render() {\n    const {url, name} = this.props;\n    return (<li><a key={name} className=\"topic-link\" href={url}>{name}</a></li>);\n  }\n}\n\nexport class Topics extends React.PureComponent {\n  render() {\n    const {topics, read_more_endpoint} = this.props;\n    return (\n      <div className=\"topic\">\n        <span><FormattedMessage id=\"pocket_read_more\" /></span>\n        <ul>{topics && topics.map(t => <Topic key={t.name} url={t.url} name={t.name} />)}</ul>\n\n        {read_more_endpoint && <a className=\"topic-read-more\" href={read_more_endpoint}>\n          <FormattedMessage id=\"pocket_read_even_more\" />\n        </a>}\n      </div>\n    );\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/Topics/Topics.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {MIN_CORNER_FAVICON_SIZE, MIN_RICH_FAVICON_SIZE, TOP_SITES_SOURCE} from \"./TopSitesConstants\";\nimport {CollapsibleSection} from \"content-src/components/CollapsibleSection/CollapsibleSection\";\nimport {ComponentPerfTimer} from \"content-src/components/ComponentPerfTimer/ComponentPerfTimer\";\nimport {connect} from \"react-redux\";\nimport {injectIntl} from \"react-intl\";\nimport React from \"react\";\nimport {TOP_SITES_MAX_SITES_PER_ROW} from \"common/Reducers.jsm\";\nimport {TopSiteForm} from \"./TopSiteForm\";\nimport {TopSiteList} from \"./TopSite\";\n\nfunction topSiteIconType(link) {\n  if (link.customScreenshotURL) {\n    return \"custom_screenshot\";\n  }\n  if (link.tippyTopIcon || link.faviconRef === \"tippytop\") {\n    return \"tippytop\";\n  }\n  if (link.faviconSize >= MIN_RICH_FAVICON_SIZE) {\n    return \"rich_icon\";\n  }\n  if (link.screenshot && link.faviconSize >= MIN_CORNER_FAVICON_SIZE) {\n    return \"screenshot_with_icon\";\n  }\n  if (link.screenshot) {\n    return \"screenshot\";\n  }\n  return \"no_image\";\n}\n\n/**\n * Iterates through TopSites and counts types of images.\n * @param acc Accumulator for reducer.\n * @param topsite Entry in TopSites.\n */\nfunction countTopSitesIconsTypes(topSites) {\n  const countTopSitesTypes = (acc, link) => {\n    acc[topSiteIconType(link)]++;\n    return acc;\n  };\n\n  return topSites.reduce(countTopSitesTypes, {\n    \"custom_screenshot\": 0,\n    \"screenshot_with_icon\": 0,\n    \"screenshot\": 0,\n    \"tippytop\": 0,\n    \"rich_icon\": 0,\n    \"no_image\": 0\n  });\n}\n\nexport class _TopSites extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onFormClose = this.onFormClose.bind(this);\n  }\n\n  /**\n   * Dispatch session statistics about the quality of TopSites icons and pinned count.\n   */\n  _dispatchTopSitesStats() {\n    const topSites = this._getVisibleTopSites();\n    const topSitesIconsStats = countTopSitesIconsTypes(topSites);\n    const topSitesPinned = topSites.filter(site => !!site.isPinned).length;\n    // Dispatch telemetry event with the count of TopSites images types.\n    this.props.dispatch(ac.AlsoToMain({\n      type: at.SAVE_SESSION_PERF_DATA,\n      data: {topsites_icon_stats: topSitesIconsStats, topsites_pinned: topSitesPinned}\n    }));\n  }\n\n  /**\n   * Return the TopSites that are visible based on prefs and window width.\n   */\n  _getVisibleTopSites() {\n    // We hide 2 sites per row when not in the wide layout.\n    let sitesPerRow = TOP_SITES_MAX_SITES_PER_ROW;\n    // $break-point-widest = 1072px (from _variables.scss)\n    if (!global.matchMedia(`(min-width: 1072px)`).matches) {\n      sitesPerRow -= 2;\n    }\n    return this.props.TopSites.rows.slice(0, this.props.TopSitesRows * sitesPerRow);\n  }\n\n  componentDidUpdate() {\n    this._dispatchTopSitesStats();\n  }\n\n  componentDidMount() {\n    this._dispatchTopSitesStats();\n  }\n\n  onFormClose() {\n    this.props.dispatch(ac.UserEvent({\n      source: TOP_SITES_SOURCE,\n      event: \"TOP_SITES_EDIT_CLOSE\"\n    }));\n    this.props.dispatch({type: at.TOP_SITES_CANCEL_EDIT});\n  }\n\n  render() {\n    const {props} = this;\n    const {editForm} = props.TopSites;\n\n    return (<ComponentPerfTimer id=\"topsites\" initialized={props.TopSites.initialized} dispatch={props.dispatch}>\n      <CollapsibleSection\n        className=\"top-sites\"\n        icon=\"topsites\"\n        id=\"topsites\"\n        title={{id: \"header_top_sites\"}}\n        extraMenuOptions={[\"AddTopSite\"]}\n        showPrefName=\"feeds.topsites\"\n        eventSource={TOP_SITES_SOURCE}\n        collapsed={props.TopSites.pref ? props.TopSites.pref.collapsed : undefined}\n        isFirst={props.isFirst}\n        isLast={props.isLast}\n        dispatch={props.dispatch}>\n        <TopSiteList TopSites={props.TopSites} TopSitesRows={props.TopSitesRows} dispatch={props.dispatch} intl={props.intl} topSiteIconType={topSiteIconType} />\n        <div className=\"edit-topsites-wrapper\">\n          {editForm &&\n            <div className=\"edit-topsites\">\n              <div className=\"modal-overlay\" onClick={this.onFormClose} />\n              <div className=\"modal\">\n                <TopSiteForm\n                  site={props.TopSites.rows[editForm.index]}\n                  onClose={this.onFormClose}\n                  dispatch={this.props.dispatch}\n                  intl={this.props.intl}\n                  {...editForm} />\n              </div>\n            </div>\n          }\n        </div>\n      </CollapsibleSection>\n    </ComponentPerfTimer>);\n  }\n}\n\nexport const TopSites = connect(state => ({\n  TopSites: state.TopSites,\n  Prefs: state.Prefs,\n  TopSitesRows: state.Prefs.values.topSitesRows\n}))(injectIntl(_TopSites));\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/TopSites/TopSites.jsx","import {FormattedMessage} from \"react-intl\";\nimport React from \"react\";\n\nexport class TopSiteFormInput extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.state = {validationError: this.props.validationError};\n    this.onChange = this.onChange.bind(this);\n    this.onMount = this.onMount.bind(this);\n  }\n\n  componentWillReceiveProps(nextProps) {\n    if (nextProps.shouldFocus && !this.props.shouldFocus) {\n      this.input.focus();\n    }\n    if (nextProps.validationError && !this.props.validationError) {\n      this.setState({validationError: true});\n    }\n    // If the component is in an error state but the value was cleared by the parent\n    if (this.state.validationError && !nextProps.value) {\n      this.setState({validationError: false});\n    }\n  }\n\n  onChange(ev) {\n    if (this.state.validationError) {\n      this.setState({validationError: false});\n    }\n    this.props.onChange(ev);\n  }\n\n  onMount(input) {\n    this.input = input;\n  }\n\n  render() {\n    const showClearButton = this.props.value && this.props.onClear;\n    const {typeUrl} = this.props;\n    const {validationError} = this.state;\n\n    return (<label><FormattedMessage id={this.props.titleId} />\n      <div className={`field ${typeUrl ? \"url\" : \"\"}${validationError ? \" invalid\" : \"\"}`}>\n        {this.props.loading ?\n          <div className=\"loading-container\"><div className=\"loading-animation\" /></div> :\n          showClearButton && <div className=\"icon icon-clear-input\" onClick={this.props.onClear} />}\n        <input type=\"text\"\n          value={this.props.value}\n          ref={this.onMount}\n          onChange={this.onChange}\n          placeholder={this.props.intl.formatMessage({id: this.props.placeholderId})}\n          autoFocus={this.props.shouldFocus}\n          disabled={this.props.loading} />\n        {validationError &&\n          <aside className=\"error-tooltip\">\n            <FormattedMessage id={this.props.errorMessageId} />\n          </aside>}\n      </div>\n    </label>);\n  }\n}\n\nTopSiteFormInput.defaultProps = {\n  showClearButton: false,\n  value: \"\",\n  validationError: false\n};\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/TopSites/TopSiteFormInput.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {FormattedMessage} from \"react-intl\";\nimport React from \"react\";\nimport {TOP_SITES_SOURCE} from \"./TopSitesConstants\";\nimport {TopSiteFormInput} from \"./TopSiteFormInput\";\nimport {TopSiteLink} from \"./TopSite\";\n\nexport class TopSiteForm extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    const {site} = props;\n    this.state = {\n      label: site ? (site.label || site.hostname) : \"\",\n      url: site ? site.url : \"\",\n      validationError: false,\n      customScreenshotUrl: site ? site.customScreenshotURL : \"\",\n      showCustomScreenshotForm: site ? site.customScreenshotURL : false\n    };\n    this.onClearScreenshotInput = this.onClearScreenshotInput.bind(this);\n    this.onLabelChange = this.onLabelChange.bind(this);\n    this.onUrlChange = this.onUrlChange.bind(this);\n    this.onCancelButtonClick = this.onCancelButtonClick.bind(this);\n    this.onClearUrlClick = this.onClearUrlClick.bind(this);\n    this.onDoneButtonClick = this.onDoneButtonClick.bind(this);\n    this.onCustomScreenshotUrlChange = this.onCustomScreenshotUrlChange.bind(this);\n    this.onPreviewButtonClick = this.onPreviewButtonClick.bind(this);\n    this.onEnableScreenshotUrlForm = this.onEnableScreenshotUrlForm.bind(this);\n    this.validateUrl = this.validateUrl.bind(this);\n  }\n\n  onLabelChange(event) {\n    this.setState({\"label\": event.target.value});\n  }\n\n  onUrlChange(event) {\n    this.setState({\n      url: event.target.value,\n      validationError: false\n    });\n  }\n\n  onClearUrlClick() {\n    this.setState({\n      url: \"\",\n      validationError: false\n    });\n  }\n\n  onEnableScreenshotUrlForm() {\n    this.setState({showCustomScreenshotForm: true});\n  }\n\n  _updateCustomScreenshotInput(customScreenshotUrl) {\n    this.setState({\n      customScreenshotUrl,\n      validationError: false\n    });\n    this.props.dispatch({type: at.PREVIEW_REQUEST_CANCEL});\n  }\n\n  onCustomScreenshotUrlChange(event) {\n    this._updateCustomScreenshotInput(event.target.value);\n  }\n\n  onClearScreenshotInput() {\n    this._updateCustomScreenshotInput(\"\");\n  }\n\n  onCancelButtonClick(ev) {\n    ev.preventDefault();\n    this.props.onClose();\n  }\n\n  onDoneButtonClick(ev) {\n    ev.preventDefault();\n\n    if (this.validateForm()) {\n      const site = {url: this.cleanUrl(this.state.url)};\n      const {index} = this.props;\n      if (this.state.label !== \"\") {\n        site.label = this.state.label;\n      }\n\n      if (this.state.customScreenshotUrl) {\n        site.customScreenshotURL = this.cleanUrl(this.state.customScreenshotUrl);\n      } else if (this.props.site && this.props.site.customScreenshotURL) {\n        // Used to flag that previously cached screenshot should be removed\n        site.customScreenshotURL = null;\n      }\n      this.props.dispatch(ac.AlsoToMain({\n        type: at.TOP_SITES_PIN,\n        data: {site, index}\n      }));\n      this.props.dispatch(ac.UserEvent({\n        source: TOP_SITES_SOURCE,\n        event: \"TOP_SITES_EDIT\",\n        action_position: index\n      }));\n\n      this.props.onClose();\n    }\n  }\n\n  onPreviewButtonClick(event) {\n    event.preventDefault();\n    if (this.validateForm()) {\n      this.props.dispatch(ac.AlsoToMain({\n        type: at.PREVIEW_REQUEST,\n        data: {url: this.cleanUrl(this.state.customScreenshotUrl)}\n      }));\n      this.props.dispatch(ac.UserEvent({\n        source: TOP_SITES_SOURCE,\n        event: \"PREVIEW_REQUEST\"\n      }));\n    }\n  }\n\n  cleanUrl(url) {\n    // If we are missing a protocol, prepend http://\n    if (!url.startsWith(\"http:\") && !url.startsWith(\"https:\")) {\n      return `http://${url}`;\n    }\n    return url;\n  }\n\n  _tryParseUrl(url) {\n    try {\n      return new URL(url);\n    } catch (e) {\n      return null;\n    }\n  }\n\n  validateUrl(url) {\n    const validProtocols = [\"http:\", \"https:\"];\n    const urlObj = this._tryParseUrl(url) || this._tryParseUrl(this.cleanUrl(url));\n\n    return urlObj && validProtocols.includes(urlObj.protocol);\n  }\n\n  validateCustomScreenshotUrl() {\n    const {customScreenshotUrl} = this.state;\n    return !customScreenshotUrl || this.validateUrl(customScreenshotUrl);\n  }\n\n  validateForm() {\n    const validate = this.validateUrl(this.state.url) && this.validateCustomScreenshotUrl();\n\n    if (!validate) {\n      this.setState({validationError: true});\n    }\n\n    return validate;\n  }\n\n  _renderCustomScreenshotInput() {\n    const {customScreenshotUrl} = this.state;\n    const requestFailed = this.props.previewResponse === \"\";\n    const validationError = (this.state.validationError && !this.validateCustomScreenshotUrl()) || requestFailed;\n    // Set focus on error if the url field is valid or when the input is first rendered and is empty\n    const shouldFocus = (validationError && this.validateUrl(this.state.url)) || !customScreenshotUrl;\n    const isLoading = this.props.previewResponse === null &&\n      customScreenshotUrl && this.props.previewUrl === this.cleanUrl(customScreenshotUrl);\n\n    if (!this.state.showCustomScreenshotForm) {\n      return (<a className=\"enable-custom-image-input\" onClick={this.onEnableScreenshotUrlForm}>\n        <FormattedMessage id=\"topsites_form_use_image_link\" />\n      </a>);\n    }\n    return (<div className=\"custom-image-input-container\">\n      <TopSiteFormInput\n        errorMessageId={requestFailed ? \"topsites_form_image_validation\" : \"topsites_form_url_validation\"}\n        loading={isLoading}\n        onChange={this.onCustomScreenshotUrlChange}\n        onClear={this.onClearScreenshotInput}\n        shouldFocus={shouldFocus}\n        typeUrl={true}\n        value={customScreenshotUrl}\n        validationError={validationError}\n        titleId=\"topsites_form_image_url_label\"\n        placeholderId=\"topsites_form_url_placeholder\"\n        intl={this.props.intl} />\n    </div>);\n  }\n\n  render() {\n    const {customScreenshotUrl} = this.state;\n    const requestFailed = this.props.previewResponse === \"\";\n    // For UI purposes, editing without an existing link is \"add\"\n    const showAsAdd = !this.props.site;\n    const previous = (this.props.site && this.props.site.customScreenshotURL) || \"\";\n    const changed = customScreenshotUrl && this.cleanUrl(customScreenshotUrl) !== previous;\n    // Preview mode if changes were made to the custom screenshot URL and no preview was received yet\n    // or the request failed\n    const previewMode = changed && !this.props.previewResponse;\n    const previewLink = Object.assign({}, this.props.site);\n    if (this.props.previewResponse) {\n      previewLink.screenshot = this.props.previewResponse;\n      previewLink.customScreenshotURL = this.props.previewUrl;\n    }\n    return (\n      <form className=\"topsite-form\">\n        <div className=\"form-input-container\">\n          <h3 className=\"section-title\">\n            <FormattedMessage id={showAsAdd ? \"topsites_form_add_header\" : \"topsites_form_edit_header\"} />\n          </h3>\n          <div className=\"fields-and-preview\">\n            <div className=\"form-wrapper\">\n              <TopSiteFormInput onChange={this.onLabelChange}\n                value={this.state.label}\n                titleId=\"topsites_form_title_label\"\n                placeholderId=\"topsites_form_title_placeholder\"\n                intl={this.props.intl} />\n              <TopSiteFormInput onChange={this.onUrlChange}\n                shouldFocus={this.state.validationError && !this.validateUrl(this.state.url)}\n                value={this.state.url}\n                onClear={this.onClearUrlClick}\n                validationError={this.state.validationError && !this.validateUrl(this.state.url)}\n                titleId=\"topsites_form_url_label\"\n                typeUrl={true}\n                placeholderId=\"topsites_form_url_placeholder\"\n                errorMessageId=\"topsites_form_url_validation\"\n                intl={this.props.intl} />\n              {this._renderCustomScreenshotInput()}\n            </div>\n            <TopSiteLink link={previewLink}\n              defaultStyle={requestFailed}\n              title={this.state.label} />\n          </div>\n        </div>\n        <section className=\"actions\">\n          <button className=\"cancel\" type=\"button\" onClick={this.onCancelButtonClick}>\n            <FormattedMessage id=\"topsites_form_cancel_button\" />\n          </button>\n          {previewMode ?\n            <button className=\"done preview\" type=\"submit\" onClick={this.onPreviewButtonClick}>\n              <FormattedMessage id=\"topsites_form_preview_button\" />\n            </button> :\n            <button className=\"done\" type=\"submit\" onClick={this.onDoneButtonClick}>\n              <FormattedMessage id={showAsAdd ? \"topsites_form_add_button\" : \"topsites_form_save_button\"} />\n            </button>}\n        </section>\n      </form>\n    );\n  }\n}\n\nTopSiteForm.defaultProps = {\n  site: null,\n  index: -1\n};\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/TopSites/TopSiteForm.jsx","import {FormattedMessage, injectIntl} from \"react-intl\";\nimport {actionCreators as ac} from \"common/Actions.jsm\";\nimport {connect} from \"react-redux\";\nimport React from \"react\";\n\nexport class _StartupOverlay extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onInputChange = this.onInputChange.bind(this);\n    this.onSubmit = this.onSubmit.bind(this);\n    this.clickSkip = this.clickSkip.bind(this);\n    this.initScene = this.initScene.bind(this);\n    this.removeOverlay = this.removeOverlay.bind(this);\n\n    this.state = {emailInput: \"\"};\n    this.initScene();\n  }\n\n  initScene() {\n    // Timeout to allow the scene to render once before attaching the attribute\n    // to trigger the animation.\n    setTimeout(() => {\n      this.setState({show: true});\n    }, 10);\n  }\n\n  removeOverlay() {\n    window.removeEventListener(\"visibilitychange\", this.removeOverlay);\n    this.setState({show: false});\n    setTimeout(() => {\n      // Allow scrolling and fully remove overlay after animation finishes.\n      document.body.classList.remove(\"welcome\");\n    }, 400);\n  }\n\n  onInputChange(e) {\n    this.setState({emailInput: e.target.value});\n  }\n\n  onSubmit() {\n    this.props.dispatch(ac.UserEvent({event: \"SUBMIT_EMAIL\"}));\n    window.addEventListener(\"visibilitychange\", this.removeOverlay);\n  }\n\n  clickSkip() {\n    this.props.dispatch(ac.UserEvent({event: \"SKIPPED_SIGNIN\"}));\n    this.removeOverlay();\n  }\n\n  render() {\n    let termsLink = (<a href=\"https://accounts.firefox.com/legal/terms\" target=\"_blank\" rel=\"noopener noreferrer\"><FormattedMessage id=\"firstrun_terms_of_service\" /></a>);\n    let privacyLink = (<a href=\"https://accounts.firefox.com/legal/privacy\" target=\"_blank\" rel=\"noopener noreferrer\"><FormattedMessage id=\"firstrun_privacy_notice\" /></a>);\n    return (\n      <div className={`overlay-wrapper ${this.state.show ? \"show \" : \"\"}`}>\n        <div className=\"background\" />\n        <div className=\"firstrun-scene\">\n          <div className=\"fxaccounts-container\">\n            <div className=\"firstrun-left-divider\">\n              <h1 className=\"firstrun-title\"><FormattedMessage id=\"firstrun_title\" /></h1>\n              <p className=\"firstrun-content\"><FormattedMessage id=\"firstrun_content\" /></p>\n              <a className=\"firstrun-link\" href=\"https://www.mozilla.org/firefox/features/sync/\" target=\"_blank\" rel=\"noopener noreferrer\"><FormattedMessage id=\"firstrun_learn_more_link\" /></a>\n            </div>\n            <div className=\"firstrun-sign-in\">\n              <p className=\"form-header\"><FormattedMessage id=\"firstrun_form_header\" /><span><FormattedMessage id=\"firstrun_form_sub_header\" /></span></p>\n              <form method=\"get\" action=\"https://accounts.firefox.com?entrypoint=activity-stream-firstrun&utm_source=activity-stream&utm_campaign=firstrun\" target=\"_blank\" rel=\"noopener noreferrer\" onSubmit={this.onSubmit}>\n                <input name=\"service\" type=\"hidden\" value=\"sync\" />\n                <input name=\"action\" type=\"hidden\" value=\"email\" />\n                <input name=\"context\" type=\"hidden\" value=\"fx_desktop_v3\" />\n                <input className=\"email-input\" name=\"email\" type=\"email\" required=\"true\" placeholder={this.props.intl.formatMessage({id: \"firstrun_email_input_placeholder\"})} onChange={this.onInputChange} />\n                <div className=\"extra-links\">\n                  <FormattedMessage\n                    id=\"firstrun_extra_legal_links\"\n                    values={{\n                      terms: termsLink,\n                      privacy: privacyLink\n                    }} />\n                </div>\n                <button className=\"continue-button\" type=\"submit\"><FormattedMessage id=\"firstrun_continue_to_login\" /></button>\n              </form>\n              <button className=\"skip-button\" disabled={!!this.state.emailInput} onClick={this.clickSkip}><FormattedMessage id=\"firstrun_skip_login\" /></button>\n            </div>\n          </div>\n        </div>\n      </div>\n    );\n  }\n}\n\nexport const StartupOverlay = connect()(injectIntl(_StartupOverlay));\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/components/StartupOverlay/StartupOverlay.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {perfService as perfSvc} from \"common/PerfService.jsm\";\n\nconst VISIBLE = \"visible\";\nconst VISIBILITY_CHANGE_EVENT = \"visibilitychange\";\n\nexport class DetectUserSessionStart {\n  constructor(store, options = {}) {\n    this._store = store;\n    // Overrides for testing\n    this.document = options.document || global.document;\n    this._perfService = options.perfService || perfSvc;\n    this._onVisibilityChange = this._onVisibilityChange.bind(this);\n  }\n\n  /**\n   * sendEventOrAddListener - Notify immediately if the page is already visible,\n   *                    or else set up a listener for when visibility changes.\n   *                    This is needed for accurate session tracking for telemetry,\n   *                    because tabs are pre-loaded.\n   */\n  sendEventOrAddListener() {\n    if (this.document.visibilityState === VISIBLE) {\n      // If the document is already visible, to the user, send a notification\n      // immediately that a session has started.\n      this._sendEvent();\n    } else {\n      // If the document is not visible, listen for when it does become visible.\n      this.document.addEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n    }\n  }\n\n  /**\n   * _sendEvent - Sends a message to the main process to indicate the current\n   *              tab is now visible to the user, includes the\n   *              visibility_event_rcvd_ts time in ms from the UNIX epoch.\n   */\n  _sendEvent() {\n    this._perfService.mark(\"visibility_event_rcvd_ts\");\n\n    try {\n      let visibility_event_rcvd_ts = this._perfService\n        .getMostRecentAbsMarkStartByName(\"visibility_event_rcvd_ts\");\n\n      this._store.dispatch(ac.AlsoToMain({\n        type: at.SAVE_SESSION_PERF_DATA,\n        data: {visibility_event_rcvd_ts}\n      }));\n    } catch (ex) {\n      // If this failed, it's likely because the `privacy.resistFingerprinting`\n      // pref is true.  We should at least not blow up.\n    }\n  }\n\n  /**\n   * _onVisibilityChange - If the visibility has changed to visible, sends a notification\n   *                      and removes the event listener. This should only be called once per tab.\n   */\n  _onVisibilityChange() {\n    if (this.document.visibilityState === VISIBLE) {\n      this._sendEvent();\n      this.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n    }\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./system-addon/content-src/lib/detect-user-session-start.js"],"sourceRoot":""}
\ No newline at end of file
+{"version":3,"sources":["webpack:///webpack/bootstrap 504a0d0d0f6f16b719aa","webpack:///external \"React\"","webpack:///./common/Actions.jsm","webpack:///external \"ReactIntl\"","webpack:///(webpack)/buildin/global.js","webpack:///external \"ReactRedux\"","webpack:///./content-src/components/TopSites/TopSitesConstants.js","webpack:///./common/Dedupe.jsm","webpack:///./common/Reducers.jsm","webpack:///./content-src/asrouter/asrouter-content.jsx","webpack:///./content-src/lib/init-store.js","webpack:///external \"ReactDOM\"","webpack:///./content-src/components/ErrorBoundary/ErrorBoundary.jsx","webpack:///./content-src/lib/link-menu-options.js","webpack:///./content-src/components/LinkMenu/LinkMenu.jsx","webpack:///./content-src/components/ContextMenu/ContextMenu.jsx","webpack:///./content-src/components/CollapsibleSection/CollapsibleSection.jsx","webpack:///./content-src/lib/section-menu-options.js","webpack:///./content-src/components/ComponentPerfTimer/ComponentPerfTimer.jsx","webpack:///./common/PerfService.jsm","webpack:///./content-src/components/TopSites/TopSite.jsx","webpack:///./content-src/activity-stream.jsx","webpack:///./content-src/lib/snippets.js","webpack:///external \"Redux\"","webpack:///./content-src/asrouter/components/ImpressionsWrapper/ImpressionsWrapper.jsx","webpack:///./content-src/asrouter/components/ModalOverlay/ModalOverlay.jsx","webpack:///./content-src/asrouter/templates/OnboardingMessage/OnboardingMessage.jsx","webpack:///./content-src/asrouter/template-utils.js","webpack:///./content-src/asrouter/components/Button/Button.jsx","webpack:///./content-src/asrouter/components/SnippetBase/SnippetBase.jsx","webpack:///./content-src/asrouter/templates/SimpleSnippet/SimpleSnippet.jsx","webpack:///./content-src/components/Base/Base.jsx","webpack:///./content-src/components/ASRouterAdmin/ASRouterAdmin.jsx","webpack:///./content-src/components/ConfirmDialog/ConfirmDialog.jsx","webpack:///./content-src/components/ManualMigration/ManualMigration.jsx","webpack:///./common/PrerenderData.jsm","webpack:///./content-src/components/Search/Search.jsx","webpack:///./content-src/lib/constants.js","webpack:///./content-src/components/Sections/Sections.jsx","webpack:///./content-src/components/Card/Card.jsx","webpack:///./content-src/components/Card/types.js","webpack:///./content-src/components/SectionMenu/SectionMenu.jsx","webpack:///./content-src/components/Topics/Topics.jsx","webpack:///./content-src/components/TopSites/TopSites.jsx","webpack:///./content-src/components/TopSites/TopSiteFormInput.jsx","webpack:///./content-src/components/TopSites/TopSiteForm.jsx","webpack:///./content-src/components/StartupOverlay/StartupOverlay.jsx","webpack:///./content-src/lib/detect-user-session-start.js"],"names":["globalImportContext","Window","BACKGROUND_PROCESS","UI_CODE","actionTypes","type","ASRouterActions","_RouteMessage","action","options","meta","from","to","Error","forEach","o","AlsoToMain","fromTarget","skipLocal","CONTENT_MESSAGE_TYPE","MAIN_MESSAGE_TYPE","OnlyToMain","BroadcastToContent","AlsoToOneContent","target","skipMain","toTarget","OnlyToOneContent","AlsoToPreloaded","PRELOAD_MESSAGE_TYPE","UserEvent","data","TELEMETRY_USER_EVENT","ASRouterUserEvent","AS_ROUTER_TELEMETRY_USER_EVENT","UndesiredEvent","importContext","TELEMETRY_UNDESIRED_EVENT","PerfEvent","TELEMETRY_PERFORMANCE_EVENT","ImpressionStats","TELEMETRY_IMPRESSION_STATS","SetPref","name","value","SET_PREF","WebExtEvent","source","isSendToMain","isBroadcastToContent","isSendToOneContent","isSendToPreloaded","isFromMain","getPortIdOfSender","TOP_SITES_SOURCE","TOP_SITES_CONTEXT_MENU_OPTIONS","MIN_RICH_FAVICON_SIZE","MIN_CORNER_FAVICON_SIZE","Dedupe","constructor","createKey","defaultCreateKey","item","group","groups","globalKeys","Set","result","values","valueMap","Map","key","has","set","push","add","map","m","Array","TOP_SITES_DEFAULT_ROWS","TOP_SITES_MAX_SITES_PER_ROW","dedupe","site","url","INITIAL_STATE","App","initialized","version","Snippets","TopSites","rows","editForm","Prefs","Theme","className","Dialog","visible","Sections","prevState","at","INIT","Object","assign","insertPinned","links","pinned","pinnedUrls","link","newLinks","filter","includes","isPinned","pinIndex","val","index","length","splice","hasMatch","newRows","TOP_SITES_UPDATED","pref","TOP_SITES_PREFS_UPDATED","TOP_SITES_EDIT","previewResponse","TOP_SITES_CANCEL_EDIT","PREVIEW_RESPONSE","previewUrl","preview","PREVIEW_REQUEST","PREVIEW_REQUEST_CANCEL","SCREENSHOT_UPDATED","row","screenshot","PLACES_BOOKMARK_ADDED","bookmarkGuid","bookmarkTitle","dateAdded","bookmarkDateCreated","PLACES_BOOKMARK_REMOVED","newSite","PLACES_LINK_DELETED","DIALOG_OPEN","DIALOG_CANCEL","DELETE_HISTORY_URL","newValues","PREFS_INITIAL_VALUES","PREF_CHANGED","newState","SECTION_DEREGISTER","section","id","SECTION_REGISTER","title","enabled","SECTION_UPDATE","find","card","dedupeConfigurations","dedupeConf","dedupedRows","dedupeFrom","reduce","dedupeSectionId","dedupeSection","s","SECTION_UPDATE_CARD","PLACES_SAVED_TO_POCKET","open_url","pocket_id","PLACES_LINK_BLOCKED","DELETE_FROM_POCKET","ARCHIVE_FROM_POCKET","SNIPPETS_DATA","SNIPPET_BLOCKED","blockList","concat","SNIPPETS_BLOCKLIST_CLEARED","SNIPPETS_RESET","THEME_UPDATE","INCOMING_MESSAGE_NAME","OUTGOING_MESSAGE_NAME","ASRouterUtils","addListener","listener","global","addMessageListener","removeListener","removeMessageListener","sendMessage","sendAsyncMessage","blockById","blockBundle","bundle","executeAction","button_action","button_action_params","unblockById","unblockBundle","getNextMessage","overrideMessage","sendTelemetry","ping","payload","ac","shouldSendImpressionOnUpdate","nextProps","prevProps","message","ASRouterUISurface","React","PureComponent","props","onMessageFromParent","bind","sendImpression","sendUserActionTelemetry","state","extraProps","message_id","eventType","provider","event","onBlockById","clearBundle","setState","componentWillMount","componentWillUnmount","renderSnippets","document","renderOnboarding","render","template","defaultProps","ASRouterContent","containerElement","_mount","getElementById","ReactDOM","_unmount","unmountComponentAtNode","init","uninit","MERGE_STORE_ACTION","EARLY_QUEUED_ACTIONS","SAVE_SESSION_PERF_DATA","PAGE_PRERENDERED","mergeStateReducer","mainReducer","messageMiddleware","store","next","au","rehydrationMiddleware","_didRehydrate","isMergeStoreAction","isRehydrationRequest","NEW_TAB_STATE_REQUEST","_didRequestInitialState","queueEarlyMessageMiddleware","_receivedFromMain","_earlyActionQueue","initStore","reducers","initialState","createStore","combineReducers","applyMiddleware","msg","dispatch","ex","console","error","dump","JSON","stringify","stack","ErrorBoundaryFallback","windowObj","window","onClick","location","reload","defaultClass","ErrorBoundary","hasError","componentDidCatch","info","children","FallbackComponent","_OpenInPrivateWindow","icon","OPEN_PRIVATE_WINDOW","referrer","userEvent","GetPlatformString","platform","LinkMenuOptions","Separator","EmptyItem","RemoveBookmark","DELETE_BOOKMARK_BY_ID","AddBookmark","BOOKMARK_URL","OpenInNewWindow","OPEN_NEW_WINDOW","typedBonus","BlockUrl","eventSource","BLOCK_URL","impression","block","tiles","guid","pos","WebExtDismiss","string_id","WEBEXT_DISMISS","action_position","DeleteUrl","isEnabled","siteInfo","onConfirm","forceBlock","body_string_id","confirm_button_string_id","cancel_button_string_id","ShowFile","SHOW_DOWNLOAD_FILE","OpenFile","OPEN_DOWNLOAD_FILE","CopyDownloadLink","COPY_DOWNLOAD_LINK","GoToDownloadPage","OPEN_LINK","disabled","RemoveDownload","REMOVE_DOWNLOAD_FILE","PinTopSite","TOP_SITES_PIN","UnpinTopSite","TOP_SITES_UNPIN","SaveToPocket","SAVE_TO_POCKET","pocket","DeleteFromPocket","ArchiveFromPocket","EditTopSite","CheckBookmark","CheckPinTopSite","CheckSavedToPocket","CheckBookmarkOrArchive","OpenInPrivateWindow","DEFAULT_SITE_MENU_OPTIONS","_LinkMenu","getOptions","isPrivateBrowsingEnabled","propOptions","isDefault","option","label","intl","formatMessage","userEventData","shouldSendImpressionStats","first","last","onUpdate","getState","LinkMenu","connect","injectIntl","ContextMenu","hideContext","componentDidMount","setTimeout","addEventListener","removeEventListener","stopPropagation","i","ContextMenuItem","onKeyDown","shiftKey","VISIBLE","VISIBILITY_CHANGE_EVENT","getFormattedMessage","Disclaimer","onAcknowledge","disclaimerPref","disclaimer","text","href","button","DisclaimerIntl","_CollapsibleSection","onBodyMount","onHeaderClick","onTransitionEnd","enableOrDisableAnimation","onMenuButtonClick","onMenuButtonMouseEnter","onMenuButtonMouseLeave","onMenuUpdate","enableAnimation","isAnimating","menuButtonHover","showContextMenu","componentWillUpdate","collapsed","sectionBody","scrollHeight","visibilityState","node","undefined","maxHeight","SectionMenuOptions","CheckCollapsed","currentTarget","renderIcon","startsWith","backgroundImage","preventDefault","isCollapsible","extraMenuOptions","showPrefName","privacyNoticeURL","isFirst","isLast","isWebExtension","needsDisclaimer","active","CollapsibleSection","MoveUp","SECTION_MOVE","direction","MoveDown","RemoveSection","CollapseSection","UPDATE_SECTION_PREFS","ExpandSection","ManageSection","SETTINGS_OPEN","ManageWebExtension","OPEN_WEBEXT_SETTINGS","AddTopSite","PrivacyNotice","RECORDED_SECTIONS","ComponentPerfTimer","Component","perfSvc","_sendBadStateEvent","_sendPaintedEvent","_reportMissingData","_timestampHandled","_recordedFirstRender","_maybeSendPaintedEvent","componentDidUpdate","_afterFramePaint","callback","requestAnimationFrame","_maybeSendBadStateEvent","_ensureFirstRenderTsRecorded","mark","dataReadyKey","firstRenderKey","parseInt","getMostRecentAbsMarkStartByName","ChromeUtils","import","usablePerfObj","Services","appShell","hiddenDOMWindow","performance","now","_PerfService","performanceObj","_perf","prototype","str","getEntriesByName","timeOrigin","absNow","entries","mostRecentEntry","startTime","TopSiteLink","onDragEvent","_allowDrop","e","dataTransfer","types","dragged","effectAllowed","setData","blur","defaultStyle","isDraggable","topSiteOuterClassName","isDragged","tippyTopIcon","faviconSize","letterFallback","imageClassName","imageStyle","showSmallFavicon","smallFaviconStyle","smallFaviconFallback","customScreenshotURL","backgroundColor","favicon","draggableProps","onDragEnd","onDragStart","onMouseDown","TopSite","onLinkClick","_getTelemetryInfo","icon_type","iconType","card_type","altKey","ctrlKey","metaKey","onActivate","isContextMenuOpen","activeIndex","hostname","TopSitePlaceholder","onEditButtonClick","_TopSiteList","DEFAULT_STATE","draggedIndex","draggedSite","draggedTitle","topSitesPreview","componentWillReceiveProps","prevTopSites","newTopSites","dropped","_makeTopSitesPreview","TOP_SITES_INSERT","draggedFromIndex","_getTopSites","topSites","slice","TopSitesRows","pinnedOnly","unpinned","siteToInsert","holeIndex","indexStep","shiftingStep","nextIndex","shift","topSitesUI","commonProps","maxNarrowVisibleIndex","l","topSiteIconType","slotProps","TopSiteList","gActivityStreamPrerenderedState","sendEventOrAddListener","hydrate","documentElement","lang","gActivityStreamStrings","addSnippetsSubscriber","DATABASE_NAME","DATABASE_VERSION","SNIPPETS_OBJECTSTORE_NAME","SNIPPETS_UPDATE_INTERVAL_MS","SNIPPETS_ENABLED_EVENT","SNIPPETS_DISABLED_EVENT","SnippetsMap","_db","_dispatch","_dbTransaction","db","put","delete","clear","get","blockSnippetById","SNIPPETS_BLOCKLIST_UPDATED","disableOnboarding","DISABLE_ONBOARDING","showFirefoxAccounts","SHOW_FIREFOX_ACCOUNTS","getTotalBookmarksCount","Promise","resolve","TOTAL_BOOKMARKS_REQUEST","onMessage","TOTAL_BOOKMARKS_RESPONSE","getAddonsInfo","ADDONS_INFO_REQUEST","ADDONS_INFO_RESPONSE","_openDB","_restoreFromDb","modifier","reject","transaction","objectStore","onsuccess","onerror","openRequest","indexedDB","open","deleteDatabase","onupgradeneeded","objectStoreNames","contains","createObjectStore","err","onversionchange","versionChangeEvent","close","cursorRequest","openCursor","cursor","continue","SnippetsProvider","gSnippetsMap","_onAction","snippetsMap","_refreshSnippets","cachedVersion","appData","lastUpdate","needsUpdate","Date","snippetsURL","response","fetch","status","_noSnippetFallback","_forceOnboardingVisibility","shouldBeVisible","onboardingEl","style","display","_showRemoteSnippets","snippetsEl","elementId","innerHTML","scriptEl","getElementsByTagName","relocatedScript","createElement","parentNode","replaceChild","keys","dispatchEvent","Event","snippets","asrouterContent","initializing","subscribe","asrouterExperimentEnabled","disableSnippets","ImpressionsWrapper","sendImpressionOrAddListener","_onVisibilityChange","sendOnMount","body","classList","remove","button_label","onDoneButton","UISurface","onAction","content","safeURI","protocol","URL","isAllowed","warn","ALLOWED_STYLE_TAGS","Button","tag","border","onBlockClicked","onBlock","containerClassName","DEFAULT_ICON_PATH","onButtonClick","renderTitle","renderTitleIcon","titleIcon","title_icon","renderButton","button_url","button_color","button_background_color","hasLink","button_type","hasButton","tall","PrefsButton","addLocaleDataForReactIntl","locale","addLocaleData","parentLocale","_Base","updateTheme","sendNewTabRehydrated","isPrerendered","bodyClassName","isFirstrun","v","join","renderNotified","NEW_TAB_REHYDRATED","strings","hash","BaseContent","openPreferences","prefs","shouldBeFixedToTop","PrerenderData","arePrefsValid","outerClassName","showSearch","migrationExpired","Base","ASRouterAdmin","findOtherBundledMessagesOfSameTemplate","messages","bundled","handleBlock","handleUnblock","handleOverride","renderMessageItem","isCurrent","lastMessageId","isBlocked","itemClassName","renderMessages","renderProviders","providers","_ConfirmDialog","_handleCancelBtn","_handleConfirmBtn","_renderModalMessage","message_body","ConfirmDialog","_ManualMigration","onLaunchTour","onCancelTour","MIGRATION_START","MIGRATION_CANCEL","ManualMigration","_PrerenderData","initialPrefs","initialSections","_setValidation","validation","_validation","invalidatingPrefs","_invalidatingPrefs","oneOf","getPref","indexedDBPrefs","some","anyModifiedPrefs","prefName","order","_Search","onInputMount","handleEvent","detail","gContentSearchController","search","input","healthReportKey","IS_NEWTAB","searchSource","ContentSearchUIController","Search","documentURI","CARDS_PER_ROW_DEFAULT","CARDS_PER_ROW_COMPACT_WIDE","Section","numRows","rowsPref","maxRows","_dispatchImpressionStats","cardsPerRow","compactCards","matchMedia","matches","maxCards","cards","needsImpressionStats","impressionCardGuids","sendImpressionStatsOrAddListener","isCollapsed","wasCollapsed","emptyState","contextMenuOptions","maxCardsPerRow","maxCardsOnNarrow","shouldShowTopics","topics","realRows","shouldShowEmptyState","sectionClassName","feed","padding","read_more_endpoint","SectionIntl","_Sections","renderSections","sections","enabledSections","sectionOrder","showTopSites","expectedCount","sectionId","split","gImageLoading","_Card","activeCard","imageLoaded","cardImage","maybeLoadImage","imageUrl","loaderPromise","loader","Image","src","catch","then","isImageInState","image","isLocalImageObject","path","getNextStateFromProps","imageInState","nextState","maybeRevokeImageBlob","createObjectURL","revokeObjectURL","WEBEXT_CLICK","click","intlID","cardContextTypes","hasImage","placeholder","description","context","Card","PlaceholderCard","history","bookmark","trending","download","DEFAULT_SECTION_MENU_OPTIONS","WEBEXT_SECTION_MENU_OPTIONS","_SectionMenu","extraOptions","SectionMenu","Topic","Topics","t","faviconRef","countTopSitesIconsTypes","countTopSitesTypes","acc","_TopSites","onFormClose","_dispatchTopSitesStats","_getVisibleTopSites","topSitesIconsStats","topSitesPinned","topsites_icon_stats","topsites_pinned","sitesPerRow","topSitesRows","validationError","onChange","onMount","shouldFocus","focus","ev","showClearButton","onClear","typeUrl","titleId","loading","placeholderId","errorMessageId","TopSiteFormInput","customScreenshotUrl","showCustomScreenshotForm","onClearScreenshotInput","onLabelChange","onUrlChange","onCancelButtonClick","onClearUrlClick","onDoneButtonClick","onCustomScreenshotUrlChange","onPreviewButtonClick","onEnableScreenshotUrlForm","validateUrl","_updateCustomScreenshotInput","onClose","validateForm","cleanUrl","_tryParseUrl","validProtocols","urlObj","validateCustomScreenshotUrl","validate","_renderCustomScreenshotInput","requestFailed","isLoading","showAsAdd","previous","changed","previewMode","previewLink","TopSiteForm","_StartupOverlay","onInputChange","onSubmit","clickSkip","initScene","removeOverlay","emailInput","show","termsLink","privacyLink","terms","privacy","StartupOverlay","DetectUserSessionStart","_store","_perfService","perfService","_sendEvent","visibility_event_rcvd_ts"],"mappings":"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","file":"activity-stream.bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 19);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 504a0d0d0f6f16b719aa","module.exports = React;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"React\"\n// module id = 0\n// module chunks = 0","/* 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\"use strict\";\n\nthis.MAIN_MESSAGE_TYPE = \"ActivityStream:Main\";\nthis.CONTENT_MESSAGE_TYPE = \"ActivityStream:Content\";\nthis.PRELOAD_MESSAGE_TYPE = \"ActivityStream:PreloadedBrowser\";\nthis.UI_CODE = 1;\nthis.BACKGROUND_PROCESS = 2;\n\n/**\n * globalImportContext - Are we in UI code (i.e. react, a dom) or some kind of background process?\n *                       Use this in action creators if you need different logic\n *                       for ui/background processes.\n */\nconst globalImportContext = typeof Window === \"undefined\" ? BACKGROUND_PROCESS : UI_CODE;\n// Export for tests\nthis.globalImportContext = globalImportContext;\n\n// Create an object that avoids accidental differing key/value pairs:\n// {\n//   INIT: \"INIT\",\n//   UNINIT: \"UNINIT\"\n// }\nconst actionTypes = {};\nfor (const type of [\n  \"ADDONS_INFO_REQUEST\",\n  \"ADDONS_INFO_RESPONSE\",\n  \"ARCHIVE_FROM_POCKET\",\n  \"AS_ROUTER_TELEMETRY_USER_EVENT\",\n  \"BLOCK_URL\",\n  \"BOOKMARK_URL\",\n  \"COPY_DOWNLOAD_LINK\",\n  \"DELETE_BOOKMARK_BY_ID\",\n  \"DELETE_FROM_POCKET\",\n  \"DELETE_HISTORY_URL\",\n  \"DIALOG_CANCEL\",\n  \"DIALOG_OPEN\",\n  \"DISABLE_ONBOARDING\",\n  \"DOWNLOAD_CHANGED\",\n  \"INIT\",\n  \"MIGRATION_CANCEL\",\n  \"MIGRATION_COMPLETED\",\n  \"MIGRATION_START\",\n  \"NEW_TAB_INIT\",\n  \"NEW_TAB_INITIAL_STATE\",\n  \"NEW_TAB_LOAD\",\n  \"NEW_TAB_REHYDRATED\",\n  \"NEW_TAB_STATE_REQUEST\",\n  \"NEW_TAB_UNLOAD\",\n  \"OPEN_DOWNLOAD_FILE\",\n  \"OPEN_LINK\",\n  \"OPEN_NEW_WINDOW\",\n  \"OPEN_PRIVATE_WINDOW\",\n  \"OPEN_WEBEXT_SETTINGS\",\n  \"PAGE_PRERENDERED\",\n  \"PLACES_BOOKMARK_ADDED\",\n  \"PLACES_BOOKMARK_REMOVED\",\n  \"PLACES_HISTORY_CLEARED\",\n  \"PLACES_LINKS_CHANGED\",\n  \"PLACES_LINK_BLOCKED\",\n  \"PLACES_LINK_DELETED\",\n  \"PLACES_SAVED_TO_POCKET\",\n  \"PREFS_INITIAL_VALUES\",\n  \"PREF_CHANGED\",\n  \"PREVIEW_REQUEST\",\n  \"PREVIEW_REQUEST_CANCEL\",\n  \"PREVIEW_RESPONSE\",\n  \"REMOVE_DOWNLOAD_FILE\",\n  \"RICH_ICON_MISSING\",\n  \"SAVE_SESSION_PERF_DATA\",\n  \"SAVE_TO_POCKET\",\n  \"SCREENSHOT_UPDATED\",\n  \"SECTION_DEREGISTER\",\n  \"SECTION_DISABLE\",\n  \"SECTION_ENABLE\",\n  \"SECTION_MOVE\",\n  \"SECTION_OPTIONS_CHANGED\",\n  \"SECTION_REGISTER\",\n  \"SECTION_UPDATE\",\n  \"SECTION_UPDATE_CARD\",\n  \"SETTINGS_CLOSE\",\n  \"SETTINGS_OPEN\",\n  \"SET_PREF\",\n  \"SHOW_DOWNLOAD_FILE\",\n  \"SHOW_FIREFOX_ACCOUNTS\",\n  \"SKIPPED_SIGNIN\",\n  \"SNIPPETS_BLOCKLIST_CLEARED\",\n  \"SNIPPETS_BLOCKLIST_UPDATED\",\n  \"SNIPPETS_DATA\",\n  \"SNIPPETS_RESET\",\n  \"SNIPPET_BLOCKED\",\n  \"SUBMIT_EMAIL\",\n  \"SYSTEM_TICK\",\n  \"TELEMETRY_IMPRESSION_STATS\",\n  \"TELEMETRY_PERFORMANCE_EVENT\",\n  \"TELEMETRY_UNDESIRED_EVENT\",\n  \"TELEMETRY_USER_EVENT\",\n  \"THEME_UPDATE\",\n  \"TOP_SITES_CANCEL_EDIT\",\n  \"TOP_SITES_EDIT\",\n  \"TOP_SITES_INSERT\",\n  \"TOP_SITES_PIN\",\n  \"TOP_SITES_PREFS_UPDATED\",\n  \"TOP_SITES_UNPIN\",\n  \"TOP_SITES_UPDATED\",\n  \"TOTAL_BOOKMARKS_REQUEST\",\n  \"TOTAL_BOOKMARKS_RESPONSE\",\n  \"UNINIT\",\n  \"UPDATE_SECTION_PREFS\",\n  \"WEBEXT_CLICK\",\n  \"WEBEXT_DISMISS\"\n]) {\n  actionTypes[type] = type;\n}\n\n// These are acceptable actions for AS Router messages to have. They can show up\n// as call-to-action buttons in snippets, onboarding tour, etc.\nconst ASRouterActions = {};\nfor (const type of [\n  \"OPEN_PRIVATE_BROWSER_WINDOW\",\n  \"OPEN_URL\",\n  \"OPEN_ABOUT_PAGE\"\n]) {\n  ASRouterActions[type] = type;\n}\n\n// Helper function for creating routed actions between content and main\n// Not intended to be used by consumers\nfunction _RouteMessage(action, options) {\n  const meta = action.meta ? {...action.meta} : {};\n  if (!options || !options.from || !options.to) {\n    throw new Error(\"Routed Messages must have options as the second parameter, and must at least include a .from and .to property.\");\n  }\n  // For each of these fields, if they are passed as an option,\n  // add them to the action. If they are not defined, remove them.\n  [\"from\", \"to\", \"toTarget\", \"fromTarget\", \"skipMain\", \"skipLocal\"].forEach(o => {\n    if (typeof options[o] !== \"undefined\") {\n      meta[o] = options[o];\n    } else if (meta[o]) {\n      delete meta[o];\n    }\n  });\n  return {...action, meta};\n}\n\n/**\n * AlsoToMain - Creates a message that will be dispatched locally and also sent to the Main process.\n *\n * @param  {object} action Any redux action (required)\n * @param  {object} options\n * @param  {bool}   skipLocal Used by OnlyToMain to skip the main reducer\n * @param  {string} fromTarget The id of the content port from which the action originated. (optional)\n * @return {object} An action with added .meta properties\n */\nfunction AlsoToMain(action, fromTarget, skipLocal) {\n  return _RouteMessage(action, {\n    from: CONTENT_MESSAGE_TYPE,\n    to: MAIN_MESSAGE_TYPE,\n    fromTarget,\n    skipLocal\n  });\n}\n\n/**\n * OnlyToMain - Creates a message that will be sent to the Main process and skip the local reducer.\n *\n * @param  {object} action Any redux action (required)\n * @param  {object} options\n * @param  {string} fromTarget The id of the content port from which the action originated. (optional)\n * @return {object} An action with added .meta properties\n */\nfunction OnlyToMain(action, fromTarget) {\n  return AlsoToMain(action, fromTarget, true);\n}\n\n/**\n * BroadcastToContent - Creates a message that will be dispatched to main and sent to ALL content processes.\n *\n * @param  {object} action Any redux action (required)\n * @return {object} An action with added .meta properties\n */\nfunction BroadcastToContent(action) {\n  return _RouteMessage(action, {\n    from: MAIN_MESSAGE_TYPE,\n    to: CONTENT_MESSAGE_TYPE\n  });\n}\n\n/**\n * AlsoToOneContent - Creates a message that will be will be dispatched to the main store\n *                    and also sent to a particular Content process.\n *\n * @param  {object} action Any redux action (required)\n * @param  {string} target The id of a content port\n * @param  {bool} skipMain Used by OnlyToOneContent to skip the main process\n * @return {object} An action with added .meta properties\n */\nfunction AlsoToOneContent(action, target, skipMain) {\n  if (!target) {\n    throw new Error(\"You must provide a target ID as the second parameter of AlsoToOneContent. If you want to send to all content processes, use BroadcastToContent\");\n  }\n  return _RouteMessage(action, {\n    from: MAIN_MESSAGE_TYPE,\n    to: CONTENT_MESSAGE_TYPE,\n    toTarget: target,\n    skipMain\n  });\n}\n\n/**\n * OnlyToOneContent - Creates a message that will be sent to a particular Content process\n *                    and skip the main reducer.\n *\n * @param  {object} action Any redux action (required)\n * @param  {string} target The id of a content port\n * @return {object} An action with added .meta properties\n */\nfunction OnlyToOneContent(action, target) {\n  return AlsoToOneContent(action, target, true);\n}\n\n/**\n * AlsoToPreloaded - Creates a message that dispatched to the main reducer and also sent to the preloaded tab.\n *\n * @param  {object} action Any redux action (required)\n * @return {object} An action with added .meta properties\n */\nfunction AlsoToPreloaded(action) {\n  return _RouteMessage(action, {\n    from: MAIN_MESSAGE_TYPE,\n    to: PRELOAD_MESSAGE_TYPE\n  });\n}\n\n/**\n * UserEvent - A telemetry ping indicating a user action. This should only\n *                   be sent from the UI during a user session.\n *\n * @param  {object} data Fields to include in the ping (source, etc.)\n * @return {object} An AlsoToMain action\n */\nfunction UserEvent(data) {\n  return AlsoToMain({\n    type: actionTypes.TELEMETRY_USER_EVENT,\n    data\n  });\n}\n\n/**\n * ASRouterUserEvent - A telemetry ping indicating a user action from AS router. This should only\n *                     be sent from the UI during a user session.\n *\n * @param  {object} data Fields to include in the ping (source, etc.)\n * @return {object} An AlsoToMain action\n */\nfunction ASRouterUserEvent(data) {\n  return AlsoToMain({\n    type: actionTypes.AS_ROUTER_TELEMETRY_USER_EVENT,\n    data\n  });\n}\n\n/**\n * UndesiredEvent - A telemetry ping indicating an undesired state.\n *\n * @param  {object} data Fields to include in the ping (value, etc.)\n * @param  {int} importContext (For testing) Override the import context for testing.\n * @return {object} An action. For UI code, a AlsoToMain action.\n */\nfunction UndesiredEvent(data, importContext = globalImportContext) {\n  const action = {\n    type: actionTypes.TELEMETRY_UNDESIRED_EVENT,\n    data\n  };\n  return importContext === UI_CODE ? AlsoToMain(action) : action;\n}\n\n/**\n * PerfEvent - A telemetry ping indicating a performance-related event.\n *\n * @param  {object} data Fields to include in the ping (value, etc.)\n * @param  {int} importContext (For testing) Override the import context for testing.\n * @return {object} An action. For UI code, a AlsoToMain action.\n */\nfunction PerfEvent(data, importContext = globalImportContext) {\n  const action = {\n    type: actionTypes.TELEMETRY_PERFORMANCE_EVENT,\n    data\n  };\n  return importContext === UI_CODE ? AlsoToMain(action) : action;\n}\n\n/**\n * ImpressionStats - A telemetry ping indicating an impression stats.\n *\n * @param  {object} data Fields to include in the ping\n * @param  {int} importContext (For testing) Override the import context for testing.\n * #return {object} An action. For UI code, a AlsoToMain action.\n */\nfunction ImpressionStats(data, importContext = globalImportContext) {\n  const action = {\n    type: actionTypes.TELEMETRY_IMPRESSION_STATS,\n    data\n  };\n  return importContext === UI_CODE ? AlsoToMain(action) : action;\n}\n\nfunction SetPref(name, value, importContext = globalImportContext) {\n  const action = {type: actionTypes.SET_PREF, data: {name, value}};\n  return importContext === UI_CODE ? AlsoToMain(action) : action;\n}\n\nfunction WebExtEvent(type, data, importContext = globalImportContext) {\n  if (!data || !data.source) {\n    throw new Error(\"WebExtEvent actions should include a property \\\"source\\\", the id of the webextension that should receive the event.\");\n  }\n  const action = {type, data};\n  return importContext === UI_CODE ? AlsoToMain(action) : action;\n}\n\nthis.actionTypes = actionTypes;\nthis.ASRouterActions = ASRouterActions;\n\nthis.actionCreators = {\n  BroadcastToContent,\n  UserEvent,\n  ASRouterUserEvent,\n  UndesiredEvent,\n  PerfEvent,\n  ImpressionStats,\n  AlsoToOneContent,\n  OnlyToOneContent,\n  AlsoToMain,\n  OnlyToMain,\n  AlsoToPreloaded,\n  SetPref,\n  WebExtEvent\n};\n\n// These are helpers to test for certain kinds of actions\nthis.actionUtils = {\n  isSendToMain(action) {\n    if (!action.meta) {\n      return false;\n    }\n    return action.meta.to === MAIN_MESSAGE_TYPE && action.meta.from === CONTENT_MESSAGE_TYPE;\n  },\n  isBroadcastToContent(action) {\n    if (!action.meta) {\n      return false;\n    }\n    if (action.meta.to === CONTENT_MESSAGE_TYPE && !action.meta.toTarget) {\n      return true;\n    }\n    return false;\n  },\n  isSendToOneContent(action) {\n    if (!action.meta) {\n      return false;\n    }\n    if (action.meta.to === CONTENT_MESSAGE_TYPE && action.meta.toTarget) {\n      return true;\n    }\n    return false;\n  },\n  isSendToPreloaded(action) {\n    if (!action.meta) {\n      return false;\n    }\n    return action.meta.to === PRELOAD_MESSAGE_TYPE &&\n      action.meta.from === MAIN_MESSAGE_TYPE;\n  },\n  isFromMain(action) {\n    if (!action.meta) {\n      return false;\n    }\n    return action.meta.from === MAIN_MESSAGE_TYPE &&\n      action.meta.to === CONTENT_MESSAGE_TYPE;\n  },\n  getPortIdOfSender(action) {\n    return (action.meta && action.meta.fromTarget) || null;\n  },\n  _RouteMessage\n};\n\nconst EXPORTED_SYMBOLS = [\n  \"actionTypes\",\n  \"actionCreators\",\n  \"actionUtils\",\n  \"ASRouterActions\",\n  \"globalImportContext\",\n  \"UI_CODE\",\n  \"BACKGROUND_PROCESS\",\n  \"MAIN_MESSAGE_TYPE\",\n  \"CONTENT_MESSAGE_TYPE\",\n  \"PRELOAD_MESSAGE_TYPE\"\n];\n\n\n\n// WEBPACK FOOTER //\n// ./common/Actions.jsm","module.exports = ReactIntl;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"ReactIntl\"\n// module id = 2\n// module chunks = 0","var g;\r\n\r\n// This works in non-strict mode\r\ng = (function() {\r\n\treturn this;\r\n})();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === \"object\")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it's\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/global.js\n// module id = 3\n// module chunks = 0","module.exports = ReactRedux;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"ReactRedux\"\n// module id = 4\n// module chunks = 0","export const TOP_SITES_SOURCE = \"TOP_SITES\";\nexport const TOP_SITES_CONTEXT_MENU_OPTIONS = [\"CheckPinTopSite\", \"EditTopSite\", \"Separator\",\n  \"OpenInNewWindow\", \"OpenInPrivateWindow\", \"Separator\", \"BlockUrl\", \"DeleteUrl\"];\n// minimum size necessary to show a rich icon instead of a screenshot\nexport const MIN_RICH_FAVICON_SIZE = 96;\n// minimum size necessary to show any icon in the top left corner with a screenshot\nexport const MIN_CORNER_FAVICON_SIZE = 16;\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/TopSites/TopSitesConstants.js","this.Dedupe = class Dedupe {\n  constructor(createKey) {\n    this.createKey = createKey || this.defaultCreateKey;\n  }\n\n  defaultCreateKey(item) {\n    return item;\n  }\n\n  /**\n   * Dedupe any number of grouped elements favoring those from earlier groups.\n   *\n   * @param {Array} groups Contains an arbitrary number of arrays of elements.\n   * @returns {Array} A matching array of each provided group deduped.\n   */\n  group(...groups) {\n    const globalKeys = new Set();\n    const result = [];\n    for (const values of groups) {\n      const valueMap = new Map();\n      for (const value of values) {\n        const key = this.createKey(value);\n        if (!globalKeys.has(key) && !valueMap.has(key)) {\n          valueMap.set(key, value);\n        }\n      }\n      result.push(valueMap);\n      valueMap.forEach((value, key) => globalKeys.add(key));\n    }\n    return result.map(m => Array.from(m.values()));\n  }\n};\n\nconst EXPORTED_SYMBOLS = [\"Dedupe\"];\n\n\n\n// WEBPACK FOOTER //\n// ./common/Dedupe.jsm","/* 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\"use strict\";\n\nconst {actionTypes: at} = ChromeUtils.import(\"resource://activity-stream/common/Actions.jsm\", {});\nconst {Dedupe} = ChromeUtils.import(\"resource://activity-stream/common/Dedupe.jsm\", {});\n\nconst TOP_SITES_DEFAULT_ROWS = 1;\nconst TOP_SITES_MAX_SITES_PER_ROW = 8;\n\nconst dedupe = new Dedupe(site => site && site.url);\n\nconst INITIAL_STATE = {\n  App: {\n    // Have we received real data from the app yet?\n    initialized: false,\n    // The version of the system-addon\n    version: null\n  },\n  Snippets: {initialized: false},\n  TopSites: {\n    // Have we received real data from history yet?\n    initialized: false,\n    // The history (and possibly default) links\n    rows: [],\n    // Used in content only to dispatch action to TopSiteForm.\n    editForm: null\n  },\n  Prefs: {\n    initialized: false,\n    values: {}\n  },\n  Theme: {className: \"\"},\n  Dialog: {\n    visible: false,\n    data: {}\n  },\n  Sections: []\n};\n\nfunction App(prevState = INITIAL_STATE.App, action) {\n  switch (action.type) {\n    case at.INIT:\n      return Object.assign({}, prevState, action.data || {}, {initialized: true});\n    default:\n      return prevState;\n  }\n}\n\n/**\n * insertPinned - Inserts pinned links in their specified slots\n *\n * @param {array} a list of links\n * @param {array} a list of pinned links\n * @return {array} resulting list of links with pinned links inserted\n */\nfunction insertPinned(links, pinned) {\n  // Remove any pinned links\n  const pinnedUrls = pinned.map(link => link && link.url);\n  let newLinks = links.filter(link => (link ? !pinnedUrls.includes(link.url) : false));\n  newLinks = newLinks.map(link => {\n    if (link && link.isPinned) {\n      delete link.isPinned;\n      delete link.pinIndex;\n    }\n    return link;\n  });\n\n  // Then insert them in their specified location\n  pinned.forEach((val, index) => {\n    if (!val) { return; }\n    let link = Object.assign({}, val, {isPinned: true, pinIndex: index});\n    if (index > newLinks.length) {\n      newLinks[index] = link;\n    } else {\n      newLinks.splice(index, 0, link);\n    }\n  });\n\n  return newLinks;\n}\n\nfunction TopSites(prevState = INITIAL_STATE.TopSites, action) {\n  let hasMatch;\n  let newRows;\n  switch (action.type) {\n    case at.TOP_SITES_UPDATED:\n      if (!action.data || !action.data.links) {\n        return prevState;\n      }\n      return Object.assign({}, prevState, {initialized: true, rows: action.data.links}, action.data.pref ? {pref: action.data.pref} : {});\n    case at.TOP_SITES_PREFS_UPDATED:\n      return Object.assign({}, prevState, {pref: action.data.pref});\n    case at.TOP_SITES_EDIT:\n      return Object.assign({}, prevState, {\n        editForm: {\n          index: action.data.index,\n          previewResponse: null\n        }\n      });\n    case at.TOP_SITES_CANCEL_EDIT:\n      return Object.assign({}, prevState, {editForm: null});\n    case at.PREVIEW_RESPONSE:\n      if (!prevState.editForm || action.data.url !== prevState.editForm.previewUrl) {\n        return prevState;\n      }\n      return Object.assign({}, prevState, {\n        editForm: {\n          index: prevState.editForm.index,\n          previewResponse: action.data.preview,\n          previewUrl: action.data.url\n        }\n      });\n    case at.PREVIEW_REQUEST:\n      if (!prevState.editForm) {\n        return prevState;\n      }\n      return Object.assign({}, prevState, {\n        editForm: {\n          index: prevState.editForm.index,\n          previewResponse: null,\n          previewUrl: action.data.url\n        }\n      });\n    case at.PREVIEW_REQUEST_CANCEL:\n      if (!prevState.editForm) {\n        return prevState;\n      }\n      return Object.assign({}, prevState, {\n        editForm: {\n          index: prevState.editForm.index,\n          previewResponse: null\n        }\n      });\n    case at.SCREENSHOT_UPDATED:\n      newRows = prevState.rows.map(row => {\n        if (row && row.url === action.data.url) {\n          hasMatch = true;\n          return Object.assign({}, row, {screenshot: action.data.screenshot});\n        }\n        return row;\n      });\n      return hasMatch ? Object.assign({}, prevState, {rows: newRows}) : prevState;\n    case at.PLACES_BOOKMARK_ADDED:\n      if (!action.data) {\n        return prevState;\n      }\n      newRows = prevState.rows.map(site => {\n        if (site && site.url === action.data.url) {\n          const {bookmarkGuid, bookmarkTitle, dateAdded} = action.data;\n          return Object.assign({}, site, {bookmarkGuid, bookmarkTitle, bookmarkDateCreated: dateAdded});\n        }\n        return site;\n      });\n      return Object.assign({}, prevState, {rows: newRows});\n    case at.PLACES_BOOKMARK_REMOVED:\n      if (!action.data) {\n        return prevState;\n      }\n      newRows = prevState.rows.map(site => {\n        if (site && site.url === action.data.url) {\n          const newSite = Object.assign({}, site);\n          delete newSite.bookmarkGuid;\n          delete newSite.bookmarkTitle;\n          delete newSite.bookmarkDateCreated;\n          return newSite;\n        }\n        return site;\n      });\n      return Object.assign({}, prevState, {rows: newRows});\n    case at.PLACES_LINK_DELETED:\n      if (!action.data) {\n        return prevState;\n      }\n      newRows = prevState.rows.filter(site => action.data.url !== site.url);\n      return Object.assign({}, prevState, {rows: newRows});\n    default:\n      return prevState;\n  }\n}\n\nfunction Dialog(prevState = INITIAL_STATE.Dialog, action) {\n  switch (action.type) {\n    case at.DIALOG_OPEN:\n      return Object.assign({}, prevState, {visible: true, data: action.data});\n    case at.DIALOG_CANCEL:\n      return Object.assign({}, prevState, {visible: false});\n    case at.DELETE_HISTORY_URL:\n      return Object.assign({}, INITIAL_STATE.Dialog);\n    default:\n      return prevState;\n  }\n}\n\nfunction Prefs(prevState = INITIAL_STATE.Prefs, action) {\n  let newValues;\n  switch (action.type) {\n    case at.PREFS_INITIAL_VALUES:\n      return Object.assign({}, prevState, {initialized: true, values: action.data});\n    case at.PREF_CHANGED:\n      newValues = Object.assign({}, prevState.values);\n      newValues[action.data.name] = action.data.value;\n      return Object.assign({}, prevState, {values: newValues});\n    default:\n      return prevState;\n  }\n}\n\nfunction Sections(prevState = INITIAL_STATE.Sections, action) {\n  let hasMatch;\n  let newState;\n  switch (action.type) {\n    case at.SECTION_DEREGISTER:\n      return prevState.filter(section => section.id !== action.data);\n    case at.SECTION_REGISTER:\n      // If section exists in prevState, update it\n      newState = prevState.map(section => {\n        if (section && section.id === action.data.id) {\n          hasMatch = true;\n          return Object.assign({}, section, action.data);\n        }\n        return section;\n      });\n      // Otherwise, append it\n      if (!hasMatch) {\n        const initialized = !!(action.data.rows && action.data.rows.length > 0);\n        const section = Object.assign({title: \"\", rows: [], enabled: false}, action.data, {initialized});\n        newState.push(section);\n      }\n      return newState;\n    case at.SECTION_UPDATE:\n      newState = prevState.map(section => {\n        if (section && section.id === action.data.id) {\n          // If the action is updating rows, we should consider initialized to be true.\n          // This can be overridden if initialized is defined in the action.data\n          const initialized = action.data.rows ? {initialized: true} : {};\n\n          // Make sure pinned cards stay at their current position when rows are updated.\n          // Disabling a section (SECTION_UPDATE with empty rows) does not retain pinned cards.\n          if (action.data.rows && action.data.rows.length > 0 && section.rows.find(card => card.pinned)) {\n            const rows = Array.from(action.data.rows);\n            section.rows.forEach((card, index) => {\n              if (card.pinned) {\n                rows.splice(index, 0, card);\n              }\n            });\n            return Object.assign({}, section, initialized, Object.assign({}, action.data, {rows}));\n          }\n\n          return Object.assign({}, section, initialized, action.data);\n        }\n        return section;\n      });\n\n      if (!action.data.dedupeConfigurations) {\n        return newState;\n      }\n\n      action.data.dedupeConfigurations.forEach(dedupeConf => {\n        newState = newState.map(section => {\n          if (section.id === dedupeConf.id) {\n            const dedupedRows = dedupeConf.dedupeFrom.reduce((rows, dedupeSectionId) => {\n              const dedupeSection = newState.find(s => s.id === dedupeSectionId);\n              const [, newRows] = dedupe.group(dedupeSection.rows, rows);\n              return newRows;\n            }, section.rows);\n\n            return Object.assign({}, section, {rows: dedupedRows});\n          }\n\n          return section;\n        });\n      });\n\n      return newState;\n    case at.SECTION_UPDATE_CARD:\n      return prevState.map(section => {\n        if (section && section.id === action.data.id && section.rows) {\n          const newRows = section.rows.map(card => {\n            if (card.url === action.data.url) {\n              return Object.assign({}, card, action.data.options);\n            }\n            return card;\n          });\n          return Object.assign({}, section, {rows: newRows});\n        }\n        return section;\n      });\n    case at.PLACES_BOOKMARK_ADDED:\n      if (!action.data) {\n        return prevState;\n      }\n      return prevState.map(section => Object.assign({}, section, {\n        rows: section.rows.map(item => {\n          // find the item within the rows that is attempted to be bookmarked\n          if (item.url === action.data.url) {\n            const {bookmarkGuid, bookmarkTitle, dateAdded} = action.data;\n            return Object.assign({}, item, {\n              bookmarkGuid,\n              bookmarkTitle,\n              bookmarkDateCreated: dateAdded,\n              type: \"bookmark\"\n            });\n          }\n          return item;\n        })\n      }));\n    case at.PLACES_SAVED_TO_POCKET:\n      if (!action.data) {\n        return prevState;\n      }\n      return prevState.map(section => Object.assign({}, section, {\n        rows: section.rows.map(item => {\n          if (item.url === action.data.url) {\n            return Object.assign({}, item, {\n              open_url: action.data.open_url,\n              pocket_id: action.data.pocket_id,\n              title: action.data.title,\n              type: \"pocket\"\n            });\n          }\n          return item;\n        })\n      }));\n    case at.PLACES_BOOKMARK_REMOVED:\n      if (!action.data) {\n        return prevState;\n      }\n      return prevState.map(section => Object.assign({}, section, {\n        rows: section.rows.map(item => {\n          // find the bookmark within the rows that is attempted to be removed\n          if (item.url === action.data.url) {\n            const newSite = Object.assign({}, item);\n            delete newSite.bookmarkGuid;\n            delete newSite.bookmarkTitle;\n            delete newSite.bookmarkDateCreated;\n            if (!newSite.type || newSite.type === \"bookmark\") {\n              newSite.type = \"history\";\n            }\n            return newSite;\n          }\n          return item;\n        })\n      }));\n    case at.PLACES_LINK_DELETED:\n    case at.PLACES_LINK_BLOCKED:\n      if (!action.data) {\n        return prevState;\n      }\n      return prevState.map(section =>\n        Object.assign({}, section, {rows: section.rows.filter(site => site.url !== action.data.url)}));\n    case at.DELETE_FROM_POCKET:\n    case at.ARCHIVE_FROM_POCKET:\n      return prevState.map(section =>\n        Object.assign({}, section, {rows: section.rows.filter(site => site.pocket_id !== action.data.pocket_id)}));\n    default:\n      return prevState;\n  }\n}\n\nfunction Snippets(prevState = INITIAL_STATE.Snippets, action) {\n  switch (action.type) {\n    case at.SNIPPETS_DATA:\n      return Object.assign({}, prevState, {initialized: true}, action.data);\n    case at.SNIPPET_BLOCKED:\n      return Object.assign({}, prevState, {blockList: prevState.blockList.concat(action.data)});\n    case at.SNIPPETS_BLOCKLIST_CLEARED:\n      return Object.assign({}, prevState, {blockList: []});\n    case at.SNIPPETS_RESET:\n      return INITIAL_STATE.Snippets;\n    default:\n      return prevState;\n  }\n}\n\nfunction Theme(prevState = INITIAL_STATE.Theme, action) {\n  switch (action.type) {\n    case at.THEME_UPDATE:\n      return Object.assign({}, prevState, action.data);\n    default:\n      return prevState;\n  }\n}\n\nthis.INITIAL_STATE = INITIAL_STATE;\nthis.TOP_SITES_DEFAULT_ROWS = TOP_SITES_DEFAULT_ROWS;\nthis.TOP_SITES_MAX_SITES_PER_ROW = TOP_SITES_MAX_SITES_PER_ROW;\n\nthis.reducers = {TopSites, App, Snippets, Prefs, Dialog, Sections, Theme};\n\nconst EXPORTED_SYMBOLS = [\"reducers\", \"INITIAL_STATE\", \"insertPinned\", \"TOP_SITES_DEFAULT_ROWS\", \"TOP_SITES_MAX_SITES_PER_ROW\"];\n\n\n\n// WEBPACK FOOTER //\n// ./common/Reducers.jsm","import {actionCreators as ac, ASRouterActions as ra} from \"common/Actions.jsm\";\nimport {OUTGOING_MESSAGE_NAME as AS_GENERAL_OUTGOING_MESSAGE_NAME} from \"content-src/lib/init-store\";\nimport {ImpressionsWrapper} from \"./components/ImpressionsWrapper/ImpressionsWrapper\";\nimport {OnboardingMessage} from \"./templates/OnboardingMessage/OnboardingMessage\";\nimport React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport {SimpleSnippet} from \"./templates/SimpleSnippet/SimpleSnippet\";\n\nconst INCOMING_MESSAGE_NAME = \"ASRouter:parent-to-child\";\nconst OUTGOING_MESSAGE_NAME = \"ASRouter:child-to-parent\";\n\nexport const ASRouterUtils = {\n  addListener(listener) {\n    global.addMessageListener(INCOMING_MESSAGE_NAME, listener);\n  },\n  removeListener(listener) {\n    global.removeMessageListener(INCOMING_MESSAGE_NAME, listener);\n  },\n  sendMessage(action) {\n    global.sendAsyncMessage(OUTGOING_MESSAGE_NAME, action);\n  },\n  blockById(id) {\n    ASRouterUtils.sendMessage({type: \"BLOCK_MESSAGE_BY_ID\", data: {id}});\n  },\n  blockBundle(bundle) {\n    ASRouterUtils.sendMessage({type: \"BLOCK_BUNDLE\", data: {bundle}});\n  },\n  executeAction({button_action, button_action_params}) {\n    if (button_action in ra) {\n      ASRouterUtils.sendMessage({type: button_action, data: {button_action_params}});\n    }\n  },\n  unblockById(id) {\n    ASRouterUtils.sendMessage({type: \"UNBLOCK_MESSAGE_BY_ID\", data: {id}});\n  },\n  unblockBundle(bundle) {\n    ASRouterUtils.sendMessage({type: \"UNBLOCK_BUNDLE\", data: {bundle}});\n  },\n  getNextMessage() {\n    ASRouterUtils.sendMessage({type: \"GET_NEXT_MESSAGE\"});\n  },\n  overrideMessage(id) {\n    ASRouterUtils.sendMessage({type: \"OVERRIDE_MESSAGE\", data: {id}});\n  },\n  sendTelemetry(ping) {\n    const payload = ac.ASRouterUserEvent(ping);\n    global.sendAsyncMessage(AS_GENERAL_OUTGOING_MESSAGE_NAME, payload);\n  }\n};\n\n// Note: nextProps/prevProps refer to props passed to <ImpressionsWrapper />, not <ASRouterUISurface />\nfunction shouldSendImpressionOnUpdate(nextProps, prevProps) {\n  return (nextProps.message.id && (!prevProps.message || prevProps.message.id !== nextProps.message.id));\n}\n\nexport class ASRouterUISurface extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onMessageFromParent = this.onMessageFromParent.bind(this);\n    this.sendImpression = this.sendImpression.bind(this);\n    this.sendUserActionTelemetry = this.sendUserActionTelemetry.bind(this);\n    this.state = {message: {}, bundle: {}};\n  }\n\n  sendUserActionTelemetry(extraProps = {}) {\n    const {message, bundle} = this.state;\n    if (!message && !extraProps.message_id) {\n      throw new Error(`You must provide a message_id for bundled messages`);\n    }\n    const eventType = `${message.provider || bundle.provider}_user_event`;\n    ASRouterUtils.sendTelemetry({\n      message_id: message.id || extraProps.message_id,\n      source: extraProps.id,\n      action: eventType,\n      ...extraProps\n    });\n  }\n\n  sendImpression(extraProps) {\n    this.sendUserActionTelemetry({event: \"IMPRESSION\", ...extraProps});\n  }\n\n  onBlockById(id) {\n    return () => ASRouterUtils.blockById(id);\n  }\n\n  clearBundle(bundle) {\n    return () => ASRouterUtils.blockBundle(bundle);\n  }\n\n  onMessageFromParent({data: action}) {\n    switch (action.type) {\n      case \"SET_MESSAGE\":\n        this.setState({message: action.data});\n        break;\n      case \"SET_BUNDLED_MESSAGES\":\n        this.setState({bundle: action.data});\n        break;\n      case \"CLEAR_MESSAGE\":\n        if (action.data.id === this.state.message.id) {\n          this.setState({message: {}});\n        }\n        break;\n      case \"CLEAR_BUNDLE\":\n        if (this.state.bundle.bundle) {\n          this.setState({bundle: {}});\n        }\n        break;\n      case \"CLEAR_ALL\":\n        this.setState({message: {}, bundle: {}});\n    }\n  }\n\n  componentWillMount() {\n    ASRouterUtils.addListener(this.onMessageFromParent);\n    ASRouterUtils.sendMessage({type: \"CONNECT_UI_REQUEST\"});\n  }\n\n  componentWillUnmount() {\n    ASRouterUtils.removeListener(this.onMessageFromParent);\n  }\n\n  renderSnippets() {\n    return (\n      <ImpressionsWrapper\n        id=\"NEWTAB_FOOTER_BAR\"\n        message={this.state.message}\n        sendImpression={this.sendImpression}\n        shouldSendImpressionOnUpdate={shouldSendImpressionOnUpdate}\n        // This helps with testing\n        document={this.props.document}>\n          <SimpleSnippet\n            {...this.state.message}\n            UISurface=\"NEWTAB_FOOTER_BAR\"\n            getNextMessage={ASRouterUtils.getNextMessage}\n            onBlock={this.onBlockById(this.state.message.id)}\n            sendUserActionTelemetry={this.sendUserActionTelemetry} />\n      </ImpressionsWrapper>);\n  }\n\n  renderOnboarding() {\n    return (\n      <OnboardingMessage\n        {...this.state.bundle}\n        UISurface=\"NEWTAB_OVERLAY\"\n        onAction={ASRouterUtils.executeAction}\n        onDoneButton={this.clearBundle(this.state.bundle.bundle)}\n        getNextMessage={ASRouterUtils.getNextMessage}\n        sendUserActionTelemetry={this.sendUserActionTelemetry} />);\n  }\n\n  render() {\n    const {message, bundle} = this.state;\n    if (!message.id && !bundle.template) { return null; }\n    if (bundle.template === \"onboarding\") { return this.renderOnboarding(); }\n    return this.renderSnippets();\n  }\n}\n\nASRouterUISurface.defaultProps = {document: global.document};\n\nexport class ASRouterContent {\n  constructor() {\n    this.initialized = false;\n    this.containerElement = null;\n  }\n\n  _mount() {\n    this.containerElement = global.document.getElementById(\"snippets-container\");\n    ReactDOM.render(<ASRouterUISurface />, this.containerElement);\n  }\n\n  _unmount() {\n    ReactDOM.unmountComponentAtNode(this.containerElement);\n  }\n\n  init() {\n    this._mount();\n    this.initialized = true;\n  }\n\n  uninit() {\n    if (this.initialized) {\n      this._unmount();\n      this.initialized = false;\n    }\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/asrouter/asrouter-content.jsx","/* eslint-env mozilla/frame-script */\n\nimport {actionCreators as ac, actionTypes as at, actionUtils as au} from \"common/Actions.jsm\";\nimport {applyMiddleware, combineReducers, createStore} from \"redux\";\n\nexport const MERGE_STORE_ACTION = \"NEW_TAB_INITIAL_STATE\";\nexport const OUTGOING_MESSAGE_NAME = \"ActivityStream:ContentToMain\";\nexport const INCOMING_MESSAGE_NAME = \"ActivityStream:MainToContent\";\nexport const EARLY_QUEUED_ACTIONS = [at.SAVE_SESSION_PERF_DATA, at.PAGE_PRERENDERED];\n\n/**\n * A higher-order function which returns a reducer that, on MERGE_STORE action,\n * will return the action.data object merged into the previous state.\n *\n * For all other actions, it merely calls mainReducer.\n *\n * Because we want this to merge the entire state object, it's written as a\n * higher order function which takes the main reducer (itself often a call to\n * combineReducers) as a parameter.\n *\n * @param  {function} mainReducer reducer to call if action != MERGE_STORE_ACTION\n * @return {function}             a reducer that, on MERGE_STORE_ACTION action,\n *                                will return the action.data object merged\n *                                into the previous state, and the result\n *                                of calling mainReducer otherwise.\n */\nfunction mergeStateReducer(mainReducer) {\n  return (prevState, action) => {\n    if (action.type === MERGE_STORE_ACTION) {\n      return {...prevState, ...action.data};\n    }\n\n    return mainReducer(prevState, action);\n  };\n}\n\n/**\n * messageMiddleware - Middleware that looks for SentToMain type actions, and sends them if necessary\n */\nconst messageMiddleware = store => next => action => {\n  const skipLocal = action.meta && action.meta.skipLocal;\n  if (au.isSendToMain(action)) {\n    sendAsyncMessage(OUTGOING_MESSAGE_NAME, action);\n  }\n  if (!skipLocal) {\n    next(action);\n  }\n};\n\nexport const rehydrationMiddleware = store => next => action => {\n  if (store._didRehydrate) {\n    return next(action);\n  }\n\n  const isMergeStoreAction = action.type === MERGE_STORE_ACTION;\n  const isRehydrationRequest = action.type === at.NEW_TAB_STATE_REQUEST;\n\n  if (isRehydrationRequest) {\n    store._didRequestInitialState = true;\n    return next(action);\n  }\n\n  if (isMergeStoreAction) {\n    store._didRehydrate = true;\n    return next(action);\n  }\n\n  // If init happened after our request was made, we need to re-request\n  if (store._didRequestInitialState && action.type === at.INIT) {\n    return next(ac.AlsoToMain({type: at.NEW_TAB_STATE_REQUEST}));\n  }\n\n  if (au.isBroadcastToContent(action) || au.isSendToOneContent(action) || au.isSendToPreloaded(action)) {\n    // Note that actions received before didRehydrate will not be dispatched\n    // because this could negatively affect preloading and the the state\n    // will be replaced by rehydration anyway.\n    return null;\n  }\n\n  return next(action);\n};\n\n/**\n * This middleware queues up all the EARLY_QUEUED_ACTIONS until it receives\n * the first action from main. This is useful for those actions for main which\n * require higher reliability, i.e. the action will not be lost in the case\n * that it gets sent before the main is ready to receive it. Conversely, any\n * actions allowed early are accepted to be ignorable or re-sendable.\n */\nexport const queueEarlyMessageMiddleware = store => next => action => {\n  if (store._receivedFromMain) {\n    next(action);\n  } else if (au.isFromMain(action)) {\n    next(action);\n    store._receivedFromMain = true;\n    // Sending out all the early actions as main is ready now\n    if (store._earlyActionQueue) {\n      store._earlyActionQueue.forEach(next);\n      store._earlyActionQueue = [];\n    }\n  } else if (EARLY_QUEUED_ACTIONS.includes(action.type)) {\n    store._earlyActionQueue = store._earlyActionQueue || [];\n    store._earlyActionQueue.push(action);\n  } else {\n    // Let any other type of action go through\n    next(action);\n  }\n};\n\n/**\n * initStore - Create a store and listen for incoming actions\n *\n * @param  {object} reducers An object containing Redux reducers\n * @param  {object} intialState (optional) The initial state of the store, if desired\n * @return {object}          A redux store\n */\nexport function initStore(reducers, initialState) {\n  const store = createStore(\n    mergeStateReducer(combineReducers(reducers)),\n    initialState,\n    global.addMessageListener && applyMiddleware(rehydrationMiddleware, queueEarlyMessageMiddleware, messageMiddleware)\n  );\n\n  store._didRehydrate = false;\n  store._didRequestInitialState = false;\n\n  if (global.addMessageListener) {\n    global.addMessageListener(INCOMING_MESSAGE_NAME, msg => {\n      try {\n        store.dispatch(msg.data);\n      } catch (ex) {\n        console.error(\"Content msg:\", msg, \"Dispatch error: \", ex); // eslint-disable-line no-console\n        dump(`Content msg: ${JSON.stringify(msg)}\\nDispatch error: ${ex}\\n${ex.stack}`);\n      }\n    });\n  }\n\n  return store;\n}\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/lib/init-store.js","module.exports = ReactDOM;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"ReactDOM\"\n// module id = 9\n// module chunks = 0","import {FormattedMessage} from \"react-intl\";\nimport React from \"react\";\n\nexport class ErrorBoundaryFallback extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.windowObj = this.props.windowObj || window;\n    this.onClick = this.onClick.bind(this);\n  }\n\n  /**\n   * Since we only get here if part of the page has crashed, do a\n   * forced reload to give us the best chance at recovering.\n   */\n  onClick() {\n    this.windowObj.location.reload(true);\n  }\n\n  render() {\n    const defaultClass = \"as-error-fallback\";\n    let className;\n    if (\"className\" in this.props) {\n      className = `${this.props.className} ${defaultClass}`;\n    } else {\n      className = defaultClass;\n    }\n\n    // href=\"#\" to force normal link styling stuff (eg cursor on hover)\n    return (\n      <div className={className}>\n        <div>\n          <FormattedMessage\n            defaultMessage=\"Oops, something went wrong loading this content.\"\n            id=\"error_fallback_default_info\" />\n        </div>\n        <span>\n          <a href=\"#\" className=\"reload-button\" onClick={this.onClick}>\n            <FormattedMessage\n              defaultMessage=\"Refresh page to try again.\"\n              id=\"error_fallback_default_refresh_suggestion\" />\n          </a>\n        </span>\n      </div>\n    );\n  }\n}\nErrorBoundaryFallback.defaultProps = {className: \"as-error-fallback\"};\n\nexport class ErrorBoundary extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.state = {hasError: false};\n  }\n\n  componentDidCatch(error, info) {\n    this.setState({hasError: true});\n  }\n\n  render() {\n    if (!this.state.hasError) {\n      return (this.props.children);\n    }\n\n    return <this.props.FallbackComponent className={this.props.className} />;\n  }\n}\n\nErrorBoundary.defaultProps = {FallbackComponent: ErrorBoundaryFallback};\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/ErrorBoundary/ErrorBoundary.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\n\nconst _OpenInPrivateWindow = site => ({\n  id: \"menu_action_open_private_window\",\n  icon: \"new-window-private\",\n  action: ac.OnlyToMain({\n    type: at.OPEN_PRIVATE_WINDOW,\n    data: {url: site.url, referrer: site.referrer}\n  }),\n  userEvent: \"OPEN_PRIVATE_WINDOW\"\n});\n\nexport const GetPlatformString = platform => {\n  switch (platform) {\n    case \"win\":\n      return \"menu_action_show_file_windows\";\n    case \"macosx\":\n      return \"menu_action_show_file_mac_os\";\n    case \"linux\":\n      return \"menu_action_show_file_linux\";\n    default:\n      return \"menu_action_show_file_default\";\n  }\n};\n\n/**\n * List of functions that return items that can be included as menu options in a\n * LinkMenu. All functions take the site as the first parameter, and optionally\n * the index of the site.\n */\nexport const LinkMenuOptions = {\n  Separator: () => ({type: \"separator\"}),\n  EmptyItem: () => ({type: \"empty\"}),\n  RemoveBookmark: site => ({\n    id: \"menu_action_remove_bookmark\",\n    icon: \"bookmark-added\",\n    action: ac.AlsoToMain({\n      type: at.DELETE_BOOKMARK_BY_ID,\n      data: site.bookmarkGuid\n    }),\n    userEvent: \"BOOKMARK_DELETE\"\n  }),\n  AddBookmark: site => ({\n    id: \"menu_action_bookmark\",\n    icon: \"bookmark-hollow\",\n    action: ac.AlsoToMain({\n      type: at.BOOKMARK_URL,\n      data: {url: site.url, title: site.title, type: site.type}\n    }),\n    userEvent: \"BOOKMARK_ADD\"\n  }),\n  OpenInNewWindow: site => ({\n    id: \"menu_action_open_new_window\",\n    icon: \"new-window\",\n    action: ac.AlsoToMain({\n      type: at.OPEN_NEW_WINDOW,\n      data: {\n        referrer: site.referrer,\n        typedBonus: site.typedBonus,\n        url: site.url\n      }\n    }),\n    userEvent: \"OPEN_NEW_WINDOW\"\n  }),\n  BlockUrl: (site, index, eventSource) => ({\n    id: \"menu_action_dismiss\",\n    icon: \"dismiss\",\n    action: ac.AlsoToMain({\n      type: at.BLOCK_URL,\n      data: {url: site.url, pocket_id: site.pocket_id}\n    }),\n    impression: ac.ImpressionStats({\n      source: eventSource,\n      block: 0,\n      tiles: [{id: site.guid, pos: index}]\n    }),\n    userEvent: \"BLOCK\"\n  }),\n\n  // This is an option for web extentions which will result in remove items from\n  // memory and notify the web extenion, rather than using the built-in block list.\n  WebExtDismiss: (site, index, eventSource) => ({\n    id: \"menu_action_webext_dismiss\",\n    string_id: \"menu_action_dismiss\",\n    icon: \"dismiss\",\n    action: ac.WebExtEvent(at.WEBEXT_DISMISS, {\n      source: eventSource,\n      url: site.url,\n      action_position: index\n    })\n  }),\n  DeleteUrl: (site, index, eventSource, isEnabled, siteInfo) => ({\n    id: \"menu_action_delete\",\n    icon: \"delete\",\n    action: {\n      type: at.DIALOG_OPEN,\n      data: {\n        onConfirm: [\n          ac.AlsoToMain({type: at.DELETE_HISTORY_URL, data: {url: site.url, pocket_id: site.pocket_id, forceBlock: site.bookmarkGuid}}),\n          ac.UserEvent(Object.assign({event: \"DELETE\", source: eventSource, action_position: index}, siteInfo))\n        ],\n        eventSource,\n        body_string_id: [\"confirm_history_delete_p1\", \"confirm_history_delete_notice_p2\"],\n        confirm_button_string_id: \"menu_action_delete\",\n        cancel_button_string_id: \"topsites_form_cancel_button\",\n        icon: \"modal-delete\"\n      }\n    },\n    userEvent: \"DIALOG_OPEN\"\n  }),\n  ShowFile: (site, index, eventSource, isEnabled, siteInfo, platform) => ({\n    id: GetPlatformString(platform),\n    icon: \"search\",\n    action: ac.OnlyToMain({\n      type: at.SHOW_DOWNLOAD_FILE,\n      data: {url: site.url}\n    })\n  }),\n  OpenFile: site => ({\n    id: \"menu_action_open_file\",\n    icon: \"open-file\",\n    action: ac.OnlyToMain({\n      type: at.OPEN_DOWNLOAD_FILE,\n      data: {url: site.url}\n    })\n  }),\n  CopyDownloadLink: site => ({\n    id: \"menu_action_copy_download_link\",\n    icon: \"copy\",\n    action: ac.OnlyToMain({\n      type: at.COPY_DOWNLOAD_LINK,\n      data: {url: site.url}\n    })\n  }),\n  GoToDownloadPage: site => ({\n    id: \"menu_action_go_to_download_page\",\n    icon: \"download\",\n    action: ac.OnlyToMain({\n      type: at.OPEN_LINK,\n      data: {url: site.referrer}\n    }),\n    disabled: !site.referrer\n  }),\n  RemoveDownload: site => ({\n    id: \"menu_action_remove_download\",\n    icon: \"delete\",\n    action: ac.OnlyToMain({\n      type: at.REMOVE_DOWNLOAD_FILE,\n      data: {url: site.url}\n    })\n  }),\n  PinTopSite: (site, index) => ({\n    id: \"menu_action_pin\",\n    icon: \"pin\",\n    action: ac.AlsoToMain({\n      type: at.TOP_SITES_PIN,\n      data: {site: {url: site.url}, index}\n    }),\n    userEvent: \"PIN\"\n  }),\n  UnpinTopSite: site => ({\n    id: \"menu_action_unpin\",\n    icon: \"unpin\",\n    action: ac.AlsoToMain({\n      type: at.TOP_SITES_UNPIN,\n      data: {site: {url: site.url}}\n    }),\n    userEvent: \"UNPIN\"\n  }),\n  SaveToPocket: (site, index, eventSource) => ({\n    id: \"menu_action_save_to_pocket\",\n    icon: \"pocket\",\n    action: ac.AlsoToMain({\n      type: at.SAVE_TO_POCKET,\n      data: {site: {url: site.url, title: site.title}}\n    }),\n    impression: ac.ImpressionStats({\n      source: eventSource,\n      pocket: 0,\n      tiles: [{id: site.guid, pos: index}]\n    }),\n    userEvent: \"SAVE_TO_POCKET\"\n  }),\n  DeleteFromPocket: site => ({\n    id: \"menu_action_delete_pocket\",\n    icon: \"delete\",\n    action: ac.AlsoToMain({\n      type: at.DELETE_FROM_POCKET,\n      data: {pocket_id: site.pocket_id}\n    }),\n    userEvent: \"DELETE_FROM_POCKET\"\n  }),\n  ArchiveFromPocket: site => ({\n    id: \"menu_action_archive_pocket\",\n    icon: \"check\",\n    action: ac.AlsoToMain({\n      type: at.ARCHIVE_FROM_POCKET,\n      data: {pocket_id: site.pocket_id}\n    }),\n    userEvent: \"ARCHIVE_FROM_POCKET\"\n  }),\n  EditTopSite: (site, index) => ({\n    id: \"edit_topsites_button_text\",\n    icon: \"edit\",\n    action: {\n      type: at.TOP_SITES_EDIT,\n      data: {index}\n    }\n  }),\n  CheckBookmark: site => (site.bookmarkGuid ? LinkMenuOptions.RemoveBookmark(site) : LinkMenuOptions.AddBookmark(site)),\n  CheckPinTopSite: (site, index) => (site.isPinned ? LinkMenuOptions.UnpinTopSite(site) : LinkMenuOptions.PinTopSite(site, index)),\n  CheckSavedToPocket: (site, index) => (site.pocket_id ? LinkMenuOptions.DeleteFromPocket(site) : LinkMenuOptions.SaveToPocket(site, index)),\n  CheckBookmarkOrArchive: site => (site.pocket_id ? LinkMenuOptions.ArchiveFromPocket(site) : LinkMenuOptions.CheckBookmark(site)),\n  OpenInPrivateWindow: (site, index, eventSource, isEnabled) => (isEnabled ? _OpenInPrivateWindow(site) : LinkMenuOptions.EmptyItem())\n};\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/lib/link-menu-options.js","import {actionCreators as ac} from \"common/Actions.jsm\";\nimport {connect} from \"react-redux\";\nimport {ContextMenu} from \"content-src/components/ContextMenu/ContextMenu\";\nimport {injectIntl} from \"react-intl\";\nimport {LinkMenuOptions} from \"content-src/lib/link-menu-options\";\nimport React from \"react\";\n\nconst DEFAULT_SITE_MENU_OPTIONS = [\"CheckPinTopSite\", \"EditTopSite\", \"Separator\", \"OpenInNewWindow\", \"OpenInPrivateWindow\", \"Separator\", \"BlockUrl\"];\n\nexport class _LinkMenu extends React.PureComponent {\n  getOptions() {\n    const {props} = this;\n    const {site, index, source, isPrivateBrowsingEnabled, siteInfo, platform} = props;\n\n    // Handle special case of default site\n    const propOptions = !site.isDefault ? props.options : DEFAULT_SITE_MENU_OPTIONS;\n\n    const options = propOptions.map(o => LinkMenuOptions[o](site, index, source, isPrivateBrowsingEnabled, siteInfo, platform)).map(option => {\n      const {action, impression, id, string_id, type, userEvent} = option;\n      if (!type && id) {\n        option.label = props.intl.formatMessage({id: string_id || id});\n        option.onClick = () => {\n          props.dispatch(action);\n          if (userEvent) {\n            const userEventData = Object.assign({\n              event: userEvent,\n              source,\n              action_position: index\n            }, siteInfo);\n            props.dispatch(ac.UserEvent(userEventData));\n          }\n          if (impression && props.shouldSendImpressionStats) {\n            props.dispatch(impression);\n          }\n        };\n      }\n      return option;\n    });\n\n    // This is for accessibility to support making each item tabbable.\n    // We want to know which item is the first and which item\n    // is the last, so we can close the context menu accordingly.\n    options[0].first = true;\n    options[options.length - 1].last = true;\n    return options;\n  }\n\n  render() {\n    return (<ContextMenu\n      onUpdate={this.props.onUpdate}\n      options={this.getOptions()} />);\n  }\n}\n\nconst getState = state => ({isPrivateBrowsingEnabled: state.Prefs.values.isPrivateBrowsingEnabled, platform: state.Prefs.values.platform});\nexport const LinkMenu = connect(getState)(injectIntl(_LinkMenu));\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/LinkMenu/LinkMenu.jsx","import React from \"react\";\n\nexport class ContextMenu extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.hideContext = this.hideContext.bind(this);\n    this.onClick = this.onClick.bind(this);\n  }\n\n  hideContext() {\n    this.props.onUpdate(false);\n  }\n\n  componentDidMount() {\n    setTimeout(() => {\n      global.addEventListener(\"click\", this.hideContext);\n    }, 0);\n  }\n\n  componentWillUnmount() {\n    global.removeEventListener(\"click\", this.hideContext);\n  }\n\n  onClick(event) {\n    // Eat all clicks on the context menu so they don't bubble up to window.\n    // This prevents the context menu from closing when clicking disabled items\n    // or the separators.\n    event.stopPropagation();\n  }\n\n  render() {\n    return (<span className=\"context-menu\" onClick={this.onClick}>\n      <ul role=\"menu\" className=\"context-menu-list\">\n        {this.props.options.map((option, i) => (option.type === \"separator\" ?\n          (<li key={i} className=\"separator\" />) :\n          (option.type !== \"empty\" && <ContextMenuItem key={i} option={option} hideContext={this.hideContext} />)\n        ))}\n      </ul>\n    </span>);\n  }\n}\n\nexport class ContextMenuItem extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onClick = this.onClick.bind(this);\n    this.onKeyDown = this.onKeyDown.bind(this);\n  }\n\n  onClick() {\n    this.props.hideContext();\n    this.props.option.onClick();\n  }\n\n  onKeyDown(event) {\n    const {option} = this.props;\n    switch (event.key) {\n      case \"Tab\":\n        // tab goes down in context menu, shift + tab goes up in context menu\n        // if we're on the last item, one more tab will close the context menu\n        // similarly, if we're on the first item, one more shift + tab will close it\n        if ((event.shiftKey && option.first) || (!event.shiftKey && option.last)) {\n          this.props.hideContext();\n        }\n        break;\n      case \"Enter\":\n        this.props.hideContext();\n        option.onClick();\n        break;\n    }\n  }\n\n  render() {\n    const {option} = this.props;\n    return (\n      <li role=\"menuitem\" className=\"context-menu-item\">\n        <a onClick={this.onClick} onKeyDown={this.onKeyDown} tabIndex=\"0\" className={option.disabled ? \"disabled\" : \"\"}>\n          {option.icon && <span className={`icon icon-spacer icon-${option.icon}`} />}\n          {option.label}\n        </a>\n      </li>);\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/ContextMenu/ContextMenu.jsx","import {FormattedMessage, injectIntl} from \"react-intl\";\nimport {actionCreators as ac} from \"common/Actions.jsm\";\nimport {ErrorBoundary} from \"content-src/components/ErrorBoundary/ErrorBoundary\";\nimport React from \"react\";\nimport {SectionMenu} from \"content-src/components/SectionMenu/SectionMenu\";\nimport {SectionMenuOptions} from \"content-src/lib/section-menu-options\";\n\nconst VISIBLE = \"visible\";\nconst VISIBILITY_CHANGE_EVENT = \"visibilitychange\";\n\nfunction getFormattedMessage(message) {\n  return typeof message === \"string\" ? <span>{message}</span> : <FormattedMessage {...message} />;\n}\n\nexport class Disclaimer extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onAcknowledge = this.onAcknowledge.bind(this);\n  }\n\n  onAcknowledge() {\n    this.props.dispatch(ac.SetPref(this.props.disclaimerPref, false));\n    this.props.dispatch(ac.UserEvent({event: \"DISCLAIMER_ACKED\", source: this.props.eventSource}));\n  }\n\n  render() {\n    const {disclaimer} = this.props;\n    return (\n      <div className=\"section-disclaimer\">\n          <div className=\"section-disclaimer-text\">\n            {getFormattedMessage(disclaimer.text)}\n            {disclaimer.link &&\n              <a href={disclaimer.link.href} target=\"_blank\" rel=\"noopener noreferrer\">\n                {getFormattedMessage(disclaimer.link.title || disclaimer.link)}\n              </a>\n            }\n          </div>\n\n          <button onClick={this.onAcknowledge}>\n            {getFormattedMessage(disclaimer.button)}\n          </button>\n      </div>\n    );\n  }\n}\n\nexport const DisclaimerIntl = injectIntl(Disclaimer);\n\nexport class _CollapsibleSection extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onBodyMount = this.onBodyMount.bind(this);\n    this.onHeaderClick = this.onHeaderClick.bind(this);\n    this.onTransitionEnd = this.onTransitionEnd.bind(this);\n    this.enableOrDisableAnimation = this.enableOrDisableAnimation.bind(this);\n    this.onMenuButtonClick = this.onMenuButtonClick.bind(this);\n    this.onMenuButtonMouseEnter = this.onMenuButtonMouseEnter.bind(this);\n    this.onMenuButtonMouseLeave = this.onMenuButtonMouseLeave.bind(this);\n    this.onMenuUpdate = this.onMenuUpdate.bind(this);\n    this.state = {enableAnimation: true, isAnimating: false, menuButtonHover: false, showContextMenu: false};\n  }\n\n  componentWillMount() {\n    this.props.document.addEventListener(VISIBILITY_CHANGE_EVENT, this.enableOrDisableAnimation);\n  }\n\n  componentWillUpdate(nextProps) {\n    // Check if we're about to go from expanded to collapsed\n    if (!this.props.collapsed && nextProps.collapsed) {\n      // This next line forces a layout flush of the section body, which has a\n      // max-height style set, so that the upcoming collapse animation can\n      // animate from that height to the collapsed height. Without this, the\n      // update is coalesced and there's no animation from no-max-height to 0.\n      this.sectionBody.scrollHeight; // eslint-disable-line no-unused-expressions\n    }\n  }\n\n  componentWillUnmount() {\n    this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this.enableOrDisableAnimation);\n  }\n\n  enableOrDisableAnimation() {\n    // Only animate the collapse/expand for visible tabs.\n    const visible = this.props.document.visibilityState === VISIBLE;\n    if (this.state.enableAnimation !== visible) {\n      this.setState({enableAnimation: visible});\n    }\n  }\n\n  onBodyMount(node) {\n    this.sectionBody = node;\n  }\n\n  onHeaderClick() {\n    // If this.sectionBody is unset, it means that we're in some sort of error\n    // state, probably displaying the error fallback, so we won't be able to\n    // compute the height, and we don't want to persist the preference.\n    // If props.collapsed is undefined handler shouldn't do anything.\n    if (!this.sectionBody || this.props.collapsed === undefined) {\n      return;\n    }\n\n    // Get the current height of the body so max-height transitions can work\n    this.setState({\n      isAnimating: true,\n      maxHeight: `${this.sectionBody.scrollHeight}px`\n    });\n    const {action, userEvent} = SectionMenuOptions.CheckCollapsed(this.props);\n    this.props.dispatch(action);\n    this.props.dispatch(ac.UserEvent({\n      event: userEvent,\n      source: this.props.source\n    }));\n  }\n\n  onTransitionEnd(event) {\n    // Only update the animating state for our own transition (not a child's)\n    if (event.target === event.currentTarget) {\n      this.setState({isAnimating: false});\n    }\n  }\n\n  renderIcon() {\n    const {icon} = this.props;\n    if (icon && icon.startsWith(\"moz-extension://\")) {\n      return <span className=\"icon icon-small-spacer\" style={{backgroundImage: `url('${icon}')`}} />;\n    }\n    return <span className={`icon icon-small-spacer icon-${icon || \"webextension\"}`} />;\n  }\n\n  onMenuButtonClick(event) {\n    event.preventDefault();\n    this.setState({showContextMenu: true});\n  }\n\n  onMenuButtonMouseEnter() {\n    this.setState({menuButtonHover: true});\n  }\n\n  onMenuButtonMouseLeave() {\n    this.setState({menuButtonHover: false});\n  }\n\n  onMenuUpdate(showContextMenu) {\n    this.setState({showContextMenu});\n  }\n\n  render() {\n    const isCollapsible = this.props.collapsed !== undefined;\n    const {enableAnimation, isAnimating, maxHeight, menuButtonHover, showContextMenu} = this.state;\n    const {id, eventSource, collapsed, disclaimer, title, extraMenuOptions, showPrefName, privacyNoticeURL, dispatch, isFirst, isLast, isWebExtension} = this.props;\n    const disclaimerPref = `section.${id}.showDisclaimer`;\n    const needsDisclaimer = disclaimer && this.props.Prefs.values[disclaimerPref];\n    const active = menuButtonHover || showContextMenu;\n    return (\n      <section\n        className={`collapsible-section ${this.props.className}${enableAnimation ? \" animation-enabled\" : \"\"}${collapsed ? \" collapsed\" : \"\"}${active ? \" active\" : \"\"}`}\n        // Note: data-section-id is used for web extension api tests in mozilla central\n        data-section-id={id}>\n        <div className=\"section-top-bar\">\n          <h3 className=\"section-title\">\n            <span className=\"click-target\" onClick={this.onHeaderClick}>\n              {this.renderIcon()}\n              {getFormattedMessage(title)}\n              {isCollapsible && <span className={`collapsible-arrow icon ${collapsed ? \"icon-arrowhead-forward-small\" : \"icon-arrowhead-down-small\"}`} />}\n            </span>\n          </h3>\n          <div>\n            <button\n              className=\"context-menu-button icon\"\n              onClick={this.onMenuButtonClick}\n              onMouseEnter={this.onMenuButtonMouseEnter}\n              onMouseLeave={this.onMenuButtonMouseLeave}>\n              <span className=\"sr-only\">\n                <FormattedMessage id=\"section_context_menu_button_sr\" />\n              </span>\n            </button>\n            {showContextMenu &&\n              <SectionMenu\n                id={id}\n                extraOptions={extraMenuOptions}\n                eventSource={eventSource}\n                showPrefName={showPrefName}\n                privacyNoticeURL={privacyNoticeURL}\n                collapsed={collapsed}\n                onUpdate={this.onMenuUpdate}\n                isFirst={isFirst}\n                isLast={isLast}\n                dispatch={dispatch}\n                isWebExtension={isWebExtension} />\n            }\n          </div>\n        </div>\n        <ErrorBoundary className=\"section-body-fallback\">\n          <div\n            className={`section-body${isAnimating ? \" animating\" : \"\"}`}\n            onTransitionEnd={this.onTransitionEnd}\n            ref={this.onBodyMount}\n            style={isAnimating && !collapsed ? {maxHeight} : null}>\n            {needsDisclaimer && <DisclaimerIntl disclaimerPref={disclaimerPref} disclaimer={disclaimer} eventSource={eventSource} dispatch={this.props.dispatch} />}\n            {this.props.children}\n          </div>\n        </ErrorBoundary>\n      </section>\n    );\n  }\n}\n\n_CollapsibleSection.defaultProps = {\n  document: global.document || {\n    addEventListener: () => {},\n    removeEventListener: () => {},\n    visibilityState: \"hidden\"\n  },\n  Prefs: {values: {}}\n};\n\nexport const CollapsibleSection = injectIntl(_CollapsibleSection);\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/CollapsibleSection/CollapsibleSection.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\n\n/**\n * List of functions that return items that can be included as menu options in a\n * SectionMenu. All functions take the section as the only parameter.\n */\nexport const SectionMenuOptions = {\n  Separator: () => ({type: \"separator\"}),\n  MoveUp: section => ({\n    id: \"section_menu_action_move_up\",\n    icon: \"arrowhead-up\",\n    action: ac.OnlyToMain({\n      type: at.SECTION_MOVE,\n      data: {id: section.id, direction: -1}\n    }),\n    userEvent: \"MENU_MOVE_UP\",\n    disabled: !!section.isFirst\n  }),\n  MoveDown: section => ({\n    id: \"section_menu_action_move_down\",\n    icon: \"arrowhead-down\",\n    action: ac.OnlyToMain({\n      type: at.SECTION_MOVE,\n      data: {id: section.id, direction: +1}\n    }),\n    userEvent: \"MENU_MOVE_DOWN\",\n    disabled: !!section.isLast\n  }),\n  RemoveSection: section => ({\n    id: \"section_menu_action_remove_section\",\n    icon: \"dismiss\",\n    action: ac.SetPref(section.showPrefName, false),\n    userEvent: \"MENU_REMOVE\"\n  }),\n  CollapseSection: section => ({\n    id: \"section_menu_action_collapse_section\",\n    icon: \"minimize\",\n    action: ac.OnlyToMain({type: at.UPDATE_SECTION_PREFS, data: {id: section.id, value: {collapsed: true}}}),\n    userEvent: \"MENU_COLLAPSE\"\n  }),\n  ExpandSection: section => ({\n    id: \"section_menu_action_expand_section\",\n    icon: \"maximize\",\n    action: ac.OnlyToMain({type: at.UPDATE_SECTION_PREFS, data: {id: section.id, value: {collapsed: false}}}),\n    userEvent: \"MENU_EXPAND\"\n  }),\n  ManageSection: section => ({\n    id: \"section_menu_action_manage_section\",\n    icon: \"settings\",\n    action: ac.OnlyToMain({type: at.SETTINGS_OPEN}),\n    userEvent: \"MENU_MANAGE\"\n  }),\n  ManageWebExtension: section => ({\n    id: \"section_menu_action_manage_webext\",\n    icon: \"settings\",\n    action: ac.OnlyToMain({type: at.OPEN_WEBEXT_SETTINGS, data: section.id})\n  }),\n  AddTopSite: section => ({\n    id: \"section_menu_action_add_topsite\",\n    icon: \"add\",\n    action: {type: at.TOP_SITES_EDIT, data: {index: -1}},\n    userEvent: \"MENU_ADD_TOPSITE\"\n  }),\n  PrivacyNotice: section => ({\n    id: \"section_menu_action_privacy_notice\",\n    icon: \"info\",\n    action: ac.OnlyToMain({\n      type: at.OPEN_LINK,\n      data: {url: section.privacyNoticeURL}\n    }),\n    userEvent: \"MENU_PRIVACY_NOTICE\"\n  }),\n  CheckCollapsed: section => (section.collapsed ? SectionMenuOptions.ExpandSection(section) : SectionMenuOptions.CollapseSection(section))\n};\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/lib/section-menu-options.js","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {perfService as perfSvc} from \"common/PerfService.jsm\";\nimport React from \"react\";\n\n// Currently record only a fixed set of sections. This will prevent data\n// from custom sections from showing up or from topstories.\nconst RECORDED_SECTIONS = [\"highlights\", \"topsites\"];\n\nexport class ComponentPerfTimer extends React.Component {\n  constructor(props) {\n    super(props);\n    // Just for test dependency injection:\n    this.perfSvc = this.props.perfSvc || perfSvc;\n\n    this._sendBadStateEvent = this._sendBadStateEvent.bind(this);\n    this._sendPaintedEvent = this._sendPaintedEvent.bind(this);\n    this._reportMissingData = false;\n    this._timestampHandled = false;\n    this._recordedFirstRender = false;\n  }\n\n  componentDidMount() {\n    if (!RECORDED_SECTIONS.includes(this.props.id)) {\n      return;\n    }\n\n    this._maybeSendPaintedEvent();\n  }\n\n  componentDidUpdate() {\n    if (!RECORDED_SECTIONS.includes(this.props.id)) {\n      return;\n    }\n\n    this._maybeSendPaintedEvent();\n  }\n\n  /**\n   * Call the given callback after the upcoming frame paints.\n   *\n   * @note Both setTimeout and requestAnimationFrame are throttled when the page\n   * is hidden, so this callback may get called up to a second or so after the\n   * requestAnimationFrame \"paint\" for hidden tabs.\n   *\n   * Newtabs hidden while loading will presumably be fairly rare (other than\n   * preloaded tabs, which we will be filtering out on the server side), so such\n   * cases should get lost in the noise.\n   *\n   * If we decide that it's important to find out when something that's hidden\n   * has \"painted\", however, another option is to post a message to this window.\n   * That should happen even faster than setTimeout, and, at least as of this\n   * writing, it's not throttled in hidden windows in Firefox.\n   *\n   * @param {Function} callback\n   *\n   * @returns void\n   */\n  _afterFramePaint(callback) {\n    requestAnimationFrame(() => setTimeout(callback, 0));\n  }\n\n  _maybeSendBadStateEvent() {\n    // Follow up bugs:\n    // https://github.com/mozilla/activity-stream/issues/3691\n    if (!this.props.initialized) {\n      // Remember to report back when data is available.\n      this._reportMissingData = true;\n    } else if (this._reportMissingData) {\n      this._reportMissingData = false;\n      // Report how long it took for component to become initialized.\n      this._sendBadStateEvent();\n    }\n  }\n\n  _maybeSendPaintedEvent() {\n    // If we've already handled a timestamp, don't do it again.\n    if (this._timestampHandled || !this.props.initialized) {\n      return;\n    }\n\n    // And if we haven't, we're doing so now, so remember that. Even if\n    // something goes wrong in the callback, we can't try again, as we'd be\n    // sending back the wrong data, and we have to do it here, so that other\n    // calls to this method while waiting for the next frame won't also try to\n    // handle it.\n    this._timestampHandled = true;\n    this._afterFramePaint(this._sendPaintedEvent);\n  }\n\n  /**\n   * Triggered by call to render. Only first call goes through due to\n   * `_recordedFirstRender`.\n   */\n  _ensureFirstRenderTsRecorded() {\n    // Used as t0 for recording how long component took to initialize.\n    if (!this._recordedFirstRender) {\n      this._recordedFirstRender = true;\n      // topsites_first_render_ts, highlights_first_render_ts.\n      const key = `${this.props.id}_first_render_ts`;\n      this.perfSvc.mark(key);\n    }\n  }\n\n  /**\n   * Creates `TELEMETRY_UNDESIRED_EVENT` with timestamp in ms\n   * of how much longer the data took to be ready for display than it would\n   * have been the ideal case.\n   * https://github.com/mozilla/ping-centre/issues/98\n   */\n  _sendBadStateEvent() {\n    // highlights_data_ready_ts, topsites_data_ready_ts.\n    const dataReadyKey = `${this.props.id}_data_ready_ts`;\n    this.perfSvc.mark(dataReadyKey);\n\n    try {\n      const firstRenderKey = `${this.props.id}_first_render_ts`;\n      // value has to be Int32.\n      const value = parseInt(this.perfSvc.getMostRecentAbsMarkStartByName(dataReadyKey) -\n                             this.perfSvc.getMostRecentAbsMarkStartByName(firstRenderKey), 10);\n      this.props.dispatch(ac.OnlyToMain({\n        type: at.SAVE_SESSION_PERF_DATA,\n        // highlights_data_late_by_ms, topsites_data_late_by_ms.\n        data: {[`${this.props.id}_data_late_by_ms`]: value}\n      }));\n    } catch (ex) {\n      // If this failed, it's likely because the `privacy.resistFingerprinting`\n      // pref is true.\n    }\n  }\n\n  _sendPaintedEvent() {\n    // Record first_painted event but only send if topsites.\n    if (this.props.id !== \"topsites\") {\n      return;\n    }\n\n    // topsites_first_painted_ts.\n    const key = `${this.props.id}_first_painted_ts`;\n    this.perfSvc.mark(key);\n\n    try {\n      const data = {};\n      data[key] = this.perfSvc.getMostRecentAbsMarkStartByName(key);\n\n      this.props.dispatch(ac.OnlyToMain({\n        type: at.SAVE_SESSION_PERF_DATA,\n        data\n      }));\n    } catch (ex) {\n      // If this failed, it's likely because the `privacy.resistFingerprinting`\n      // pref is true.  We should at least not blow up, and should continue\n      // to set this._timestampHandled to avoid going through this again.\n    }\n  }\n\n  render() {\n    if (RECORDED_SECTIONS.includes(this.props.id)) {\n      this._ensureFirstRenderTsRecorded();\n      this._maybeSendBadStateEvent();\n    }\n    return this.props.children;\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/ComponentPerfTimer/ComponentPerfTimer.jsx","/* globals Services */\n\"use strict\";\n\n/* istanbul ignore if */\nif (typeof ChromeUtils !== \"undefined\") {\n  ChromeUtils.import(\"resource://gre/modules/Services.jsm\");\n}\n\nlet usablePerfObj;\n\n/* istanbul ignore if */\n/* istanbul ignore else */\nif (typeof Services !== \"undefined\") {\n  // Borrow the high-resolution timer from the hidden window....\n  usablePerfObj = Services.appShell.hiddenDOMWindow.performance;\n} else if (typeof performance !== \"undefined\") {\n  // we must be running in content space\n  // eslint-disable-next-line no-undef\n  usablePerfObj = performance;\n} else {\n  // This is a dummy object so this file doesn't crash in the node prerendering\n  // task.\n  usablePerfObj = {\n    now() {},\n    mark() {}\n  };\n}\n\nfunction _PerfService(options) {\n  // For testing, so that we can use a fake Window.performance object with\n  // known state.\n  if (options && options.performanceObj) {\n    this._perf = options.performanceObj;\n  } else {\n    this._perf = usablePerfObj;\n  }\n}\n\n_PerfService.prototype = {\n  /**\n   * Calls the underlying mark() method on the appropriate Window.performance\n   * object to add a mark with the given name to the appropriate performance\n   * timeline.\n   *\n   * @param  {String} name  the name to give the current mark\n   * @return {void}\n   */\n  mark: function mark(str) {\n    this._perf.mark(str);\n  },\n\n  /**\n   * Calls the underlying getEntriesByName on the appropriate Window.performance\n   * object.\n   *\n   * @param  {String} name\n   * @param  {String} type eg \"mark\"\n   * @return {Array}       Performance* objects\n   */\n  getEntriesByName: function getEntriesByName(name, type) {\n    return this._perf.getEntriesByName(name, type);\n  },\n\n  /**\n   * The timeOrigin property from the appropriate performance object.\n   * Used to ensure that timestamps from the add-on code and the content code\n   * are comparable.\n   *\n   * @note If this is called from a context without a window\n   * (eg a JSM in chrome), it will return the timeOrigin of the XUL hidden\n   * window, which appears to be the first created window (and thus\n   * timeOrigin) in the browser.  Note also, however, there is also a private\n   * hidden window, presumably for private browsing, which appears to be\n   * created dynamically later.  Exactly how/when that shows up needs to be\n   * investigated.\n   *\n   * @return {Number} A double of milliseconds with a precision of 0.5us.\n   */\n  get timeOrigin() {\n    return this._perf.timeOrigin;\n  },\n\n  /**\n   * Returns the \"absolute\" version of performance.now(), i.e. one that\n   * should ([bug 1401406](https://bugzilla.mozilla.org/show_bug.cgi?id=1401406)\n   * be comparable across both chrome and content.\n   *\n   * @return {Number}\n   */\n  absNow: function absNow() {\n    return this.timeOrigin + this._perf.now();\n  },\n\n  /**\n   * This returns the absolute startTime from the most recent performance.mark()\n   * with the given name.\n   *\n   * @param  {String} name  the name to lookup the start time for\n   *\n   * @return {Number}       the returned start time, as a DOMHighResTimeStamp\n   *\n   * @throws {Error}        \"No Marks with the name ...\" if none are available\n   *\n   * @note Always surround calls to this by try/catch.  Otherwise your code\n   * may fail when the `privacy.resistFingerprinting` pref is true.  When\n   * this pref is set, all attempts to get marks will likely fail, which will\n   * cause this method to throw.\n   *\n   * See [bug 1369303](https://bugzilla.mozilla.org/show_bug.cgi?id=1369303)\n   * for more info.\n   */\n  getMostRecentAbsMarkStartByName(name) {\n    let entries = this.getEntriesByName(name, \"mark\");\n\n    if (!entries.length) {\n      throw new Error(`No marks with the name ${name}`);\n    }\n\n    let mostRecentEntry = entries[entries.length - 1];\n    return this._perf.timeOrigin + mostRecentEntry.startTime;\n  }\n};\n\nthis.perfService = new _PerfService();\nconst EXPORTED_SYMBOLS = [\"_PerfService\", \"perfService\"];\n\n\n\n// WEBPACK FOOTER //\n// ./common/PerfService.jsm","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {FormattedMessage, injectIntl} from \"react-intl\";\nimport {\n  MIN_CORNER_FAVICON_SIZE,\n  MIN_RICH_FAVICON_SIZE,\n  TOP_SITES_CONTEXT_MENU_OPTIONS,\n  TOP_SITES_SOURCE\n} from \"./TopSitesConstants\";\nimport {LinkMenu} from \"content-src/components/LinkMenu/LinkMenu\";\nimport React from \"react\";\nimport {TOP_SITES_MAX_SITES_PER_ROW} from \"common/Reducers.jsm\";\n\nexport class TopSiteLink extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onDragEvent = this.onDragEvent.bind(this);\n  }\n\n  /*\n   * Helper to determine whether the drop zone should allow a drop. We only allow\n   * dropping top sites for now.\n   */\n  _allowDrop(e) {\n    return e.dataTransfer.types.includes(\"text/topsite-index\");\n  }\n\n  onDragEvent(event) {\n    switch (event.type) {\n      case \"click\":\n        // Stop any link clicks if we started any dragging\n        if (this.dragged) {\n          event.preventDefault();\n        }\n        break;\n      case \"dragstart\":\n        this.dragged = true;\n        event.dataTransfer.effectAllowed = \"move\";\n        event.dataTransfer.setData(\"text/topsite-index\", this.props.index);\n        event.target.blur();\n        this.props.onDragEvent(event, this.props.index, this.props.link, this.props.title);\n        break;\n      case \"dragend\":\n        this.props.onDragEvent(event);\n        break;\n      case \"dragenter\":\n      case \"dragover\":\n      case \"drop\":\n        if (this._allowDrop(event)) {\n          event.preventDefault();\n          this.props.onDragEvent(event, this.props.index);\n        }\n        break;\n      case \"mousedown\":\n        // Reset at the first mouse event of a potential drag\n        this.dragged = false;\n        break;\n    }\n  }\n\n  render() {\n    const {children, className, defaultStyle, isDraggable, link, onClick, title} = this.props;\n    const topSiteOuterClassName = `top-site-outer${className ? ` ${className}` : \"\"}${link.isDragged ? \" dragged\" : \"\"}`;\n    const {tippyTopIcon, faviconSize} = link;\n    const [letterFallback] = title;\n    let imageClassName;\n    let imageStyle;\n    let showSmallFavicon = false;\n    let smallFaviconStyle;\n    let smallFaviconFallback;\n    if (defaultStyle) { // force no styles (letter fallback) even if the link has imagery\n      smallFaviconFallback = false;\n    } else if (link.customScreenshotURL) {\n      // assume high quality custom screenshot and use rich icon styles and class names\n      imageClassName = \"top-site-icon rich-icon\";\n      imageStyle = {\n        backgroundColor: link.backgroundColor,\n        backgroundImage: `url(${link.screenshot})`\n      };\n    } else if (tippyTopIcon || faviconSize >= MIN_RICH_FAVICON_SIZE) {\n      // styles and class names for top sites with rich icons\n      imageClassName = \"top-site-icon rich-icon\";\n      imageStyle = {\n        backgroundColor: link.backgroundColor,\n        backgroundImage: `url(${tippyTopIcon || link.favicon})`\n      };\n    } else {\n      // styles and class names for top sites with screenshot + small icon in top left corner\n      imageClassName = `screenshot${link.screenshot ? \" active\" : \"\"}`;\n      imageStyle = {backgroundImage: link.screenshot ? `url(${link.screenshot})` : \"none\"};\n\n      // only show a favicon in top left if it's greater than 16x16\n      if (faviconSize >= MIN_CORNER_FAVICON_SIZE) {\n        showSmallFavicon = true;\n        smallFaviconStyle = {backgroundImage:  `url(${link.favicon})`};\n      } else if (link.screenshot) {\n        // Don't show a small favicon if there is no screenshot, because that\n        // would result in two fallback icons\n        showSmallFavicon = true;\n        smallFaviconFallback = true;\n      }\n    }\n    let draggableProps = {};\n    if (isDraggable) {\n      draggableProps = {\n        onClick: this.onDragEvent,\n        onDragEnd: this.onDragEvent,\n        onDragStart: this.onDragEvent,\n        onMouseDown: this.onDragEvent\n      };\n    }\n    return (<li className={topSiteOuterClassName} onDrop={this.onDragEvent} onDragOver={this.onDragEvent} onDragEnter={this.onDragEvent} onDragLeave={this.onDragEvent} {...draggableProps}>\n      <div className=\"top-site-inner\">\n         <a href={link.url} onClick={onClick}>\n            <div className=\"tile\" aria-hidden={true} data-fallback={letterFallback}>\n              <div className={imageClassName} style={imageStyle} />\n              {showSmallFavicon && <div\n                className=\"top-site-icon default-icon\"\n                data-fallback={smallFaviconFallback && letterFallback}\n                style={smallFaviconStyle} />}\n           </div>\n           <div className={`title ${link.isPinned ? \"pinned\" : \"\"}`}>\n             {link.isPinned && <div className=\"icon icon-pin-small\" />}\n              <span dir=\"auto\">{title}</span>\n           </div>\n         </a>\n         {children}\n      </div>\n    </li>);\n  }\n}\nTopSiteLink.defaultProps = {\n  title: \"\",\n  link: {},\n  isDraggable: true\n};\n\nexport class TopSite extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.state = {showContextMenu: false};\n    this.onLinkClick = this.onLinkClick.bind(this);\n    this.onMenuButtonClick = this.onMenuButtonClick.bind(this);\n    this.onMenuUpdate = this.onMenuUpdate.bind(this);\n  }\n\n  /**\n   * Report to telemetry additional information about the item.\n   */\n  _getTelemetryInfo() {\n    const value = {icon_type: this.props.link.iconType};\n    // Filter out \"not_pinned\" type for being the default\n    if (this.props.link.isPinned) {\n      value.card_type = \"pinned\";\n    }\n    return {value};\n  }\n\n  userEvent(event) {\n    this.props.dispatch(ac.UserEvent(Object.assign({\n      event,\n      source: TOP_SITES_SOURCE,\n      action_position: this.props.index\n    }, this._getTelemetryInfo())));\n  }\n\n  onLinkClick(event) {\n    this.userEvent(\"CLICK\");\n\n    // Specially handle a top site link click for \"typed\" frecency bonus as\n    // specified as a property on the link.\n    event.preventDefault();\n    const {altKey, button, ctrlKey, metaKey, shiftKey} = event;\n    this.props.dispatch(ac.OnlyToMain({\n      type: at.OPEN_LINK,\n      data: Object.assign(this.props.link, {event: {altKey, button, ctrlKey, metaKey, shiftKey}})\n    }));\n  }\n\n  onMenuButtonClick(event) {\n    event.preventDefault();\n    this.props.onActivate(this.props.index);\n    this.setState({showContextMenu: true});\n  }\n\n  onMenuUpdate(showContextMenu) {\n    this.setState({showContextMenu});\n  }\n\n  render() {\n    const {props} = this;\n    const {link} = props;\n    const isContextMenuOpen = this.state.showContextMenu && props.activeIndex === props.index;\n    const title = link.label || link.hostname;\n    return (<TopSiteLink {...props} onClick={this.onLinkClick} onDragEvent={this.props.onDragEvent} className={`${props.className || \"\"}${isContextMenuOpen ? \" active\" : \"\"}`} title={title}>\n        <div>\n          <button className=\"context-menu-button icon\" onClick={this.onMenuButtonClick}>\n            <span className=\"sr-only\">\n              <FormattedMessage id=\"context_menu_button_sr\" values={{title}} />\n            </span>\n          </button>\n          {isContextMenuOpen &&\n            <LinkMenu\n              dispatch={props.dispatch}\n              index={props.index}\n              onUpdate={this.onMenuUpdate}\n              options={TOP_SITES_CONTEXT_MENU_OPTIONS}\n              site={link}\n              siteInfo={this._getTelemetryInfo()}\n              source={TOP_SITES_SOURCE} />\n          }\n        </div>\n    </TopSiteLink>);\n  }\n}\nTopSite.defaultProps = {\n  link: {},\n  onActivate() {}\n};\n\nexport class TopSitePlaceholder extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onEditButtonClick = this.onEditButtonClick.bind(this);\n  }\n\n  onEditButtonClick() {\n    this.props.dispatch(\n      {type: at.TOP_SITES_EDIT, data: {index: this.props.index}});\n  }\n\n  render() {\n    return (<TopSiteLink {...this.props} className={`placeholder ${this.props.className || \"\"}`} isDraggable={false}>\n      <button className=\"context-menu-button edit-button icon\"\n       title={this.props.intl.formatMessage({id: \"edit_topsites_edit_button\"})}\n       onClick={this.onEditButtonClick} />\n    </TopSiteLink>);\n  }\n}\n\nexport class _TopSiteList extends React.PureComponent {\n  static get DEFAULT_STATE() {\n    return {\n      activeIndex: null,\n      draggedIndex: null,\n      draggedSite: null,\n      draggedTitle: null,\n      topSitesPreview: null\n    };\n  }\n\n  constructor(props) {\n    super(props);\n    this.state = _TopSiteList.DEFAULT_STATE;\n    this.onDragEvent = this.onDragEvent.bind(this);\n    this.onActivate = this.onActivate.bind(this);\n  }\n\n  componentWillReceiveProps(nextProps) {\n    if (this.state.draggedSite) {\n      const prevTopSites = this.props.TopSites && this.props.TopSites.rows;\n      const newTopSites = nextProps.TopSites && nextProps.TopSites.rows;\n      if (prevTopSites && prevTopSites[this.state.draggedIndex] &&\n        prevTopSites[this.state.draggedIndex].url === this.state.draggedSite.url &&\n        (!newTopSites[this.state.draggedIndex] || newTopSites[this.state.draggedIndex].url !== this.state.draggedSite.url)) {\n        // We got the new order from the redux store via props. We can clear state now.\n        this.setState(_TopSiteList.DEFAULT_STATE);\n      }\n    }\n  }\n\n  userEvent(event, index) {\n    this.props.dispatch(ac.UserEvent({\n      event,\n      source: TOP_SITES_SOURCE,\n      action_position: index\n    }));\n  }\n\n  onDragEvent(event, index, link, title) {\n    switch (event.type) {\n      case \"dragstart\":\n        this.dropped = false;\n        this.setState({\n          draggedIndex: index,\n          draggedSite: link,\n          draggedTitle: title,\n          activeIndex: null\n        });\n        this.userEvent(\"DRAG\", index);\n        break;\n      case \"dragend\":\n        if (!this.dropped) {\n          // If there was no drop event, reset the state to the default.\n          this.setState(_TopSiteList.DEFAULT_STATE);\n        }\n        break;\n      case \"dragenter\":\n        if (index === this.state.draggedIndex) {\n          this.setState({topSitesPreview: null});\n        } else {\n          this.setState({topSitesPreview: this._makeTopSitesPreview(index)});\n        }\n        break;\n      case \"drop\":\n        if (index !== this.state.draggedIndex) {\n          this.dropped = true;\n          this.props.dispatch(ac.AlsoToMain({\n            type: at.TOP_SITES_INSERT,\n            data: {\n              site: {\n                url: this.state.draggedSite.url,\n                label: this.state.draggedTitle,\n                customScreenshotURL: this.state.draggedSite.customScreenshotURL\n              },\n              index,\n              draggedFromIndex: this.state.draggedIndex\n            }\n          }));\n          this.userEvent(\"DROP\", index);\n        }\n        break;\n    }\n  }\n\n  _getTopSites() {\n    // Make a copy of the sites to truncate or extend to desired length\n    let topSites = this.props.TopSites.rows.slice();\n    topSites.length = this.props.TopSitesRows * TOP_SITES_MAX_SITES_PER_ROW;\n    return topSites;\n  }\n\n  /**\n   * Make a preview of the topsites that will be the result of dropping the currently\n   * dragged site at the specified index.\n   */\n  _makeTopSitesPreview(index) {\n    const topSites = this._getTopSites();\n    topSites[this.state.draggedIndex] = null;\n    const pinnedOnly = topSites.map(site => ((site && site.isPinned) ? site : null));\n    const unpinned = topSites.filter(site => site && !site.isPinned);\n    const siteToInsert = Object.assign({}, this.state.draggedSite, {isPinned: true, isDragged: true});\n    if (!pinnedOnly[index]) {\n      pinnedOnly[index] = siteToInsert;\n    } else {\n      // Find the hole to shift the pinned site(s) towards. We shift towards the\n      // hole left by the site being dragged.\n      let holeIndex = index;\n      const indexStep = index > this.state.draggedIndex ? -1 : 1;\n      while (pinnedOnly[holeIndex]) {\n        holeIndex += indexStep;\n      }\n\n      // Shift towards the hole.\n      const shiftingStep = index > this.state.draggedIndex ? 1 : -1;\n      while (holeIndex !== index) {\n        const nextIndex = holeIndex + shiftingStep;\n        pinnedOnly[holeIndex] = pinnedOnly[nextIndex];\n        holeIndex = nextIndex;\n      }\n      pinnedOnly[index] = siteToInsert;\n    }\n\n    // Fill in the remaining holes with unpinned sites.\n    const preview = pinnedOnly;\n    for (let i = 0; i < preview.length; i++) {\n      if (!preview[i]) {\n        preview[i] = unpinned.shift() || null;\n      }\n    }\n\n    return preview;\n  }\n\n  onActivate(index) {\n    this.setState({activeIndex: index});\n  }\n\n  render() {\n    const {props} = this;\n    const topSites = this.state.topSitesPreview || this._getTopSites();\n    const topSitesUI = [];\n    const commonProps = {\n      onDragEvent: this.onDragEvent,\n      dispatch: props.dispatch,\n      intl: props.intl\n    };\n    // We assign a key to each placeholder slot. We need it to be independent\n    // of the slot index (i below) so that the keys used stay the same during\n    // drag and drop reordering and the underlying DOM nodes are reused.\n    // This mostly (only?) affects linux so be sure to test on linux before changing.\n    let holeIndex = 0;\n\n    // On narrow viewports, we only show 6 sites per row. We'll mark the rest as\n    // .hide-for-narrow to hide in CSS via @media query.\n    const maxNarrowVisibleIndex = props.TopSitesRows * 6;\n\n    for (let i = 0, l = topSites.length; i < l; i++) {\n      const link = topSites[i] && Object.assign({}, topSites[i], {iconType: this.props.topSiteIconType(topSites[i])});\n      const slotProps = {\n        key: link ? link.url : holeIndex++,\n        index: i\n      };\n      if (i >= maxNarrowVisibleIndex) {\n        slotProps.className = \"hide-for-narrow\";\n      }\n      topSitesUI.push(!link ? (\n        <TopSitePlaceholder\n          {...slotProps}\n          {...commonProps} />\n      ) : (\n        <TopSite\n          link={link}\n          activeIndex={this.state.activeIndex}\n          onActivate={this.onActivate}\n          {...slotProps}\n          {...commonProps} />\n      ));\n    }\n    return (<ul className={`top-sites-list${this.state.draggedSite ? \" dnd-active\" : \"\"}`}>\n      {topSitesUI}\n    </ul>);\n  }\n}\n\nexport const TopSiteList = injectIntl(_TopSiteList);\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/TopSites/TopSite.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {addSnippetsSubscriber} from \"content-src/lib/snippets\";\nimport {Base} from \"content-src/components/Base/Base\";\nimport {DetectUserSessionStart} from \"content-src/lib/detect-user-session-start\";\nimport {initStore} from \"content-src/lib/init-store\";\nimport {Provider} from \"react-redux\";\nimport React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport {reducers} from \"common/Reducers.jsm\";\n\nconst store = initStore(reducers, global.gActivityStreamPrerenderedState);\n\nnew DetectUserSessionStart(store).sendEventOrAddListener();\n\n// If we are starting in a prerendered state, we must wait until the first render\n// to request state rehydration (see Base.jsx). If we are NOT in a prerendered state,\n// we can request it immedately.\nif (!global.gActivityStreamPrerenderedState) {\n  store.dispatch(ac.AlsoToMain({type: at.NEW_TAB_STATE_REQUEST}));\n}\n\nReactDOM.hydrate(<Provider store={store}>\n  <Base\n    isFirstrun={global.document.location.href === \"about:welcome\"}\n    isPrerendered={!!global.gActivityStreamPrerenderedState}\n    locale={global.document.documentElement.lang}\n    strings={global.gActivityStreamStrings} />\n</Provider>, document.getElementById(\"root\"));\n\naddSnippetsSubscriber(store);\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/activity-stream.jsx","const DATABASE_NAME = \"snippets_db\";\nconst DATABASE_VERSION = 1;\nconst SNIPPETS_OBJECTSTORE_NAME = \"snippets\";\nexport const SNIPPETS_UPDATE_INTERVAL_MS = 14400000; // 4 hours.\n\nconst SNIPPETS_ENABLED_EVENT = \"Snippets:Enabled\";\nconst SNIPPETS_DISABLED_EVENT = \"Snippets:Disabled\";\n\nimport {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {ASRouterContent} from \"content-src/asrouter/asrouter-content\";\n\n/**\n * SnippetsMap - A utility for cacheing values related to the snippet. It has\n *               the same interface as a Map, but is optionally backed by\n *               indexedDB for persistent storage.\n *               Call .connect() to open a database connection and restore any\n *               previously cached data, if necessary.\n *\n */\nexport class SnippetsMap extends Map {\n  constructor(dispatch) {\n    super();\n    this._db = null;\n    this._dispatch = dispatch;\n  }\n\n  set(key, value) {\n    super.set(key, value);\n    return this._dbTransaction(db => db.put(value, key));\n  }\n\n  delete(key) {\n    super.delete(key);\n    return this._dbTransaction(db => db.delete(key));\n  }\n\n  clear() {\n    super.clear();\n    this._dispatch(ac.OnlyToMain({type: at.SNIPPETS_BLOCKLIST_CLEARED}));\n    return this._dbTransaction(db => db.clear());\n  }\n\n  get blockList() {\n    return this.get(\"blockList\") || [];\n  }\n\n  /**\n   * blockSnippetById - Blocks a snippet given an id\n   *\n   * @param  {str|int} id   The id of the snippet\n   * @return {Promise}      Resolves when the id has been written to indexedDB,\n   *                        or immediately if the snippetMap is not connected\n   */\n  async blockSnippetById(id) {\n    if (!id) {\n      return;\n    }\n    const {blockList} = this;\n    if (!blockList.includes(id)) {\n      blockList.push(id);\n      this._dispatch(ac.AlsoToMain({type: at.SNIPPETS_BLOCKLIST_UPDATED, data: id}));\n      await this.set(\"blockList\", blockList);\n    }\n  }\n\n  disableOnboarding() {\n    this._dispatch(ac.AlsoToMain({type: at.DISABLE_ONBOARDING}));\n  }\n\n  showFirefoxAccounts() {\n    this._dispatch(ac.AlsoToMain({type: at.SHOW_FIREFOX_ACCOUNTS}));\n  }\n\n  getTotalBookmarksCount() {\n    return new Promise(resolve => {\n      this._dispatch(ac.OnlyToMain({type: at.TOTAL_BOOKMARKS_REQUEST}));\n      global.addMessageListener(\"ActivityStream:MainToContent\", function onMessage({data: action}) {\n        if (action.type === at.TOTAL_BOOKMARKS_RESPONSE) {\n          resolve(action.data);\n          global.removeMessageListener(\"ActivityStream:MainToContent\", onMessage);\n        }\n      });\n    });\n  }\n\n  getAddonsInfo() {\n    return new Promise(resolve => {\n      this._dispatch(ac.OnlyToMain({type: at.ADDONS_INFO_REQUEST}));\n      global.addMessageListener(\"ActivityStream:MainToContent\", function onMessage({data: action}) {\n        if (action.type === at.ADDONS_INFO_RESPONSE) {\n          resolve(action.data);\n          global.removeMessageListener(\"ActivityStream:MainToContent\", onMessage);\n        }\n      });\n    });\n  }\n\n  /**\n   * connect - Attaches an indexedDB back-end to the Map so that any set values\n   *           are also cached in a store. It also restores any existing values\n   *           that are already stored in the indexedDB store.\n   *\n   * @return {type}  description\n   */\n  async connect() {\n    // Open the connection\n    const db = await this._openDB();\n\n    // Restore any existing values\n    await this._restoreFromDb(db);\n\n    // Attach a reference to the db\n    this._db = db;\n  }\n\n  /**\n   * _dbTransaction - Returns a db transaction wrapped with the given modifier\n   *                  function as a Promise. If the db has not been connected,\n   *                  it resolves immediately.\n   *\n   * @param  {func} modifier A function to call with the transaction\n   * @return {obj}           A Promise that resolves when the transaction has\n   *                         completed or errored\n   */\n  _dbTransaction(modifier) {\n    if (!this._db) {\n      return Promise.resolve();\n    }\n    return new Promise((resolve, reject) => {\n      const transaction = modifier(\n        this._db\n          .transaction(SNIPPETS_OBJECTSTORE_NAME, \"readwrite\")\n          .objectStore(SNIPPETS_OBJECTSTORE_NAME)\n      );\n      transaction.onsuccess = event => resolve();\n\n      /* istanbul ignore next */\n      transaction.onerror = event => reject(transaction.error);\n    });\n  }\n\n  _openDB() {\n    return new Promise((resolve, reject) => {\n      const openRequest = indexedDB.open(DATABASE_NAME, DATABASE_VERSION);\n\n      /* istanbul ignore next */\n      openRequest.onerror = event => {\n        // Try to delete the old database so that we can start this process over\n        // next time.\n        indexedDB.deleteDatabase(DATABASE_NAME);\n        reject(event);\n      };\n\n      openRequest.onupgradeneeded = event => {\n        const db = event.target.result;\n        if (!db.objectStoreNames.contains(SNIPPETS_OBJECTSTORE_NAME)) {\n          db.createObjectStore(SNIPPETS_OBJECTSTORE_NAME);\n        }\n      };\n\n      openRequest.onsuccess = event => {\n        let db = event.target.result;\n\n        /* istanbul ignore next */\n        db.onerror = err => console.error(err); // eslint-disable-line no-console\n        /* istanbul ignore next */\n        db.onversionchange = versionChangeEvent => versionChangeEvent.target.close();\n\n        resolve(db);\n      };\n    });\n  }\n\n  _restoreFromDb(db) {\n    return new Promise((resolve, reject) => {\n      let cursorRequest;\n      try {\n        cursorRequest = db.transaction(SNIPPETS_OBJECTSTORE_NAME)\n          .objectStore(SNIPPETS_OBJECTSTORE_NAME).openCursor();\n      } catch (err) {\n        // istanbul ignore next\n        reject(err);\n        // istanbul ignore next\n        return;\n      }\n\n      /* istanbul ignore next */\n      cursorRequest.onerror = event => reject(event);\n\n      cursorRequest.onsuccess = event => {\n        let cursor = event.target.result;\n        // Populate the cache from the persistent storage.\n        if (cursor) {\n          if (cursor.value !== \"blockList\") {\n            this.set(cursor.key, cursor.value);\n          }\n          cursor.continue();\n        } else {\n          // We are done.\n          resolve();\n        }\n      };\n    });\n  }\n}\n\n/**\n * SnippetsProvider - Initializes a SnippetsMap and loads snippets from a\n *                    remote location, or else default snippets if the remote\n *                    snippets cannot be retrieved.\n */\nexport class SnippetsProvider {\n  constructor(dispatch) {\n    // Initialize the Snippets Map and attaches it to a global so that\n    // the snippet payload can interact with it.\n    global.gSnippetsMap = new SnippetsMap(dispatch);\n    this._onAction = this._onAction.bind(this);\n  }\n\n  get snippetsMap() {\n    return global.gSnippetsMap;\n  }\n\n  async _refreshSnippets() {\n    // Check if the cached version of of the snippets in snippetsMap. If it's too\n    // old, blow away the entire snippetsMap.\n    const cachedVersion = this.snippetsMap.get(\"snippets-cached-version\");\n\n    if (cachedVersion !== this.appData.version) {\n      this.snippetsMap.clear();\n    }\n\n    // Has enough time passed for us to require an update?\n    const lastUpdate = this.snippetsMap.get(\"snippets-last-update\");\n    const needsUpdate = !(lastUpdate >= 0) || Date.now() - lastUpdate > SNIPPETS_UPDATE_INTERVAL_MS;\n\n    if (needsUpdate && this.appData.snippetsURL) {\n      this.snippetsMap.set(\"snippets-last-update\", Date.now());\n      try {\n        const response = await fetch(this.appData.snippetsURL);\n        if (response.status === 200) {\n          const payload = await response.text();\n\n          this.snippetsMap.set(\"snippets\", payload);\n          this.snippetsMap.set(\"snippets-cached-version\", this.appData.version);\n        }\n      } catch (e) {\n        console.error(e); // eslint-disable-line no-console\n      }\n    }\n  }\n\n  _noSnippetFallback() {\n    // TODO\n  }\n\n  _forceOnboardingVisibility(shouldBeVisible) {\n    const onboardingEl = document.getElementById(\"onboarding-notification-bar\");\n\n    if (onboardingEl) {\n      onboardingEl.style.display = shouldBeVisible ? \"\" : \"none\";\n    }\n  }\n\n  _showRemoteSnippets() {\n    const snippetsEl = document.getElementById(this.elementId);\n    const payload = this.snippetsMap.get(\"snippets\");\n\n    if (!snippetsEl) {\n      throw new Error(`No element was found with id '${this.elementId}'.`);\n    }\n\n    // This could happen if fetching failed\n    if (!payload) {\n      throw new Error(\"No remote snippets were found in gSnippetsMap.\");\n    }\n\n    if (typeof payload !== \"string\") {\n      throw new Error(\"Snippet payload was incorrectly formatted\");\n    }\n\n    // Note that injecting snippets can throw if they're invalid XML.\n    // eslint-disable-next-line no-unsanitized/property\n    snippetsEl.innerHTML = payload;\n\n    // Scripts injected by innerHTML are inactive, so we have to relocate them\n    // through DOM manipulation to activate their contents.\n    for (const scriptEl of snippetsEl.getElementsByTagName(\"script\")) {\n      const relocatedScript = document.createElement(\"script\");\n      relocatedScript.text = scriptEl.text;\n      scriptEl.parentNode.replaceChild(relocatedScript, scriptEl);\n    }\n  }\n\n  _onAction(msg) {\n    if (msg.data.type === at.SNIPPET_BLOCKED) {\n      if (!this.snippetsMap.blockList.includes(msg.data.data)) {\n        this.snippetsMap.set(\"blockList\", this.snippetsMap.blockList.concat(msg.data.data));\n        document.getElementById(\"snippets-container\").style.display = \"none\";\n      }\n    }\n  }\n\n  /**\n   * init - Fetch the snippet payload and show snippets\n   *\n   * @param  {obj} options\n   * @param  {str} options.appData.snippetsURL  The URL from which we fetch snippets\n   * @param  {int} options.appData.version  The current snippets version\n   * @param  {str} options.elementId  The id of the element in which to inject snippets\n   * @param  {bool} options.connect  Should gSnippetsMap connect to indexedDB?\n   */\n  async init(options) {\n    Object.assign(this, {\n      appData: {},\n      elementId: \"snippets\",\n      connect: true\n    }, options);\n\n    // Add listener so we know when snippets are blocked on other pages\n    if (global.addMessageListener) {\n      global.addMessageListener(\"ActivityStream:MainToContent\", this._onAction);\n    }\n\n    // TODO: Requires enabling indexedDB on newtab\n    // Restore the snippets map from indexedDB\n    if (this.connect) {\n      try {\n        await this.snippetsMap.connect();\n      } catch (e) {\n        console.error(e); // eslint-disable-line no-console\n      }\n    }\n\n    // Cache app data values so they can be accessible from gSnippetsMap\n    for (const key of Object.keys(this.appData)) {\n      if (key === \"blockList\") {\n        this.snippetsMap.set(\"blockList\", this.appData[key]);\n      } else {\n        this.snippetsMap.set(`appData.${key}`, this.appData[key]);\n      }\n    }\n\n    // Refresh snippets, if enough time has passed.\n    await this._refreshSnippets();\n\n    // Try showing remote snippets, falling back to defaults if necessary.\n    try {\n      this._showRemoteSnippets();\n    } catch (e) {\n      this._noSnippetFallback(e);\n    }\n\n    window.dispatchEvent(new Event(SNIPPETS_ENABLED_EVENT));\n\n    this._forceOnboardingVisibility(true);\n    this.initialized = true;\n  }\n\n  uninit() {\n    window.dispatchEvent(new Event(SNIPPETS_DISABLED_EVENT));\n    this._forceOnboardingVisibility(false);\n    if (global.removeMessageListener) {\n      global.removeMessageListener(\"ActivityStream:MainToContent\", this._onAction);\n    }\n    this.initialized = false;\n  }\n}\n\n/**\n * addSnippetsSubscriber - Creates a SnippetsProvider that Initializes\n *                         when the store has received the appropriate\n *                         Snippet data.\n *\n * @param  {obj} store   The redux store\n * @return {obj}         Returns the snippets instance, asrouterContent instance and unsubscribe function\n */\nexport function addSnippetsSubscriber(store) {\n  const snippets = new SnippetsProvider(store.dispatch);\n  const asrouterContent = new ASRouterContent();\n\n  let initializing = false;\n\n  store.subscribe(async () => {\n    const state = store.getState();\n    // state.Prefs.values[\"feeds.snippets\"]:  Should snippets be shown?\n    // state.Snippets.initialized             Is the snippets data initialized?\n    // snippets.initialized:                  Is SnippetsProvider currently initialised?\n    if (state.Prefs.values[\"feeds.snippets\"] &&\n      // If the message center experiment is enabled, don't show snippets\n      !state.Prefs.values.asrouterExperimentEnabled &&\n      !state.Prefs.values.disableSnippets &&\n      state.Snippets.initialized &&\n      !snippets.initialized &&\n      // Don't call init multiple times\n      !initializing &&\n      location.href !== \"about:welcome\"\n    ) {\n      initializing = true;\n      await snippets.init({appData: state.Snippets});\n      initializing = false;\n    } else if (\n      (state.Prefs.values[\"feeds.snippets\"] === false ||\n        state.Prefs.values.disableSnippets === true) &&\n      snippets.initialized\n    ) {\n      snippets.uninit();\n    }\n\n    // Turn on AS Router snippets if the experiment is enabled and the snippets pref is on;\n    // otherwise, turn it off.\n    if (\n      state.Prefs.values.asrouterExperimentEnabled &&\n      state.Prefs.values[\"feeds.snippets\"] &&\n      !asrouterContent.initialized) {\n      asrouterContent.init();\n    } else if (\n      (!state.Prefs.values.asrouterExperimentEnabled || !state.Prefs.values[\"feeds.snippets\"]) &&\n      asrouterContent.initialized\n    ) {\n      asrouterContent.uninit();\n    }\n  });\n\n  // These values are returned for testing purposes\n  return {snippets, asrouterContent};\n}\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/lib/snippets.js","module.exports = Redux;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external \"Redux\"\n// module id = 21\n// module chunks = 0","import React from \"react\";\n\nexport const VISIBLE = \"visible\";\nexport const VISIBILITY_CHANGE_EVENT = \"visibilitychange\";\n\n/**\n * Component wrapper used to send telemetry pings on every impression.\n */\nexport class ImpressionsWrapper extends React.PureComponent {\n  // This sends an event when a user sees a set of new content. If content\n  // changes while the page is hidden (i.e. preloaded or on a hidden tab),\n  // only send the event if the page becomes visible again.\n  sendImpressionOrAddListener() {\n    if (this.props.document.visibilityState === VISIBLE) {\n      this.props.sendImpression({id: this.props.id});\n    } else {\n      // We should only ever send the latest impression stats ping, so remove any\n      // older listeners.\n      if (this._onVisibilityChange) {\n        this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n      }\n\n      // When the page becomes visible, send the impression stats ping if the section isn't collapsed.\n      this._onVisibilityChange = () => {\n        if (this.props.document.visibilityState === VISIBLE) {\n          this.props.sendImpression({id: this.props.id});\n          this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n        }\n      };\n      this.props.document.addEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n    }\n  }\n\n  componentWillUnmount() {\n    if (this._onVisibilityChange) {\n      this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n    }\n  }\n\n  componentDidMount() {\n    if (this.props.sendOnMount) {\n      this.sendImpressionOrAddListener();\n    }\n  }\n\n  componentDidUpdate(prevProps) {\n    if (this.props.shouldSendImpressionOnUpdate(this.props, prevProps)) {\n      this.sendImpressionOrAddListener();\n    }\n  }\n\n  render() {\n    return this.props.children;\n  }\n}\n\nImpressionsWrapper.defaultProps = {\n  document: global.document,\n  sendOnMount: true\n};\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/asrouter/components/ImpressionsWrapper/ImpressionsWrapper.jsx","import React from \"react\";\n\nexport class ModalOverlay extends React.PureComponent {\n  componentWillMount() {\n    this.setState({active: true});\n    document.body.classList.add(\"modal-open\");\n  }\n\n  componentWillUnmount() {\n    document.body.classList.remove(\"modal-open\");\n    this.setState({active: false});\n  }\n\n  render() {\n    const {active} = this.state;\n    const {title, button_label} = this.props;\n    return (\n      <div>\n        <div className={`modalOverlayOuter ${active ? \"active\" : \"\"}`} />\n        <div className={`modalOverlayInner ${active ? \"active\" : \"\"}`}>\n          <h2> {title} </h2>\n          {this.props.children}\n          <div className=\"footer\">\n            <button onClick={this.props.onDoneButton} className=\"button primary modalButton\"> {button_label} </button>\n          </div>\n        </div>\n      </div>\n    );\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/asrouter/components/ModalOverlay/ModalOverlay.jsx","import {ModalOverlay} from \"../../components/ModalOverlay/ModalOverlay\";\nimport React from \"react\";\n\nclass OnboardingCard extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onClick = this.onClick.bind(this);\n  }\n\n  onClick() {\n    const {props} = this;\n    props.sendUserActionTelemetry({event: \"CLICK_BUTTON\", message_id: props.id, id: props.UISurface});\n    props.onAction(props.content);\n  }\n\n  render() {\n    const {content} = this.props;\n    return (\n      <div className=\"onboardingMessage\">\n        <div className={`onboardingMessageImage ${content.icon}`} />\n        <div className=\"onboardingContent\">\n          <span>\n            <h3> {content.title} </h3>\n            <p> {content.text} </p>\n          </span>\n          <span>\n            <button className=\"button onboardingButton\" onClick={this.onClick}> {content.button_label} </button>\n          </span>\n        </div>\n      </div>\n    );\n  }\n}\n\nexport class OnboardingMessage extends React.PureComponent {\n  render() {\n    const {props} = this;\n    return (\n      <ModalOverlay {...props} button_label={\"Start Browsing\"} title={\"Welcome to Firefox\"}>\n        <div className=\"onboardingMessageContainer\">\n          {props.bundle.map(message => (\n            <OnboardingCard key={message.id}\n              sendUserActionTelemetry={props.sendUserActionTelemetry}\n              onAction={props.onAction}\n              UISurface={props.UISurface}\n              {...message} />\n          ))}\n        </div>\n      </ModalOverlay>\n    );\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/asrouter/templates/OnboardingMessage/OnboardingMessage.jsx","export function safeURI(url) {\n  if (!url) {\n    return \"\";\n  }\n  const {protocol} = new URL(url);\n  const isAllowed = [\n    \"http:\",\n    \"https:\",\n    \"data:\",\n    \"resource:\",\n    \"chrome:\"\n  ].includes(protocol);\n  if (!isAllowed) {\n    console.warn(`The protocol ${protocol} is not allowed for template URLs.`); // eslint-disable-line no-console\n  }\n  return isAllowed ? url : \"\";\n}\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/asrouter/template-utils.js","import React from \"react\";\nimport {safeURI} from \"../../template-utils\";\n\nconst ALLOWED_STYLE_TAGS = [\"color\", \"backgroundColor\"];\n\nexport const Button = props => {\n  const style = {};\n\n  // Add allowed style tags from props, e.g. props.color becomes style={color: props.color}\n  for (const tag of ALLOWED_STYLE_TAGS) {\n    if (typeof props[tag] !== \"undefined\") {\n      style[tag] = props[tag];\n    }\n  }\n  // remove border if bg is set to something custom\n  if (style.backgroundColor) {\n    style.border = \"0\";\n  }\n\n  return (<a href={safeURI(props.url)}\n    onClick={props.onClick}\n    className={props.className || \"ASRouterButton\"}\n    style={style}>\n    {props.children}\n  </a>);\n};\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/asrouter/components/Button/Button.jsx","import React from \"react\";\n\nexport class SnippetBase extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onBlockClicked = this.onBlockClicked.bind(this);\n  }\n\n  onBlockClicked() {\n    this.props.sendUserActionTelemetry({event: \"BLOCK\", id: this.props.UISurface});\n    this.props.onBlock();\n  }\n\n  render() {\n    const {props} = this;\n\n    const containerClassName = `SnippetBaseContainer${props.className ? ` ${props.className}` : \"\"}`;\n\n    return (<div className={containerClassName}>\n      <div className=\"innerWrapper\">\n        {props.children}\n      </div>\n      <button className=\"blockButton\" onClick={this.onBlockClicked} />\n    </div>);\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/asrouter/components/SnippetBase/SnippetBase.jsx","import {Button} from \"../../components/Button/Button\";\nimport React from \"react\";\nimport {safeURI} from \"../../template-utils\";\nimport {SnippetBase} from \"../../components/SnippetBase/SnippetBase\";\n\nconst DEFAULT_ICON_PATH = \"chrome://branding/content/icon64.png\";\n\nexport class SimpleSnippet extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onButtonClick = this.onButtonClick.bind(this);\n  }\n\n  onButtonClick() {\n    this.props.sendUserActionTelemetry({event: \"CLICK_BUTTON\", id: this.props.UISurface});\n  }\n\n  renderTitle() {\n    const {title} = this.props.content;\n    return title ? <h3 className=\"title\">{title}</h3> : null;\n  }\n\n  renderTitleIcon() {\n    const titleIcon = safeURI(this.props.content.title_icon);\n    return titleIcon ? <span className=\"titleIcon\" style={{backgroundImage: `url(\"${titleIcon}\")`}} /> : null;\n  }\n\n  renderButton(className) {\n    const {props} = this;\n    return (<Button\n      className={className}\n      onClick={this.onButtonClick}\n      url={props.content.button_url}\n      color={props.content.button_color}\n      backgroundColor={props.content.button_background_color}>\n      {props.content.button_label}\n    </Button>);\n  }\n\n  render() {\n    const {props} = this;\n    const hasLink = props.content.button_url && props.content.button_type === \"anchor\";\n    const hasButton = props.content.button_url && !props.content.button_type;\n    const className = `SimpleSnippet${props.content.tall ? \" tall\" : \"\"}`;\n    return (<SnippetBase {...props} className={className}>\n      <img src={safeURI(props.content.icon) || DEFAULT_ICON_PATH} className=\"icon\" />\n      <div>\n        {this.renderTitleIcon()} {this.renderTitle()} <p className=\"body\">{props.content.text}</p> {hasLink ? this.renderButton(\"ASRouterAnchor\") : null}\n      </div>\n      {hasButton ? <div>{this.renderButton()}</div> : null}\n    </SnippetBase>);\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/asrouter/templates/SimpleSnippet/SimpleSnippet.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {addLocaleData, injectIntl, IntlProvider} from \"react-intl\";\nimport {ASRouterAdmin} from \"content-src/components/ASRouterAdmin/ASRouterAdmin\";\nimport {ConfirmDialog} from \"content-src/components/ConfirmDialog/ConfirmDialog\";\nimport {connect} from \"react-redux\";\nimport {ErrorBoundary} from \"content-src/components/ErrorBoundary/ErrorBoundary\";\nimport {ManualMigration} from \"content-src/components/ManualMigration/ManualMigration\";\nimport {PrerenderData} from \"common/PrerenderData.jsm\";\nimport React from \"react\";\nimport {Search} from \"content-src/components/Search/Search\";\nimport {Sections} from \"content-src/components/Sections/Sections\";\nimport {StartupOverlay} from \"content-src/components/StartupOverlay/StartupOverlay\";\n\nconst PrefsButton = injectIntl(props => (\n  <div className=\"prefs-button\">\n    <button className=\"icon icon-settings\" onClick={props.onClick} title={props.intl.formatMessage({id: \"settings_pane_button_label\"})} />\n  </div>\n));\n\n// Add the locale data for pluralization and relative-time formatting for now,\n// this just uses english locale data. We can make this more sophisticated if\n// more features are needed.\nfunction addLocaleDataForReactIntl(locale) {\n  addLocaleData([{locale, parentLocale: \"en\"}]);\n}\n\nexport class _Base extends React.PureComponent {\n  componentWillMount() {\n    const {App, locale, Theme} = this.props;\n    if (Theme.className) {\n      this.updateTheme(Theme);\n    }\n    this.sendNewTabRehydrated(App);\n    addLocaleDataForReactIntl(locale);\n  }\n\n  componentDidMount() {\n    // Request state AFTER the first render to ensure we don't cause the\n    // prerendered DOM to be unmounted. Otherwise, NEW_TAB_STATE_REQUEST is\n    // dispatched right after the store is ready.\n    if (this.props.isPrerendered) {\n      this.props.dispatch(ac.AlsoToMain({type: at.NEW_TAB_STATE_REQUEST}));\n      this.props.dispatch(ac.AlsoToMain({type: at.PAGE_PRERENDERED}));\n    }\n  }\n\n  componentWillUnmount() {\n    this.updateTheme({className: \"\"});\n  }\n\n  componentWillUpdate({App, Theme}) {\n    this.updateTheme(Theme);\n    this.sendNewTabRehydrated(App);\n  }\n\n  updateTheme(Theme) {\n    const bodyClassName = [\n      \"activity-stream\",\n      Theme.className,\n      this.props.isFirstrun ? \"welcome\" : \"\"\n    ].filter(v => v).join(\" \");\n    global.document.body.className = bodyClassName;\n  }\n\n  // The NEW_TAB_REHYDRATED event is used to inform feeds that their\n  // data has been consumed e.g. for counting the number of tabs that\n  // have rendered that data.\n  sendNewTabRehydrated(App) {\n    if (App && App.initialized && !this.renderNotified) {\n      this.props.dispatch(ac.AlsoToMain({type: at.NEW_TAB_REHYDRATED, data: {}}));\n      this.renderNotified = true;\n    }\n  }\n\n  render() {\n    const {props} = this;\n    const {App, locale, strings} = props;\n    const {initialized} = App;\n\n    if (props.Prefs.values.asrouterExperimentEnabled && window.location.hash === \"#asrouter\") {\n      return (<ASRouterAdmin />);\n    }\n\n    if (!props.isPrerendered && !initialized) {\n      return null;\n    }\n\n    return (<IntlProvider locale={locale} messages={strings}>\n        <ErrorBoundary className=\"base-content-fallback\">\n          <BaseContent {...this.props} />\n        </ErrorBoundary>\n      </IntlProvider>);\n  }\n}\n\nexport class BaseContent extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.openPreferences = this.openPreferences.bind(this);\n  }\n\n  openPreferences() {\n    this.props.dispatch(ac.OnlyToMain({type: at.SETTINGS_OPEN}));\n    this.props.dispatch(ac.UserEvent({event: \"OPEN_NEWTAB_PREFS\"}));\n  }\n\n  render() {\n    const {props} = this;\n    const {App} = props;\n    const {initialized} = App;\n    const prefs = props.Prefs.values;\n\n    const shouldBeFixedToTop = PrerenderData.arePrefsValid(name => prefs[name]);\n\n    const outerClassName = [\n      \"outer-wrapper\",\n      shouldBeFixedToTop && \"fixed-to-top\"\n    ].filter(v => v).join(\" \");\n\n    return (\n      <div>\n        <div className={outerClassName}>\n          <main>\n            {prefs.showSearch &&\n              <div className=\"non-collapsible-section\">\n                <ErrorBoundary>\n                  <Search />\n                </ErrorBoundary>\n              </div>\n            }\n            <div className={`body-wrapper${(initialized ? \" on\" : \"\")}`}>\n              {!prefs.migrationExpired &&\n                <div className=\"non-collapsible-section\">\n                  <ManualMigration />\n                </div>\n                }\n              <Sections />\n              <PrefsButton onClick={this.openPreferences} />\n            </div>\n            <ConfirmDialog />\n          </main>\n        </div>\n        {this.props.isFirstrun && <StartupOverlay />}\n      </div>);\n  }\n}\n\nexport const Base = connect(state => ({App: state.App, Prefs: state.Prefs, Theme: state.Theme}))(_Base);\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/Base/Base.jsx","import {ASRouterUtils} from \"../../asrouter/asrouter-content\";\nimport React from \"react\";\n\nexport class ASRouterAdmin extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onMessage = this.onMessage.bind(this);\n    this.findOtherBundledMessagesOfSameTemplate = this.findOtherBundledMessagesOfSameTemplate.bind(this);\n    this.state = {};\n  }\n\n  onMessage({data: action}) {\n    if (action.type === \"ADMIN_SET_STATE\") {\n      this.setState(action.data);\n    }\n  }\n\n  componentWillMount() {\n    ASRouterUtils.sendMessage({type: \"ADMIN_CONNECT_STATE\"});\n    ASRouterUtils.addListener(this.onMessage);\n  }\n\n  componentWillUnmount() {\n    ASRouterUtils.removeListener(this.onMessage);\n  }\n\n  findOtherBundledMessagesOfSameTemplate(template) {\n    return this.state.messages.filter(msg => msg.template === template && msg.bundled);\n  }\n\n  handleBlock(msg) {\n    if (msg.bundled) {\n      // If we are blocking a message that belongs to a bundle, block all other messages that are bundled of that same template\n      let bundle = this.findOtherBundledMessagesOfSameTemplate(msg.template);\n      return () => ASRouterUtils.blockBundle(bundle);\n    }\n    return () => ASRouterUtils.blockById(msg.id);\n  }\n\n  handleUnblock(msg) {\n    if (msg.bundled) {\n      // If we are unblocking a message that belongs to a bundle, unblock all other messages that are bundled of that same template\n      let bundle = this.findOtherBundledMessagesOfSameTemplate(msg.template);\n      return () => ASRouterUtils.unblockBundle(bundle);\n    }\n    return () => ASRouterUtils.unblockById(msg.id);\n  }\n\n  handleOverride(id) {\n    return () => ASRouterUtils.overrideMessage(id);\n  }\n\n  renderMessageItem(msg) {\n    const isCurrent = msg.id === this.state.lastMessageId;\n    const isBlocked = this.state.blockList.includes(msg.id);\n\n    let itemClassName = \"message-item\";\n    if (isCurrent) { itemClassName += \" current\"; }\n    if (isBlocked) { itemClassName += \" blocked\"; }\n\n    return (<tr className={itemClassName} key={msg.id}>\n      <td className=\"message-id\"><span>{msg.id}</span></td>\n      <td>\n        <button className={`button ${(isBlocked ? \"\" : \" primary\")}`} onClick={isBlocked ? this.handleUnblock(msg) : this.handleBlock(msg)}>{isBlocked ? \"Unblock\" : \"Block\"}</button>\n       {isBlocked ? null : <button className=\"button\" onClick={this.handleOverride(msg.id)}>Show</button>}\n      </td>\n      <td className=\"message-summary\">\n        <pre>{JSON.stringify(msg, null, 2)}</pre>\n      </td>\n    </tr>);\n  }\n\n  renderMessages() {\n    if (!this.state.messages) {\n      return null;\n    }\n    return (<table><tbody>\n      {this.state.messages.map(msg => this.renderMessageItem(msg))}\n    </tbody></table>);\n  }\n\n  renderProviders() {\n    return (<table><tbody>\n      {this.state.providers.map((provider, i) => (<tr className=\"message-item\" key={i}>\n        <td>{provider.id}</td>\n        <td>{provider.type === \"remote\" ? <a target=\"_blank\" href={provider.url}>{provider.url}</a> : \"(local)\"}</td>\n      </tr>))}\n    </tbody></table>);\n  }\n\n  render() {\n    return (<div className=\"asrouter-admin outer-wrapper\">\n      <h1>AS Router Admin</h1>\n      <button className=\"button primary\" onClick={ASRouterUtils.getNextMessage}>Refresh Current Message</button>\n      <h2>Message Providers</h2>\n      {this.state.providers ? this.renderProviders() : null}\n      <h2>Messages</h2>\n      {this.renderMessages()}\n    </div>);\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/ASRouterAdmin/ASRouterAdmin.jsx","import {actionCreators as ac, actionTypes} from \"common/Actions.jsm\";\nimport {connect} from \"react-redux\";\nimport {FormattedMessage} from \"react-intl\";\nimport React from \"react\";\n\n/**\n * ConfirmDialog component.\n * One primary action button, one cancel button.\n *\n * Content displayed is controlled by `data` prop the component receives.\n * Example:\n * data: {\n *   // Any sort of data needed to be passed around by actions.\n *   payload: site.url,\n *   // Primary button AlsoToMain action.\n *   action: \"DELETE_HISTORY_URL\",\n *   // Primary button USerEvent action.\n *   userEvent: \"DELETE\",\n *   // Array of locale ids to display.\n *   message_body: [\"confirm_history_delete_p1\", \"confirm_history_delete_notice_p2\"],\n *   // Text for primary button.\n *   confirm_button_string_id: \"menu_action_delete\"\n * },\n */\nexport class _ConfirmDialog extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this._handleCancelBtn = this._handleCancelBtn.bind(this);\n    this._handleConfirmBtn = this._handleConfirmBtn.bind(this);\n  }\n\n  _handleCancelBtn() {\n    this.props.dispatch({type: actionTypes.DIALOG_CANCEL});\n    this.props.dispatch(ac.UserEvent({event: actionTypes.DIALOG_CANCEL, source: this.props.data.eventSource}));\n  }\n\n  _handleConfirmBtn() {\n    this.props.data.onConfirm.forEach(this.props.dispatch);\n  }\n\n  _renderModalMessage() {\n    const message_body = this.props.data.body_string_id;\n\n    if (!message_body) {\n      return null;\n    }\n\n    return (<span>\n      {message_body.map(msg => <p key={msg}><FormattedMessage id={msg} /></p>)}\n    </span>);\n  }\n\n  render() {\n    if (!this.props.visible) {\n      return null;\n    }\n\n    return (<div className=\"confirmation-dialog\">\n      <div className=\"modal-overlay\" onClick={this._handleCancelBtn} />\n      <div className=\"modal\">\n        <section className=\"modal-message\">\n          {this.props.data.icon && <span className={`icon icon-spacer icon-${this.props.data.icon}`} />}\n          {this._renderModalMessage()}\n        </section>\n        <section className=\"actions\">\n          <button onClick={this._handleCancelBtn}>\n            <FormattedMessage id={this.props.data.cancel_button_string_id} />\n          </button>\n          <button className=\"done\" onClick={this._handleConfirmBtn}>\n            <FormattedMessage id={this.props.data.confirm_button_string_id} />\n          </button>\n        </section>\n      </div>\n    </div>);\n  }\n}\n\nexport const ConfirmDialog = connect(state => state.Dialog)(_ConfirmDialog);\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/ConfirmDialog/ConfirmDialog.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {connect} from \"react-redux\";\nimport {FormattedMessage} from \"react-intl\";\nimport React from \"react\";\n\n/**\n * Manual migration component used to start the profile import wizard.\n * Message is presented temporarily and will go away if:\n * 1.  User clicks \"No Thanks\"\n * 2.  User completed the data import\n * 3.  After 3 active days\n * 4.  User clicks \"Cancel\" on the import wizard (currently not implemented).\n */\nexport class _ManualMigration extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onLaunchTour = this.onLaunchTour.bind(this);\n    this.onCancelTour = this.onCancelTour.bind(this);\n  }\n\n  onLaunchTour() {\n    this.props.dispatch(ac.AlsoToMain({type: at.MIGRATION_START}));\n    this.props.dispatch(ac.UserEvent({event: at.MIGRATION_START}));\n  }\n\n  onCancelTour() {\n    this.props.dispatch(ac.AlsoToMain({type: at.MIGRATION_CANCEL}));\n    this.props.dispatch(ac.UserEvent({event: at.MIGRATION_CANCEL}));\n  }\n\n  render() {\n    return (<div className=\"manual-migration-container\">\n        <p>\n          <span className=\"icon icon-import\" />\n          <FormattedMessage id=\"manual_migration_explanation2\" />\n        </p>\n        <div className=\"manual-migration-actions actions\">\n          <button className=\"dismiss\" onClick={this.onCancelTour}>\n            <FormattedMessage id=\"manual_migration_cancel_button\" />\n          </button>\n          <button onClick={this.onLaunchTour}>\n            <FormattedMessage id=\"manual_migration_import_button\" />\n          </button>\n        </div>\n    </div>);\n  }\n}\n\nexport const ManualMigration = connect()(_ManualMigration);\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/ManualMigration/ManualMigration.jsx","class _PrerenderData {\n  constructor(options) {\n    this.initialPrefs = options.initialPrefs;\n    this.initialSections = options.initialSections;\n    this._setValidation(options.validation);\n  }\n\n  get validation() {\n    return this._validation;\n  }\n\n  set validation(value) {\n    this._setValidation(value);\n  }\n\n  get invalidatingPrefs() {\n    return this._invalidatingPrefs;\n  }\n\n    // This is needed so we can use it in the constructor\n  _setValidation(value = []) {\n    this._validation = value;\n    this._invalidatingPrefs = value.reduce((result, next) => {\n      if (typeof next === \"string\") {\n        result.push(next);\n        return result;\n      } else if (next && next.oneOf) {\n        return result.concat(next.oneOf);\n      } else if (next && next.indexedDB) {\n        return result.concat(next.indexedDB);\n      }\n      throw new Error(\"Your validation configuration is not properly configured\");\n    }, []);\n  }\n\n  arePrefsValid(getPref, indexedDBPrefs) {\n    for (const prefs of this.validation) {\n      // {oneOf: [\"foo\", \"bar\"]}\n      if (prefs && prefs.oneOf && !prefs.oneOf.some(name => getPref(name) === this.initialPrefs[name])) {\n        return false;\n\n        // {indexedDB: [\"foo\", \"bar\"]}\n      } else if (indexedDBPrefs && prefs && prefs.indexedDB) {\n        const anyModifiedPrefs = prefs.indexedDB.some(prefName => indexedDBPrefs.some(pref => pref && pref[prefName]));\n        if (anyModifiedPrefs) {\n          return false;\n        }\n        // \"foo\"\n      } else if (getPref(prefs) !== this.initialPrefs[prefs]) {\n        return false;\n      }\n    }\n    return true;\n  }\n}\n\nthis.PrerenderData = new _PrerenderData({\n  initialPrefs: {\n    \"migrationExpired\": true,\n    \"feeds.topsites\": true,\n    \"showSearch\": true,\n    \"topSitesRows\": 1,\n    \"feeds.section.topstories\": true,\n    \"feeds.section.highlights\": true,\n    \"sectionOrder\": \"topsites,topstories,highlights\",\n    \"collapsed\": false\n  },\n  // Prefs listed as invalidating will prevent the prerendered version\n  // of AS from being used if their value is something other than what is listed\n  // here. This is required because some preferences cause the page layout to be\n  // too different for the prerendered version to be used. Unfortunately, this\n  // will result in users who have modified some of their preferences not being\n  // able to get the benefits of prerendering.\n  validation: [\n    \"feeds.topsites\",\n    \"showSearch\",\n    \"topSitesRows\",\n    \"sectionOrder\",\n    // This means if either of these are set to their default values,\n    // prerendering can be used.\n    {oneOf: [\"feeds.section.topstories\", \"feeds.section.highlights\"]},\n    // If any component has the following preference set to `true` it will\n    // invalidate the prerendered version.\n    {indexedDB: [\"collapsed\"]}\n  ],\n  initialSections: [\n    {\n      enabled: true,\n      icon: \"pocket\",\n      id: \"topstories\",\n      order: 1,\n      title: {id: \"header_recommended_by\", values: {provider: \"Pocket\"}}\n    },\n    {\n      enabled: true,\n      id: \"highlights\",\n      icon: \"highlights\",\n      order: 2,\n      title: {id: \"header_highlights\"}\n    }\n  ]\n});\n\nthis._PrerenderData = _PrerenderData;\nconst EXPORTED_SYMBOLS = [\"PrerenderData\", \"_PrerenderData\"];\n\n\n\n// WEBPACK FOOTER //\n// ./common/PrerenderData.jsm","/* globals ContentSearchUIController */\n\"use strict\";\n\nimport {FormattedMessage, injectIntl} from \"react-intl\";\nimport {actionCreators as ac} from \"common/Actions.jsm\";\nimport {connect} from \"react-redux\";\nimport {IS_NEWTAB} from \"content-src/lib/constants\";\nimport React from \"react\";\n\nexport class _Search extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onClick = this.onClick.bind(this);\n    this.onInputMount = this.onInputMount.bind(this);\n  }\n\n  handleEvent(event) {\n    // Also track search events with our own telemetry\n    if (event.detail.type === \"Search\") {\n      this.props.dispatch(ac.UserEvent({event: \"SEARCH\"}));\n    }\n  }\n\n  onClick(event) {\n    window.gContentSearchController.search(event);\n  }\n\n  componentWillUnmount() {\n    delete window.gContentSearchController;\n  }\n\n  onInputMount(input) {\n    if (input) {\n      // The \"healthReportKey\" and needs to be \"newtab\" or \"abouthome\" so that\n      // BrowserUsageTelemetry.jsm knows to handle events with this name, and\n      // can add the appropriate telemetry probes for search. Without the correct\n      // name, certain tests like browser_UsageTelemetry_content.js will fail\n      // (See github ticket #2348 for more details)\n      const healthReportKey = IS_NEWTAB ? \"newtab\" : \"abouthome\";\n\n      // The \"searchSource\" needs to be \"newtab\" or \"homepage\" and is sent with\n      // the search data and acts as context for the search request (See\n      // nsISearchEngine.getSubmission). It is necessary so that search engine\n      // plugins can correctly atribute referrals. (See github ticket #3321 for\n      // more details)\n      const searchSource = IS_NEWTAB ? \"newtab\" : \"homepage\";\n\n      // gContentSearchController needs to exist as a global so that tests for\n      // the existing about:home can find it; and so it allows these tests to pass.\n      // In the future, when activity stream is default about:home, this can be renamed\n      window.gContentSearchController = new ContentSearchUIController(input, input.parentNode,\n        healthReportKey, searchSource);\n      addEventListener(\"ContentSearchClient\", this);\n    } else {\n      window.gContentSearchController = null;\n      removeEventListener(\"ContentSearchClient\", this);\n    }\n  }\n\n  /*\n   * Do not change the ID on the input field, as legacy newtab code\n   * specifically looks for the id 'newtab-search-text' on input fields\n   * in order to execute searches in various tests\n   */\n  render() {\n    return (<div className=\"search-wrapper\">\n      <label htmlFor=\"newtab-search-text\" className=\"search-label\">\n        <span className=\"sr-only\"><FormattedMessage id=\"search_web_placeholder\" /></span>\n      </label>\n      <input\n        id=\"newtab-search-text\"\n        maxLength=\"256\"\n        placeholder={this.props.intl.formatMessage({id: \"search_web_placeholder\"})}\n        ref={this.onInputMount}\n        title={this.props.intl.formatMessage({id: \"search_web_placeholder\"})}\n        type=\"search\" />\n      <button\n        id=\"searchSubmit\"\n        className=\"search-button\"\n        onClick={this.onClick}\n        title={this.props.intl.formatMessage({id: \"search_button\"})}>\n        <span className=\"sr-only\"><FormattedMessage id=\"search_button\" /></span>\n      </button>\n    </div>);\n  }\n}\n\nexport const Search = connect()(injectIntl(_Search));\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/Search/Search.jsx","export const IS_NEWTAB = global.document && global.document.documentURI === \"about:newtab\";\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/lib/constants.js","import {Card, PlaceholderCard} from \"content-src/components/Card/Card\";\nimport {FormattedMessage, injectIntl} from \"react-intl\";\nimport {actionCreators as ac} from \"common/Actions.jsm\";\nimport {CollapsibleSection} from \"content-src/components/CollapsibleSection/CollapsibleSection\";\nimport {ComponentPerfTimer} from \"content-src/components/ComponentPerfTimer/ComponentPerfTimer\";\nimport {connect} from \"react-redux\";\nimport React from \"react\";\nimport {Topics} from \"content-src/components/Topics/Topics\";\nimport {TopSites} from \"content-src/components/TopSites/TopSites\";\n\nconst VISIBLE = \"visible\";\nconst VISIBILITY_CHANGE_EVENT = \"visibilitychange\";\nconst CARDS_PER_ROW_DEFAULT = 3;\nconst CARDS_PER_ROW_COMPACT_WIDE = 4;\n\nfunction getFormattedMessage(message) {\n  return typeof message === \"string\" ? <span>{message}</span> : <FormattedMessage {...message} />;\n}\n\nexport class Section extends React.PureComponent {\n  get numRows() {\n    const {rowsPref, maxRows, Prefs} = this.props;\n    return rowsPref ? Prefs.values[rowsPref] : maxRows;\n  }\n\n  _dispatchImpressionStats() {\n    const {props} = this;\n    let cardsPerRow = CARDS_PER_ROW_DEFAULT;\n    if (props.compactCards && global.matchMedia(`(min-width: 1072px)`).matches) {\n      // If the section has compact cards and the viewport is wide enough, we show\n      // 4 columns instead of 3.\n      // $break-point-widest = 1072px (from _variables.scss)\n      cardsPerRow = CARDS_PER_ROW_COMPACT_WIDE;\n    }\n    const maxCards = cardsPerRow * this.numRows;\n    const cards = props.rows.slice(0, maxCards);\n\n    if (this.needsImpressionStats(cards)) {\n      props.dispatch(ac.ImpressionStats({\n        source: props.eventSource,\n        tiles: cards.map(link => ({id: link.guid}))\n      }));\n      this.impressionCardGuids = cards.map(link => link.guid);\n    }\n  }\n\n  // This sends an event when a user sees a set of new content. If content\n  // changes while the page is hidden (i.e. preloaded or on a hidden tab),\n  // only send the event if the page becomes visible again.\n  sendImpressionStatsOrAddListener() {\n    const {props} = this;\n\n    if (!props.shouldSendImpressionStats || !props.dispatch) {\n      return;\n    }\n\n    if (props.document.visibilityState === VISIBLE) {\n      this._dispatchImpressionStats();\n    } else {\n      // We should only ever send the latest impression stats ping, so remove any\n      // older listeners.\n      if (this._onVisibilityChange) {\n        props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n      }\n\n      // When the page becomes visible, send the impression stats ping if the section isn't collapsed.\n      this._onVisibilityChange = () => {\n        if (props.document.visibilityState === VISIBLE) {\n          if (!this.props.pref.collapsed) {\n            this._dispatchImpressionStats();\n          }\n          props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n        }\n      };\n      props.document.addEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n    }\n  }\n\n  componentDidMount() {\n    if (this.props.rows.length && !this.props.pref.collapsed) {\n      this.sendImpressionStatsOrAddListener();\n    }\n  }\n\n  componentDidUpdate(prevProps) {\n    const {props} = this;\n    const isCollapsed = props.pref.collapsed;\n    const wasCollapsed = prevProps.pref.collapsed;\n    if (\n      // Don't send impression stats for the empty state\n      props.rows.length &&\n      (\n        // We only want to send impression stats if the content of the cards has changed\n        // and the section is not collapsed...\n        (props.rows !== prevProps.rows && !isCollapsed) ||\n        // or if we are expanding a section that was collapsed.\n        (wasCollapsed && !isCollapsed)\n      )\n    ) {\n      this.sendImpressionStatsOrAddListener();\n    }\n  }\n\n  componentWillUnmount() {\n    if (this._onVisibilityChange) {\n      this.props.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n    }\n  }\n\n  needsImpressionStats(cards) {\n    if (!this.impressionCardGuids || (this.impressionCardGuids.length !== cards.length)) {\n      return true;\n    }\n\n    for (let i = 0; i < cards.length; i++) {\n      if (cards[i].guid !== this.impressionCardGuids[i]) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  render() {\n    const {\n      id, eventSource, title, icon, rows,\n      emptyState, dispatch, compactCards,\n      contextMenuOptions, initialized, disclaimer,\n      pref, privacyNoticeURL, isFirst, isLast\n    } = this.props;\n\n    const maxCardsPerRow = compactCards ? CARDS_PER_ROW_COMPACT_WIDE : CARDS_PER_ROW_DEFAULT;\n    const {numRows} = this;\n    const maxCards = maxCardsPerRow * numRows;\n    const maxCardsOnNarrow = CARDS_PER_ROW_DEFAULT * numRows;\n\n    // Show topics only for top stories and if it's not initialized yet (so\n    // content doesn't shift when it is loaded) or has loaded with topics\n    const shouldShowTopics = (id === \"topstories\" &&\n      (!this.props.topics || this.props.topics.length > 0));\n\n    const realRows = rows.slice(0, maxCards);\n\n    // The empty state should only be shown after we have initialized and there is no content.\n    // Otherwise, we should show placeholders.\n    const shouldShowEmptyState = initialized && !rows.length;\n\n    const cards = [];\n    if (!shouldShowEmptyState) {\n      for (let i = 0; i < maxCards; i++) {\n        const link = realRows[i];\n        // On narrow viewports, we only show 3 cards per row. We'll mark the rest as\n        // .hide-for-narrow to hide in CSS via @media query.\n        const className = (i >= maxCardsOnNarrow) ? \"hide-for-narrow\" : \"\";\n        cards.push(link ? (\n          <Card key={i}\n            index={i}\n            className={className}\n            dispatch={dispatch}\n            link={link}\n            contextMenuOptions={contextMenuOptions}\n            eventSource={eventSource}\n            shouldSendImpressionStats={this.props.shouldSendImpressionStats}\n            isWebExtension={this.props.isWebExtension} />\n        ) : (\n          <PlaceholderCard key={i} className={className} />\n        ));\n      }\n    }\n\n    const sectionClassName = [\n      \"section\",\n      compactCards ? \"compact-cards\" : \"normal-cards\"\n    ].join(\" \");\n\n    // <Section> <-- React component\n    // <section> <-- HTML5 element\n    return (<ComponentPerfTimer {...this.props}>\n      <CollapsibleSection className={sectionClassName} icon={icon}\n        title={title}\n        id={id}\n        eventSource={eventSource}\n        disclaimer={disclaimer}\n        collapsed={this.props.pref.collapsed}\n        showPrefName={(pref && pref.feed) || id}\n        privacyNoticeURL={privacyNoticeURL}\n        Prefs={this.props.Prefs}\n        isFirst={isFirst}\n        isLast={isLast}\n        dispatch={this.props.dispatch}\n        isWebExtension={this.props.isWebExtension}>\n\n        {!shouldShowEmptyState && (<ul className=\"section-list\" style={{padding: 0}}>\n          {cards}\n        </ul>)}\n        {shouldShowEmptyState &&\n          <div className=\"section-empty-state\">\n            <div className=\"empty-state\">\n              {emptyState.icon && emptyState.icon.startsWith(\"moz-extension://\") ?\n                <img className=\"empty-state-icon icon\" style={{\"background-image\": `url('${emptyState.icon}')`}} /> :\n                <img className={`empty-state-icon icon icon-${emptyState.icon}`} />}\n              <p className=\"empty-state-message\">\n                {getFormattedMessage(emptyState.message)}\n              </p>\n            </div>\n          </div>}\n        {shouldShowTopics && <Topics topics={this.props.topics} read_more_endpoint={this.props.read_more_endpoint} />}\n      </CollapsibleSection>\n    </ComponentPerfTimer>);\n  }\n}\n\nSection.defaultProps = {\n  document: global.document,\n  rows: [],\n  emptyState: {},\n  pref: {},\n  title: \"\"\n};\n\nexport const SectionIntl = connect(state => ({Prefs: state.Prefs}))(injectIntl(Section));\n\nexport class _Sections extends React.PureComponent {\n  renderSections() {\n    const sections = [];\n    const enabledSections = this.props.Sections.filter(section => section.enabled);\n    const {sectionOrder, \"feeds.topsites\": showTopSites} = this.props.Prefs.values;\n    // Enabled sections doesn't include Top Sites, so we add it if enabled.\n    const expectedCount = enabledSections.length + ~~showTopSites;\n\n    for (const sectionId of sectionOrder.split(\",\")) {\n      const commonProps = {\n        key: sectionId,\n        isFirst: sections.length === 0,\n        isLast: sections.length === expectedCount - 1\n      };\n      if (sectionId === \"topsites\" && showTopSites) {\n        sections.push(<TopSites {...commonProps} />);\n      } else {\n        const section = enabledSections.find(s => s.id === sectionId);\n        if (section) {\n          sections.push(<SectionIntl {...section} {...commonProps} />);\n        }\n      }\n    }\n    return sections;\n  }\n\n  render() {\n    return (\n      <div className=\"sections-list\">\n        {this.renderSections()}\n      </div>\n    );\n  }\n}\n\nexport const Sections = connect(state => ({Sections: state.Sections, Prefs: state.Prefs}))(_Sections);\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/Sections/Sections.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {cardContextTypes} from \"./types\";\nimport {connect} from \"react-redux\";\nimport {FormattedMessage} from \"react-intl\";\nimport {GetPlatformString} from \"content-src/lib/link-menu-options\";\nimport {LinkMenu} from \"content-src/components/LinkMenu/LinkMenu\";\nimport React from \"react\";\n\n// Keep track of pending image loads to only request once\nconst gImageLoading = new Map();\n\n/**\n * Card component.\n * Cards are found within a Section component and contain information about a link such\n * as preview image, page title, page description, and some context about if the page\n * was visited, bookmarked, trending etc...\n * Each Section can make an unordered list of Cards which will create one instane of\n * this class. Each card will then get a context menu which reflects the actions that\n * can be done on this Card.\n */\nexport class _Card extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.state = {\n      activeCard: null,\n      imageLoaded: false,\n      showContextMenu: false,\n      cardImage: null\n    };\n    this.onMenuButtonClick = this.onMenuButtonClick.bind(this);\n    this.onMenuUpdate = this.onMenuUpdate.bind(this);\n    this.onLinkClick = this.onLinkClick.bind(this);\n  }\n\n  /**\n   * Helper to conditionally load an image and update state when it loads.\n   */\n  async maybeLoadImage() {\n    // No need to load if it's already loaded or no image\n    const {cardImage} = this.state;\n    if (!cardImage) {\n      return;\n    }\n\n    const imageUrl = cardImage.url;\n    if (!this.state.imageLoaded) {\n      // Initialize a promise to share a load across multiple card updates\n      if (!gImageLoading.has(imageUrl)) {\n        const loaderPromise = new Promise((resolve, reject) => {\n          const loader = new Image();\n          loader.addEventListener(\"load\", resolve);\n          loader.addEventListener(\"error\", reject);\n          loader.src = imageUrl;\n        });\n\n        // Save and remove the promise only while it's pending\n        gImageLoading.set(imageUrl, loaderPromise);\n        loaderPromise.catch(ex => ex).then(() => gImageLoading.delete(imageUrl)).catch();\n      }\n\n      // Wait for the image whether just started loading or reused promise\n      await gImageLoading.get(imageUrl);\n\n      // Only update state if we're still waiting to load the original image\n      if (_Card.isImageInState(this.state, this.props.link.image) && !this.state.imageLoaded) {\n        this.setState({imageLoaded: true});\n      }\n    }\n  }\n\n  /**\n   * Checks if `.image` property on link object is a local image with blob data.\n   * This function only works for props since state has `.url` and not `.data`.\n   *\n   * @param {obj|string} image\n   * @returns {bool} true if image is a local image object, otherwise false\n   *                 (otherwise, image will be a URL as a string)\n   */\n  static isLocalImageObject(image) {\n    return image && image.data && image.path;\n  }\n\n  /**\n   * Helper to obtain the next state based on nextProps and prevState.\n   *\n   * NOTE: Rename this method to getDerivedStateFromProps when we update React\n   *       to >= 16.3. We will need to update tests as well. We cannot rename this\n   *       method to getDerivedStateFromProps now because there is a mismatch in\n   *       the React version that we are using for both testing and production.\n   *       (i.e. react-test-render => \"16.3.2\", react => \"16.2.0\").\n   *\n   * See https://github.com/airbnb/enzyme/blob/master/packages/enzyme-adapter-react-16/package.json#L43.\n   */\n  static getNextStateFromProps(nextProps, prevState) {\n    const {image} = nextProps.link;\n    const imageInState = _Card.isImageInState(prevState, image);\n    let nextState = null;\n\n    // Image is updating.\n    if (!imageInState && nextProps.link) {\n      nextState = {imageLoaded: false};\n    }\n\n    if (imageInState) {\n      return nextState;\n    }\n\n    nextState = nextState || {};\n\n    // Since image was updated, attempt to revoke old image blob URL, if it exists.\n    _Card.maybeRevokeImageBlob(prevState);\n\n    if (!image) {\n      nextState.cardImage = null;\n    } else if (_Card.isLocalImageObject(image)) {\n      nextState.cardImage = {url: global.URL.createObjectURL(image.data), path: image.path};\n    } else {\n      nextState.cardImage = {url: image};\n    }\n\n    return nextState;\n  }\n\n  /**\n   * Helper to conditionally revoke the previous card image if it is a blob.\n   */\n  static maybeRevokeImageBlob(prevState) {\n    if (prevState.cardImage && prevState.cardImage.path) {\n      global.URL.revokeObjectURL(prevState.cardImage.url);\n    }\n  }\n\n  /**\n   * Helper to check if an image is already in state.\n   */\n  static isImageInState(state, image) {\n    const {cardImage} = state;\n\n    // Both image and cardImage are present.\n    if (image && cardImage) {\n      return _Card.isLocalImageObject(image) ?\n             cardImage.path === image.path :\n             cardImage.url === image;\n    }\n\n    // This will only handle the remaining three possible outcomes.\n    // (i.e. everything except when both image and cardImage are present)\n    return !image && !cardImage;\n  }\n\n  onMenuButtonClick(event) {\n    event.preventDefault();\n    this.setState({\n      activeCard: this.props.index,\n      showContextMenu: true\n    });\n  }\n\n  /**\n   * Report to telemetry additional information about the item.\n   */\n  _getTelemetryInfo() {\n    // Filter out \"history\" type for being the default\n    if (this.props.link.type !== \"history\") {\n      return {value: {card_type: this.props.link.type}};\n    }\n\n    return null;\n  }\n\n  onLinkClick(event) {\n    event.preventDefault();\n    if (this.props.link.type === \"download\") {\n      this.props.dispatch(ac.OnlyToMain({\n        type: at.SHOW_DOWNLOAD_FILE,\n        data: this.props.link\n      }));\n    } else {\n      const {altKey, button, ctrlKey, metaKey, shiftKey} = event;\n      this.props.dispatch(ac.OnlyToMain({\n        type: at.OPEN_LINK,\n        data: Object.assign(this.props.link, {event: {altKey, button, ctrlKey, metaKey, shiftKey}})\n      }));\n    }\n    if (this.props.isWebExtension) {\n      this.props.dispatch(ac.WebExtEvent(at.WEBEXT_CLICK, {\n        source: this.props.eventSource,\n        url: this.props.link.url,\n        action_position: this.props.index\n      }));\n    } else {\n      this.props.dispatch(ac.UserEvent(Object.assign({\n        event: \"CLICK\",\n        source: this.props.eventSource,\n        action_position: this.props.index\n      }, this._getTelemetryInfo())));\n\n      if (this.props.shouldSendImpressionStats) {\n        this.props.dispatch(ac.ImpressionStats({\n          source: this.props.eventSource,\n          click: 0,\n          tiles: [{id: this.props.link.guid, pos: this.props.index}]\n        }));\n      }\n    }\n  }\n\n  onMenuUpdate(showContextMenu) {\n    this.setState({showContextMenu});\n  }\n\n  componentDidMount() {\n    this.maybeLoadImage();\n  }\n\n  componentDidUpdate() {\n    this.maybeLoadImage();\n  }\n\n  // NOTE: Remove this function when we update React to >= 16.3 since React will\n  //       call getDerivedStateFromProps automatically. We will also need to\n  //       rename getNextStateFromProps to getDerivedStateFromProps.\n  componentWillMount() {\n    const nextState = _Card.getNextStateFromProps(this.props, this.state);\n    if (nextState) {\n      this.setState(nextState);\n    }\n  }\n\n  // NOTE: Remove this function when we update React to >= 16.3 since React will\n  //       call getDerivedStateFromProps automatically. We will also need to\n  //       rename getNextStateFromProps to getDerivedStateFromProps.\n  componentWillReceiveProps(nextProps) {\n    const nextState = _Card.getNextStateFromProps(nextProps, this.state);\n    if (nextState) {\n      this.setState(nextState);\n    }\n  }\n\n  componentWillUnmount() {\n    _Card.maybeRevokeImageBlob(this.state);\n  }\n\n  render() {\n    const {index, className, link, dispatch, contextMenuOptions, eventSource, shouldSendImpressionStats} = this.props;\n    const {props} = this;\n    const isContextMenuOpen = this.state.showContextMenu && this.state.activeCard === index;\n    // Display \"now\" as \"trending\" until we have new strings #3402\n    const {icon, intlID} = cardContextTypes[link.type === \"now\" ? \"trending\" : link.type] || {};\n    const hasImage = this.state.cardImage || link.hasImage;\n    const imageStyle = {backgroundImage: this.state.cardImage ? `url(${this.state.cardImage.url})` : \"none\"};\n    const outerClassName = [\n      \"card-outer\",\n      className,\n      isContextMenuOpen && \"active\",\n      props.placeholder && \"placeholder\"\n    ].filter(v => v).join(\" \");\n\n    return (<li className={outerClassName}>\n      <a href={link.type === \"pocket\" ? link.open_url : link.url} onClick={!props.placeholder ? this.onLinkClick : undefined}>\n        <div className=\"card\">\n          <div className=\"card-preview-image-outer\">\n            {hasImage &&\n              <div className={`card-preview-image${this.state.imageLoaded ? \" loaded\" : \"\"}`} style={imageStyle} />\n            }\n          </div>\n          <div className=\"card-details\">\n            {link.type === \"download\" && <div className=\"card-host-name alternate\"><FormattedMessage id={GetPlatformString(this.props.platform)} /></div>}\n            {link.hostname &&\n              <div className=\"card-host-name\">\n                {link.hostname.slice(0, 100)}{link.type === \"download\" && `  \\u2014 ${link.description}`}\n              </div>\n            }\n            <div className={[\n              \"card-text\",\n              icon ? \"\" : \"no-context\",\n              link.description ? \"\" : \"no-description\",\n              link.hostname ? \"\" : \"no-host-name\"\n            ].join(\" \")}>\n              <h4 className=\"card-title\" dir=\"auto\">{link.title}</h4>\n              <p className=\"card-description\" dir=\"auto\">{link.description}</p>\n            </div>\n            <div className=\"card-context\">\n              {icon && !link.context && <span className={`card-context-icon icon icon-${icon}`} />}\n              {link.icon && link.context && <span className=\"card-context-icon icon\" style={{backgroundImage: `url('${link.icon}')`}} />}\n              {intlID && !link.context && <div className=\"card-context-label\"><FormattedMessage id={intlID} defaultMessage=\"Visited\" /></div>}\n              {link.context && <div className=\"card-context-label\">{link.context}</div>}\n            </div>\n          </div>\n        </div>\n      </a>\n      {!props.placeholder && <button className=\"context-menu-button icon\"\n        onClick={this.onMenuButtonClick}>\n        <span className=\"sr-only\">{`Open context menu for ${link.title}`}</span>\n      </button>}\n      {isContextMenuOpen &&\n        <LinkMenu\n          dispatch={dispatch}\n          index={index}\n          source={eventSource}\n          onUpdate={this.onMenuUpdate}\n          options={link.contextMenuOptions || contextMenuOptions}\n          site={link}\n          siteInfo={this._getTelemetryInfo()}\n          shouldSendImpressionStats={shouldSendImpressionStats} />\n      }\n   </li>);\n  }\n}\n_Card.defaultProps = {link: {}};\nexport const Card = connect(state => ({platform: state.Prefs.values.platform}))(_Card);\nexport const PlaceholderCard = props => <Card placeholder={true} className={props.className} />;\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/Card/Card.jsx","export const cardContextTypes = {\n  history: {\n    intlID: \"type_label_visited\",\n    icon: \"history-item\"\n  },\n  bookmark: {\n    intlID: \"type_label_bookmarked\",\n    icon: \"bookmark-added\"\n  },\n  trending: {\n    intlID: \"type_label_recommended\",\n    icon: \"trending\"\n  },\n  now: {\n    intlID: \"type_label_now\",\n    icon: \"now\"\n  },\n  pocket: {\n    intlID: \"type_label_pocket\",\n    icon: \"pocket\"\n  },\n  download: {\n    intlID: \"type_label_downloaded\",\n    icon: \"download\"\n  }\n};\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/Card/types.js","import {actionCreators as ac} from \"common/Actions.jsm\";\nimport {ContextMenu} from \"content-src/components/ContextMenu/ContextMenu\";\nimport {injectIntl} from \"react-intl\";\nimport React from \"react\";\nimport {SectionMenuOptions} from \"content-src/lib/section-menu-options\";\n\nconst DEFAULT_SECTION_MENU_OPTIONS = [\"MoveUp\", \"MoveDown\", \"Separator\", \"RemoveSection\", \"CheckCollapsed\", \"Separator\", \"ManageSection\"];\nconst WEBEXT_SECTION_MENU_OPTIONS = [\"MoveUp\", \"MoveDown\", \"Separator\", \"CheckCollapsed\", \"Separator\", \"ManageWebExtension\"];\n\nexport class _SectionMenu extends React.PureComponent {\n  getOptions() {\n    const {props} = this;\n\n    const propOptions = props.isWebExtension ? [...WEBEXT_SECTION_MENU_OPTIONS] : [...DEFAULT_SECTION_MENU_OPTIONS];\n    // Prepend custom options and a separator\n    if (props.extraOptions) {\n      propOptions.splice(0, 0, ...props.extraOptions, \"Separator\");\n    }\n    // Insert privacy notice before the last option (\"ManageSection\")\n    if (props.privacyNoticeURL) {\n      propOptions.splice(-1, 0, \"PrivacyNotice\");\n    }\n\n    const options = propOptions.map(o => SectionMenuOptions[o](props)).map(option => {\n      const {action, id, type, userEvent} = option;\n      if (!type && id) {\n        option.label = props.intl.formatMessage({id});\n        option.onClick = () => {\n          props.dispatch(action);\n          if (userEvent) {\n            props.dispatch(ac.UserEvent({\n              event: userEvent,\n              source: props.source\n            }));\n          }\n        };\n      }\n      return option;\n    });\n\n    // This is for accessibility to support making each item tabbable.\n    // We want to know which item is the first and which item\n    // is the last, so we can close the context menu accordingly.\n    options[0].first = true;\n    options[options.length - 1].last = true;\n    return options;\n  }\n\n  render() {\n    return (<ContextMenu\n      onUpdate={this.props.onUpdate}\n      options={this.getOptions()} />);\n  }\n}\n\nexport const SectionMenu = injectIntl(_SectionMenu);\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/SectionMenu/SectionMenu.jsx","import {FormattedMessage} from \"react-intl\";\nimport React from \"react\";\n\nexport class Topic extends React.PureComponent {\n  render() {\n    const {url, name} = this.props;\n    return (<li><a key={name} className=\"topic-link\" href={url}>{name}</a></li>);\n  }\n}\n\nexport class Topics extends React.PureComponent {\n  render() {\n    const {topics, read_more_endpoint} = this.props;\n    return (\n      <div className=\"topic\">\n        <span><FormattedMessage id=\"pocket_read_more\" /></span>\n        <ul>{topics && topics.map(t => <Topic key={t.name} url={t.url} name={t.name} />)}</ul>\n\n        {read_more_endpoint && <a className=\"topic-read-more\" href={read_more_endpoint}>\n          <FormattedMessage id=\"pocket_read_even_more\" />\n        </a>}\n      </div>\n    );\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/Topics/Topics.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {MIN_CORNER_FAVICON_SIZE, MIN_RICH_FAVICON_SIZE, TOP_SITES_SOURCE} from \"./TopSitesConstants\";\nimport {CollapsibleSection} from \"content-src/components/CollapsibleSection/CollapsibleSection\";\nimport {ComponentPerfTimer} from \"content-src/components/ComponentPerfTimer/ComponentPerfTimer\";\nimport {connect} from \"react-redux\";\nimport {injectIntl} from \"react-intl\";\nimport React from \"react\";\nimport {TOP_SITES_MAX_SITES_PER_ROW} from \"common/Reducers.jsm\";\nimport {TopSiteForm} from \"./TopSiteForm\";\nimport {TopSiteList} from \"./TopSite\";\n\nfunction topSiteIconType(link) {\n  if (link.customScreenshotURL) {\n    return \"custom_screenshot\";\n  }\n  if (link.tippyTopIcon || link.faviconRef === \"tippytop\") {\n    return \"tippytop\";\n  }\n  if (link.faviconSize >= MIN_RICH_FAVICON_SIZE) {\n    return \"rich_icon\";\n  }\n  if (link.screenshot && link.faviconSize >= MIN_CORNER_FAVICON_SIZE) {\n    return \"screenshot_with_icon\";\n  }\n  if (link.screenshot) {\n    return \"screenshot\";\n  }\n  return \"no_image\";\n}\n\n/**\n * Iterates through TopSites and counts types of images.\n * @param acc Accumulator for reducer.\n * @param topsite Entry in TopSites.\n */\nfunction countTopSitesIconsTypes(topSites) {\n  const countTopSitesTypes = (acc, link) => {\n    acc[topSiteIconType(link)]++;\n    return acc;\n  };\n\n  return topSites.reduce(countTopSitesTypes, {\n    \"custom_screenshot\": 0,\n    \"screenshot_with_icon\": 0,\n    \"screenshot\": 0,\n    \"tippytop\": 0,\n    \"rich_icon\": 0,\n    \"no_image\": 0\n  });\n}\n\nexport class _TopSites extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onFormClose = this.onFormClose.bind(this);\n  }\n\n  /**\n   * Dispatch session statistics about the quality of TopSites icons and pinned count.\n   */\n  _dispatchTopSitesStats() {\n    const topSites = this._getVisibleTopSites();\n    const topSitesIconsStats = countTopSitesIconsTypes(topSites);\n    const topSitesPinned = topSites.filter(site => !!site.isPinned).length;\n    // Dispatch telemetry event with the count of TopSites images types.\n    this.props.dispatch(ac.AlsoToMain({\n      type: at.SAVE_SESSION_PERF_DATA,\n      data: {topsites_icon_stats: topSitesIconsStats, topsites_pinned: topSitesPinned}\n    }));\n  }\n\n  /**\n   * Return the TopSites that are visible based on prefs and window width.\n   */\n  _getVisibleTopSites() {\n    // We hide 2 sites per row when not in the wide layout.\n    let sitesPerRow = TOP_SITES_MAX_SITES_PER_ROW;\n    // $break-point-widest = 1072px (from _variables.scss)\n    if (!global.matchMedia(`(min-width: 1072px)`).matches) {\n      sitesPerRow -= 2;\n    }\n    return this.props.TopSites.rows.slice(0, this.props.TopSitesRows * sitesPerRow);\n  }\n\n  componentDidUpdate() {\n    this._dispatchTopSitesStats();\n  }\n\n  componentDidMount() {\n    this._dispatchTopSitesStats();\n  }\n\n  onFormClose() {\n    this.props.dispatch(ac.UserEvent({\n      source: TOP_SITES_SOURCE,\n      event: \"TOP_SITES_EDIT_CLOSE\"\n    }));\n    this.props.dispatch({type: at.TOP_SITES_CANCEL_EDIT});\n  }\n\n  render() {\n    const {props} = this;\n    const {editForm} = props.TopSites;\n\n    return (<ComponentPerfTimer id=\"topsites\" initialized={props.TopSites.initialized} dispatch={props.dispatch}>\n      <CollapsibleSection\n        className=\"top-sites\"\n        icon=\"topsites\"\n        id=\"topsites\"\n        title={{id: \"header_top_sites\"}}\n        extraMenuOptions={[\"AddTopSite\"]}\n        showPrefName=\"feeds.topsites\"\n        eventSource={TOP_SITES_SOURCE}\n        collapsed={props.TopSites.pref ? props.TopSites.pref.collapsed : undefined}\n        isFirst={props.isFirst}\n        isLast={props.isLast}\n        dispatch={props.dispatch}>\n        <TopSiteList TopSites={props.TopSites} TopSitesRows={props.TopSitesRows} dispatch={props.dispatch} intl={props.intl} topSiteIconType={topSiteIconType} />\n        <div className=\"edit-topsites-wrapper\">\n          {editForm &&\n            <div className=\"edit-topsites\">\n              <div className=\"modal-overlay\" onClick={this.onFormClose} />\n              <div className=\"modal\">\n                <TopSiteForm\n                  site={props.TopSites.rows[editForm.index]}\n                  onClose={this.onFormClose}\n                  dispatch={this.props.dispatch}\n                  intl={this.props.intl}\n                  {...editForm} />\n              </div>\n            </div>\n          }\n        </div>\n      </CollapsibleSection>\n    </ComponentPerfTimer>);\n  }\n}\n\nexport const TopSites = connect(state => ({\n  TopSites: state.TopSites,\n  Prefs: state.Prefs,\n  TopSitesRows: state.Prefs.values.topSitesRows\n}))(injectIntl(_TopSites));\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/TopSites/TopSites.jsx","import {FormattedMessage} from \"react-intl\";\nimport React from \"react\";\n\nexport class TopSiteFormInput extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.state = {validationError: this.props.validationError};\n    this.onChange = this.onChange.bind(this);\n    this.onMount = this.onMount.bind(this);\n  }\n\n  componentWillReceiveProps(nextProps) {\n    if (nextProps.shouldFocus && !this.props.shouldFocus) {\n      this.input.focus();\n    }\n    if (nextProps.validationError && !this.props.validationError) {\n      this.setState({validationError: true});\n    }\n    // If the component is in an error state but the value was cleared by the parent\n    if (this.state.validationError && !nextProps.value) {\n      this.setState({validationError: false});\n    }\n  }\n\n  onChange(ev) {\n    if (this.state.validationError) {\n      this.setState({validationError: false});\n    }\n    this.props.onChange(ev);\n  }\n\n  onMount(input) {\n    this.input = input;\n  }\n\n  render() {\n    const showClearButton = this.props.value && this.props.onClear;\n    const {typeUrl} = this.props;\n    const {validationError} = this.state;\n\n    return (<label><FormattedMessage id={this.props.titleId} />\n      <div className={`field ${typeUrl ? \"url\" : \"\"}${validationError ? \" invalid\" : \"\"}`}>\n        {this.props.loading ?\n          <div className=\"loading-container\"><div className=\"loading-animation\" /></div> :\n          showClearButton && <div className=\"icon icon-clear-input\" onClick={this.props.onClear} />}\n        <input type=\"text\"\n          value={this.props.value}\n          ref={this.onMount}\n          onChange={this.onChange}\n          placeholder={this.props.intl.formatMessage({id: this.props.placeholderId})}\n          autoFocus={this.props.shouldFocus}\n          disabled={this.props.loading} />\n        {validationError &&\n          <aside className=\"error-tooltip\">\n            <FormattedMessage id={this.props.errorMessageId} />\n          </aside>}\n      </div>\n    </label>);\n  }\n}\n\nTopSiteFormInput.defaultProps = {\n  showClearButton: false,\n  value: \"\",\n  validationError: false\n};\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/TopSites/TopSiteFormInput.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {FormattedMessage} from \"react-intl\";\nimport React from \"react\";\nimport {TOP_SITES_SOURCE} from \"./TopSitesConstants\";\nimport {TopSiteFormInput} from \"./TopSiteFormInput\";\nimport {TopSiteLink} from \"./TopSite\";\n\nexport class TopSiteForm extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    const {site} = props;\n    this.state = {\n      label: site ? (site.label || site.hostname) : \"\",\n      url: site ? site.url : \"\",\n      validationError: false,\n      customScreenshotUrl: site ? site.customScreenshotURL : \"\",\n      showCustomScreenshotForm: site ? site.customScreenshotURL : false\n    };\n    this.onClearScreenshotInput = this.onClearScreenshotInput.bind(this);\n    this.onLabelChange = this.onLabelChange.bind(this);\n    this.onUrlChange = this.onUrlChange.bind(this);\n    this.onCancelButtonClick = this.onCancelButtonClick.bind(this);\n    this.onClearUrlClick = this.onClearUrlClick.bind(this);\n    this.onDoneButtonClick = this.onDoneButtonClick.bind(this);\n    this.onCustomScreenshotUrlChange = this.onCustomScreenshotUrlChange.bind(this);\n    this.onPreviewButtonClick = this.onPreviewButtonClick.bind(this);\n    this.onEnableScreenshotUrlForm = this.onEnableScreenshotUrlForm.bind(this);\n    this.validateUrl = this.validateUrl.bind(this);\n  }\n\n  onLabelChange(event) {\n    this.setState({\"label\": event.target.value});\n  }\n\n  onUrlChange(event) {\n    this.setState({\n      url: event.target.value,\n      validationError: false\n    });\n  }\n\n  onClearUrlClick() {\n    this.setState({\n      url: \"\",\n      validationError: false\n    });\n  }\n\n  onEnableScreenshotUrlForm() {\n    this.setState({showCustomScreenshotForm: true});\n  }\n\n  _updateCustomScreenshotInput(customScreenshotUrl) {\n    this.setState({\n      customScreenshotUrl,\n      validationError: false\n    });\n    this.props.dispatch({type: at.PREVIEW_REQUEST_CANCEL});\n  }\n\n  onCustomScreenshotUrlChange(event) {\n    this._updateCustomScreenshotInput(event.target.value);\n  }\n\n  onClearScreenshotInput() {\n    this._updateCustomScreenshotInput(\"\");\n  }\n\n  onCancelButtonClick(ev) {\n    ev.preventDefault();\n    this.props.onClose();\n  }\n\n  onDoneButtonClick(ev) {\n    ev.preventDefault();\n\n    if (this.validateForm()) {\n      const site = {url: this.cleanUrl(this.state.url)};\n      const {index} = this.props;\n      if (this.state.label !== \"\") {\n        site.label = this.state.label;\n      }\n\n      if (this.state.customScreenshotUrl) {\n        site.customScreenshotURL = this.cleanUrl(this.state.customScreenshotUrl);\n      } else if (this.props.site && this.props.site.customScreenshotURL) {\n        // Used to flag that previously cached screenshot should be removed\n        site.customScreenshotURL = null;\n      }\n      this.props.dispatch(ac.AlsoToMain({\n        type: at.TOP_SITES_PIN,\n        data: {site, index}\n      }));\n      this.props.dispatch(ac.UserEvent({\n        source: TOP_SITES_SOURCE,\n        event: \"TOP_SITES_EDIT\",\n        action_position: index\n      }));\n\n      this.props.onClose();\n    }\n  }\n\n  onPreviewButtonClick(event) {\n    event.preventDefault();\n    if (this.validateForm()) {\n      this.props.dispatch(ac.AlsoToMain({\n        type: at.PREVIEW_REQUEST,\n        data: {url: this.cleanUrl(this.state.customScreenshotUrl)}\n      }));\n      this.props.dispatch(ac.UserEvent({\n        source: TOP_SITES_SOURCE,\n        event: \"PREVIEW_REQUEST\"\n      }));\n    }\n  }\n\n  cleanUrl(url) {\n    // If we are missing a protocol, prepend http://\n    if (!url.startsWith(\"http:\") && !url.startsWith(\"https:\")) {\n      return `http://${url}`;\n    }\n    return url;\n  }\n\n  _tryParseUrl(url) {\n    try {\n      return new URL(url);\n    } catch (e) {\n      return null;\n    }\n  }\n\n  validateUrl(url) {\n    const validProtocols = [\"http:\", \"https:\"];\n    const urlObj = this._tryParseUrl(url) || this._tryParseUrl(this.cleanUrl(url));\n\n    return urlObj && validProtocols.includes(urlObj.protocol);\n  }\n\n  validateCustomScreenshotUrl() {\n    const {customScreenshotUrl} = this.state;\n    return !customScreenshotUrl || this.validateUrl(customScreenshotUrl);\n  }\n\n  validateForm() {\n    const validate = this.validateUrl(this.state.url) && this.validateCustomScreenshotUrl();\n\n    if (!validate) {\n      this.setState({validationError: true});\n    }\n\n    return validate;\n  }\n\n  _renderCustomScreenshotInput() {\n    const {customScreenshotUrl} = this.state;\n    const requestFailed = this.props.previewResponse === \"\";\n    const validationError = (this.state.validationError && !this.validateCustomScreenshotUrl()) || requestFailed;\n    // Set focus on error if the url field is valid or when the input is first rendered and is empty\n    const shouldFocus = (validationError && this.validateUrl(this.state.url)) || !customScreenshotUrl;\n    const isLoading = this.props.previewResponse === null &&\n      customScreenshotUrl && this.props.previewUrl === this.cleanUrl(customScreenshotUrl);\n\n    if (!this.state.showCustomScreenshotForm) {\n      return (<a className=\"enable-custom-image-input\" onClick={this.onEnableScreenshotUrlForm}>\n        <FormattedMessage id=\"topsites_form_use_image_link\" />\n      </a>);\n    }\n    return (<div className=\"custom-image-input-container\">\n      <TopSiteFormInput\n        errorMessageId={requestFailed ? \"topsites_form_image_validation\" : \"topsites_form_url_validation\"}\n        loading={isLoading}\n        onChange={this.onCustomScreenshotUrlChange}\n        onClear={this.onClearScreenshotInput}\n        shouldFocus={shouldFocus}\n        typeUrl={true}\n        value={customScreenshotUrl}\n        validationError={validationError}\n        titleId=\"topsites_form_image_url_label\"\n        placeholderId=\"topsites_form_url_placeholder\"\n        intl={this.props.intl} />\n    </div>);\n  }\n\n  render() {\n    const {customScreenshotUrl} = this.state;\n    const requestFailed = this.props.previewResponse === \"\";\n    // For UI purposes, editing without an existing link is \"add\"\n    const showAsAdd = !this.props.site;\n    const previous = (this.props.site && this.props.site.customScreenshotURL) || \"\";\n    const changed = customScreenshotUrl && this.cleanUrl(customScreenshotUrl) !== previous;\n    // Preview mode if changes were made to the custom screenshot URL and no preview was received yet\n    // or the request failed\n    const previewMode = changed && !this.props.previewResponse;\n    const previewLink = Object.assign({}, this.props.site);\n    if (this.props.previewResponse) {\n      previewLink.screenshot = this.props.previewResponse;\n      previewLink.customScreenshotURL = this.props.previewUrl;\n    }\n    return (\n      <form className=\"topsite-form\">\n        <div className=\"form-input-container\">\n          <h3 className=\"section-title\">\n            <FormattedMessage id={showAsAdd ? \"topsites_form_add_header\" : \"topsites_form_edit_header\"} />\n          </h3>\n          <div className=\"fields-and-preview\">\n            <div className=\"form-wrapper\">\n              <TopSiteFormInput onChange={this.onLabelChange}\n                value={this.state.label}\n                titleId=\"topsites_form_title_label\"\n                placeholderId=\"topsites_form_title_placeholder\"\n                intl={this.props.intl} />\n              <TopSiteFormInput onChange={this.onUrlChange}\n                shouldFocus={this.state.validationError && !this.validateUrl(this.state.url)}\n                value={this.state.url}\n                onClear={this.onClearUrlClick}\n                validationError={this.state.validationError && !this.validateUrl(this.state.url)}\n                titleId=\"topsites_form_url_label\"\n                typeUrl={true}\n                placeholderId=\"topsites_form_url_placeholder\"\n                errorMessageId=\"topsites_form_url_validation\"\n                intl={this.props.intl} />\n              {this._renderCustomScreenshotInput()}\n            </div>\n            <TopSiteLink link={previewLink}\n              defaultStyle={requestFailed}\n              title={this.state.label} />\n          </div>\n        </div>\n        <section className=\"actions\">\n          <button className=\"cancel\" type=\"button\" onClick={this.onCancelButtonClick}>\n            <FormattedMessage id=\"topsites_form_cancel_button\" />\n          </button>\n          {previewMode ?\n            <button className=\"done preview\" type=\"submit\" onClick={this.onPreviewButtonClick}>\n              <FormattedMessage id=\"topsites_form_preview_button\" />\n            </button> :\n            <button className=\"done\" type=\"submit\" onClick={this.onDoneButtonClick}>\n              <FormattedMessage id={showAsAdd ? \"topsites_form_add_button\" : \"topsites_form_save_button\"} />\n            </button>}\n        </section>\n      </form>\n    );\n  }\n}\n\nTopSiteForm.defaultProps = {\n  site: null,\n  index: -1\n};\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/TopSites/TopSiteForm.jsx","import {FormattedMessage, injectIntl} from \"react-intl\";\nimport {actionCreators as ac} from \"common/Actions.jsm\";\nimport {connect} from \"react-redux\";\nimport React from \"react\";\n\nexport class _StartupOverlay extends React.PureComponent {\n  constructor(props) {\n    super(props);\n    this.onInputChange = this.onInputChange.bind(this);\n    this.onSubmit = this.onSubmit.bind(this);\n    this.clickSkip = this.clickSkip.bind(this);\n    this.initScene = this.initScene.bind(this);\n    this.removeOverlay = this.removeOverlay.bind(this);\n\n    this.state = {emailInput: \"\"};\n    this.initScene();\n  }\n\n  initScene() {\n    // Timeout to allow the scene to render once before attaching the attribute\n    // to trigger the animation.\n    setTimeout(() => {\n      this.setState({show: true});\n    }, 10);\n  }\n\n  removeOverlay() {\n    window.removeEventListener(\"visibilitychange\", this.removeOverlay);\n    this.setState({show: false});\n    setTimeout(() => {\n      // Allow scrolling and fully remove overlay after animation finishes.\n      document.body.classList.remove(\"welcome\");\n    }, 400);\n  }\n\n  onInputChange(e) {\n    this.setState({emailInput: e.target.value});\n  }\n\n  onSubmit() {\n    this.props.dispatch(ac.UserEvent({event: \"SUBMIT_EMAIL\"}));\n    window.addEventListener(\"visibilitychange\", this.removeOverlay);\n  }\n\n  clickSkip() {\n    this.props.dispatch(ac.UserEvent({event: \"SKIPPED_SIGNIN\"}));\n    this.removeOverlay();\n  }\n\n  render() {\n    let termsLink = (<a href=\"https://accounts.firefox.com/legal/terms\" target=\"_blank\" rel=\"noopener noreferrer\"><FormattedMessage id=\"firstrun_terms_of_service\" /></a>);\n    let privacyLink = (<a href=\"https://accounts.firefox.com/legal/privacy\" target=\"_blank\" rel=\"noopener noreferrer\"><FormattedMessage id=\"firstrun_privacy_notice\" /></a>);\n    return (\n      <div className={`overlay-wrapper ${this.state.show ? \"show \" : \"\"}`}>\n        <div className=\"background\" />\n        <div className=\"firstrun-scene\">\n          <div className=\"fxaccounts-container\">\n            <div className=\"firstrun-left-divider\">\n              <h1 className=\"firstrun-title\"><FormattedMessage id=\"firstrun_title\" /></h1>\n              <p className=\"firstrun-content\"><FormattedMessage id=\"firstrun_content\" /></p>\n              <a className=\"firstrun-link\" href=\"https://www.mozilla.org/firefox/features/sync/\" target=\"_blank\" rel=\"noopener noreferrer\"><FormattedMessage id=\"firstrun_learn_more_link\" /></a>\n            </div>\n            <div className=\"firstrun-sign-in\">\n              <p className=\"form-header\"><FormattedMessage id=\"firstrun_form_header\" /><span><FormattedMessage id=\"firstrun_form_sub_header\" /></span></p>\n              <form method=\"get\" action=\"https://accounts.firefox.com?entrypoint=activity-stream-firstrun&utm_source=activity-stream&utm_campaign=firstrun\" target=\"_blank\" rel=\"noopener noreferrer\" onSubmit={this.onSubmit}>\n                <input name=\"service\" type=\"hidden\" value=\"sync\" />\n                <input name=\"action\" type=\"hidden\" value=\"email\" />\n                <input name=\"context\" type=\"hidden\" value=\"fx_desktop_v3\" />\n                <input className=\"email-input\" name=\"email\" type=\"email\" required=\"true\" placeholder={this.props.intl.formatMessage({id: \"firstrun_email_input_placeholder\"})} onChange={this.onInputChange} />\n                <div className=\"extra-links\">\n                  <FormattedMessage\n                    id=\"firstrun_extra_legal_links\"\n                    values={{\n                      terms: termsLink,\n                      privacy: privacyLink\n                    }} />\n                </div>\n                <button className=\"continue-button\" type=\"submit\"><FormattedMessage id=\"firstrun_continue_to_login\" /></button>\n              </form>\n              <button className=\"skip-button\" disabled={!!this.state.emailInput} onClick={this.clickSkip}><FormattedMessage id=\"firstrun_skip_login\" /></button>\n            </div>\n          </div>\n        </div>\n      </div>\n    );\n  }\n}\n\nexport const StartupOverlay = connect()(injectIntl(_StartupOverlay));\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/components/StartupOverlay/StartupOverlay.jsx","import {actionCreators as ac, actionTypes as at} from \"common/Actions.jsm\";\nimport {perfService as perfSvc} from \"common/PerfService.jsm\";\n\nconst VISIBLE = \"visible\";\nconst VISIBILITY_CHANGE_EVENT = \"visibilitychange\";\n\nexport class DetectUserSessionStart {\n  constructor(store, options = {}) {\n    this._store = store;\n    // Overrides for testing\n    this.document = options.document || global.document;\n    this._perfService = options.perfService || perfSvc;\n    this._onVisibilityChange = this._onVisibilityChange.bind(this);\n  }\n\n  /**\n   * sendEventOrAddListener - Notify immediately if the page is already visible,\n   *                    or else set up a listener for when visibility changes.\n   *                    This is needed for accurate session tracking for telemetry,\n   *                    because tabs are pre-loaded.\n   */\n  sendEventOrAddListener() {\n    if (this.document.visibilityState === VISIBLE) {\n      // If the document is already visible, to the user, send a notification\n      // immediately that a session has started.\n      this._sendEvent();\n    } else {\n      // If the document is not visible, listen for when it does become visible.\n      this.document.addEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n    }\n  }\n\n  /**\n   * _sendEvent - Sends a message to the main process to indicate the current\n   *              tab is now visible to the user, includes the\n   *              visibility_event_rcvd_ts time in ms from the UNIX epoch.\n   */\n  _sendEvent() {\n    this._perfService.mark(\"visibility_event_rcvd_ts\");\n\n    try {\n      let visibility_event_rcvd_ts = this._perfService\n        .getMostRecentAbsMarkStartByName(\"visibility_event_rcvd_ts\");\n\n      this._store.dispatch(ac.AlsoToMain({\n        type: at.SAVE_SESSION_PERF_DATA,\n        data: {visibility_event_rcvd_ts}\n      }));\n    } catch (ex) {\n      // If this failed, it's likely because the `privacy.resistFingerprinting`\n      // pref is true.  We should at least not blow up.\n    }\n  }\n\n  /**\n   * _onVisibilityChange - If the visibility has changed to visible, sends a notification\n   *                      and removes the event listener. This should only be called once per tab.\n   */\n  _onVisibilityChange() {\n    if (this.document.visibilityState === VISIBLE) {\n      this._sendEvent();\n      this.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);\n    }\n  }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./content-src/lib/detect-user-session-start.js"],"sourceRoot":""}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/docs/ISSUE_TEMPLATE.md
@@ -0,0 +1,6 @@
+Please file new bugs in Bugzilla:
+https://bugzilla.mozilla.org/enter_bug.cgi?product=Firefox&component=Activity%20Streams%3A%20Newtab
+
+Activity Stream is no longer accepting new issues via GitHub, but Issues are kept open, so old issues can still be viewed.
+
+Thanks for contributing!
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/docs/v2-system-addon/1.GETTING_STARTED.md
@@ -0,0 +1,102 @@
+# Activity Stream Development Guide
+
+## Contents of this guide
+
+- Installation, set-up, and other basics (this page)
+- [Writing unit tests](./unit_testing_guide.md)
+- [Adding new Telemetry (user and performance metrics)](./telemetry.md)
+- [Reading/changing Firefox prefs](./preferences.md)
+- [Adding new sections](./sections.md)
+
+## How to try Activity Stream
+
+If you just want to try out the current version of Activity Stream in Firefox, you can
+install [Firefox Nightly](https://www.mozilla.org/en-US/firefox/channel/desktop/#nightly)
+or any version of Firefox >= 57.0. If you still don't see activity stream, go to `about:config`,
+and make sure the `browser.newtabpage.activity-stream.enabled` pref is set to `true`.
+
+## Source code and submitting pull requests
+
+A copy of the code in the [system-addon/](../../system-addon/) subdirectory of this repository
+is exported to Mozilla central on a regular basis, which can be found at [browser/extensions/activity-stream](https://searchfox.org/mozilla-central/source/browser/extensions/activity-stream).
+Keep in mind that some of these files are generated, so if you intend on editing any files, you should
+do so in the Github version.
+
+Pull requests should be sent against the master branch of https://github.com/mozilla/activity-stream,
+NOT against Mozilla central.
+
+## Prerequisites for development
+
+### Operating system and software
+
+The Activity Stream development environment is designed to work on Mac and Linux.
+If you need to develop on Windows, you might want to reach out on IRC (#activity-stream)
+if you run into any problems.
+
+You will also need to install:
+
+- Node.js 7+ (On Mac, the best way to install Node.js is to use the [install link on the Node.js homepage](https://nodejs.org/en/))
+- npm (packaged with Node.js)
+
+### Activity Stream Github repository
+
+You will need to to clone Activity Stream to a local directory from the `master`
+branch of our Github repository: https://github.com/mozilla/activity-stream
+
+```
+git clone https://github.com/mozilla/activity-stream.git
+```
+
+### Mozilla Central
+You will need a local copy of Mozilla Central in a directory named `mozilla-central`. Check the detail of how to get and build Mozilla Central in [Building Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Simple_Firefox_build).
+That directory should be a sibling of your local `activity-stream` directory (like so):
+
+```
+/
+  mozilla-central/
+  activity-stream/
+```
+
+Check out [these docs on artifact builds](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Artifact_builds)
+for instructions about how to download and configure Mozilla Central if you have
+never done so before.
+
+**To build Firefox way faster**, you should definitely enable Artifact builds.
+To do that, create a `.mozconfig` (or `mozconfig`) file in the root of your
+mozilla-central directory and add the following to it:
+
+```bash
+# Automatically download and use compiled C++ components:
+ac_add_options --enable-artifact-builds
+
+# Write build artifacts to:
+mk_add_options MOZ_OBJDIR=./objdir-frontend
+```
+
+## Building
+
+1. Install required dependencies by running `npm install`.
+2. To build Activity Stream, run `npm run buildmc` from the root of the
+`activity-stream` directory. This will build the js and css files and copy them
+into the `browser/extensions/activity-stream` directory inside Mozilla Central.
+3. Build and run Firefox from the `mozilla-central` directory by running `./mach build && ./mach run`.
+
+## Continuous development
+
+Running `npm run startmc` will start a process that watches files in `activity-stream`
+and continuously builds/copies changes to `mozilla-central`. You will
+still need to rebuild Firefox (`./mach build`) if you change `.jsm` files.
+
+## Unit Tests
+
+Run `npm run testmc` to run the unit tests with karma/mocha. The source code for these
+tests can be found in `system-addon/test/unit/`.
+
+We have a [detailed write-up](unit_testing_guide.md) on
+Activity Stream unit testing.  This is an important read, as there are **significant** JavaScript differences when
+writing Firefox add-on code that must be taken into consideration.
+
+Our build process will run unit tests and code coverage tools automatically.  Make that all tests pass,
+and that you are not responsible for unduly decreasing the overall code coverage percentage.
+
+If you see any missing test coverage, you can inspect the coverage report by running `npm run testmc && npm run debugcoverage`.
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/docs/v2-system-addon/data_dictionary.md
@@ -0,0 +1,268 @@
+# Activity Stream Pings
+
+The Activity Stream system add-on sends various types of pings to the backend (HTTPS POST) [Onyx server](https://github.com/mozilla/onyx) :
+- a `health` ping that reports whether or not a user has a custom about:home or about:newtab page
+- a `session` ping that describes the ending of an Activity Stream session (a new tab is closed or refreshed), and
+- an `event` ping that records specific data about individual user interactions while interacting with Activity Stream
+- a `performance` ping that records specific performance related events
+- an `undesired` ping that records data about bad app states and missing data
+- an `impression_stats` ping that records data about Pocket impressions and user interactions
+
+Schema definitions/validations that can be used for tests can be found in `system-addon/test/schemas/pings.js`.
+
+# Example Activity Stream `health` log
+
+```js
+{
+  "addon_version": "1.0.0",
+  "client_id": "374dc4d8-0cb2-4ac5-a3cf-c5a9bc3c602e",
+  "locale": "en-US",
+  "version": "62.0a1",
+  "release_channel": "nightly",
+  "event": "AS_ENABLED",
+  "value": 10,
+
+  // These fields are generated on the server
+  "date": "2016-03-07",
+  "ip": "10.192.171.13",
+  "ua": "python-requests/2.9.1",
+  "receive_at": 1457396660000
+}
+```
+
+# Example Activity Stream `session` Log
+
+```js
+{
+  // These fields are sent from the client
+  "action": "activity_stream_session",
+  "addon_version": "1.0.0",
+  "client_id": "374dc4d8-0cb2-4ac5-a3cf-c5a9bc3c602e",
+  "locale": "en-US",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
+  "session_duration": 1635,
+  "session_id": "{12dasd-213asda-213dkakj}",
+  "region": "US",
+  "profile_creation_date": 14786,
+  "user_prefs": 7
+
+  // These fields are generated on the server
+  "date": "2016-03-07",
+  "ip": "10.192.171.13",
+  "ua": "python-requests/2.9.1",
+  "receive_at": 1457396660000
+}
+```
+
+# Example Activity Stream `user_event` Log
+
+```js
+{
+  "action": "activity_stream_user_event",
+  "action_position": "3",
+  "addon_version": "1.0.0",
+  "client_id": "374dc4d8-0cb2-4ac5-a3cf-c5a9bc3c602e",
+  "event": "click or scroll or search or delete",
+  "locale": "en-US",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
+  "source": "top sites, or bookmarks, or...",
+  "session_id": "{12dasd-213asda-213dkakj}",
+  "recommender_type": "pocket-trending",
+  "metadata_source": "MetadataService or Local or TippyTopProvider",
+  "user_prefs": 7
+
+  // These fields are generated on the server
+  "ip": "10.192.171.13",
+  "ua": "python-requests/2.9.1",
+  "receive_at": 1457396660000,
+  "date": "2016-03-07",
+}
+```
+
+# Example Activity Stream `performance` Log
+
+```js
+{
+  "action": "activity_stream_performance_event",
+  "addon_version": "1.0.0",
+  "client_id": "374dc4d8-0cb2-4ac5-a3cf-c5a9bc3c602e",
+  "event": "previewCacheHit",
+  "event_id": "45f1912165ca4dfdb5c1c2337dbdc58f",
+  "locale": "en-US",
+  "page": "unknown", // all session-specific perf events should be part of the session perf object
+  "receive_at": 1457396660000,
+  "source": "TOP_FRECENT_SITES",
+  "value": 1,
+  "user_prefs": 7,
+
+  // These fields are generated on the server
+  "ip": "10.192.171.13",
+  "ua": "python-requests/2.9.1",
+  "receive_at": 1457396660000,
+  "date": "2016-03-07"
+}
+```
+
+# Example Activity Stream `undesired event` Log
+
+```js
+{
+  "action": "activity_stream_undesired_event",
+  "addon_version": "1.0.12",
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "event": "MISSING_IMAGE",
+  "locale": "en-US",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"]
+  "source": "HIGHLIGHTS",
+  "value": 0,
+  "user_prefs": 7,
+
+  // These fields are generated on the server
+  "ip": "10.192.171.13",
+  "ua": "python-requests/2.9.1",
+  "receive_at": 1457396660000,
+  "date": "2016-03-07"
+}
+```
+# Example Activity Stream `impression_stats` Logs
+
+```js
+{
+  "action": "activity_stream_impression_stats",
+  "client_id": "n/a",
+  "session_id": "n/a",
+  "impression_id": "{005deed0-e3e4-4c02-a041-17405fd703f6}",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "source": "pocket",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"]
+  "tiles": [{"id": 10000}, {"id": 10001}, {"id": 10002}]
+  "user_prefs": 7
+}
+```
+
+```js
+{
+  "action": "activity_stream_impression_stats",
+  "client_id": "n/a",
+  "session_id": "n/a",
+  "impression_id": "{005deed0-e3e4-4c02-a041-17405fd703f6}",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "source": "pocket",
+  "page": "unknown",
+  "user_prefs": 7,
+
+  // "pos" is the 0-based index to record the tile's position in the Pocket section.
+  "tiles": [{"id": 10000, "pos": 0}],
+
+  // A 0-based index to record which tile in the "tiles" list that the user just interacted with.
+  "click|block|pocket": 0
+}
+```
+
+# Example Activity Stream `Router` Pings
+
+```js
+{
+  "client_id": "n/a",
+  "action": ["snippets_user_event" | "onboarding_user_event"],
+  "impression_id": "{005deed0-e3e4-4c02-a041-17405fd703f6}",
+  "source": "pocket",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "source": "NEWTAB_FOOTER_BAR",
+  "message_id": "some_snippet_id",
+  "event": "IMPRESSION"
+}
+```
+
+| KEY | DESCRIPTION | &nbsp; |
+|-----|-------------|:-----:|
+| `action_position` | [Optional] The index of the element in the `source` that was clicked. | :one:
+| `action` | [Required] Either `activity_stream_event`, `activity_stream_session`, or `activity_stream_performance`. | :one:
+| `addon_version` | [Required] The version of the Activity Stream addon. | :one:
+| `client_id` | [Required] An identifier for this client. | :one:
+| `card_type` | [Optional] ("bookmark", "pocket", "trending", "pinned") | :one:
+| `date` | [Auto populated by Onyx] The date in YYYY-MM-DD format. | :three:
+| `experiment_id` | [Optional] The unique identifier for a specific experiment. | :one:
+| `event_id` | [Required] An identifier shared by multiple performance pings that describe ane entire request flow. | :one:
+| `event` | [Required] The type of event. Any user defined string ("click", "share", "delete", "more_items") | :one:
+| `highlight_type` | [Optional] Either ["bookmarks", "recommendation", "history"]. | :one:
+| `impression_id` | [Optional] The unique impression identifier for a specific client. | :one:
+| `ip` | [Auto populated by Onyx] The IP address of the client. | :two:
+| `locale` | [Auto populated by Onyx] The browser chrome's language (eg. en-US). | :two:
+| `load_trigger_ts` | [Optional][Server Counter][Server Alert for too many omissions]  DOMHighResTimeStamp of the action perceived by the user to trigger the load of this page. | :one:
+| `load_trigger_type` | [Server Counter][Server Alert for too many omissions] Either ["first_window_opened", "menu_plus_or_keyboard", "unexpected"]. | :one:
+| `metadata_source` | [Optional] The source of which we computed metadata. Either (`MetadataService` or `Local` or `TippyTopProvider`). | :one:
+| `page` | [Required] One of ["about:newtab", "about:home", "about:welcome", "unknown" (which either means not-applicable or is a bug)]. | :one:
+| `recommender_type` | [Optional] The type of recommendation that is being shown, if any. | :one:
+| `session_duration` | [Optional][Server Counter][Server Alert for too many omissions] Time in (integer) milliseconds of the difference between the new tab becoming visible
+and losing focus. | :one:
+| `session_id` | [Optional] The unique identifier for a specific session. | :one:
+| `source` | [Required] Either ("recent_links", "recent_bookmarks", "frecent_links", "top_sites", "spotlight", "sidebar") and indicates what `action`. | :two:
+| `received_at` | [Auto populated by Onyx] The time in ms since epoch. | :three:
+| `total_bookmarks` | [Optional] The total number of bookmarks in the user's places db. | :one:
+| `total_history_size` | [Optional] The number of history items currently in the user's places db. | :one:
+| `ua` | [Auto populated by Onyx] The user agent string. | :two:
+| `unload_reason` | [Required] The reason the Activity Stream page lost focus. | :one:
+| `url` | [Optional] The URL of the recommendation shown in one of the highlights spots, if any. | :one:
+| `value` (performance) | [Required] An integer that represents the measured performance value. Can store counts, times in milliseconds, and should always be a positive integer.| :one:
+| `value` (event) | [Optional] An object with keys "icon_type" and "card_type" to record the extra information for event ping| :one:
+| `ver` | [Auto populated by Onyx] The version of the Onyx API the ping was sent to. | :one:
+| `highlights_size` | [Optional] The size of the Highlights set. | :one:
+| `highlights_data_late_by_ms` | [Optional] Time in ms it took for Highlights to become initialized | :one:
+| `topsites_data_late_by_ms` | [Optional] Time in ms it took for TopSites to become initialized | :one:
+| `topstories.domain.affinity.calculation.ms` | [Optional] Time in ms it took for domain affinities to be calculated | :one:
+| `topsites_first_painted_ts` | [Optional][Service Counter][Server Alert for too many omissions] Timestamp of when the Top Sites element finished painting (possibly with only placeholder screenshots) | :one:
+| `custom_screenshot` | [Optional] Number of topsites that display a custom screenshot. | :one:
+| `screenshot_with_icon` | [Optional] Number of topsites that display a screenshot and a favicon. | :one:
+| `screenshot` | [Optional] Number of topsites that display only a screenshot. | :one:
+| `tippytop` | [Optional] Number of topsites that display a tippytop icon. | :one:
+| `rich_icon` | [Optional] Number of topsites that display a high quality favicon. | :one:
+| `no_image` | [Optional] Number of topsites that have no screenshot. | :one:
+| `topsites_pinned` | [Optional] Number of topsites that are pinned. | :one:
+| `visibility_event_rcvd_ts` | [Optional][Server Counter][Server Alert for too many omissions] DOMHighResTimeStamp of when the page itself receives an event that document.visibilityState == visible. | :one:
+| `tiles` | [Required] A list of tile objects for the Pocket articles. Each tile object mush have a ID, and optionally a "pos" property to indicate the tile position | :one:
+| `click` | [Optional] An integer to record the 0-based index when user clicks on a Pocket tile. | :one:
+| `block` | [Optional] An integer to record the 0-based index when user blocks a Pocket tile. | :one:
+| `pocket` | [Optional] An integer to record the 0-based index when user saves a Pocket tile to Pocket. | :one:
+| `user_prefs` | [Required] The encoded integer of user's preferences. | :one: & :four:
+| `is_prerendered` | [Required] A boolean to signify whether the page is prerendered or not | :one:
+| `is_preloaded` | [Required] A boolean to signify whether the page is preloaded or not | :one:
+| `icon_type` | [Optional] ("tippytop", "rich_icon", "screenshot_with_icon", "screenshot", "no_image") | :one:
+| `region` | [Optional] A string maps to pref "browser.search.region", which is essentially the two letter ISO 3166-1 country code populated by the Firefox search service. Note that: 1). it reports "OTHER" for those regions with smaller Firefox user base (less than 10000) so that users cannot be uniquely identified; 2). it reports "UNSET" if this pref is missing; 3). it reports "EMPTY" if the value of this pref is an empty string. | :one:
+| `profile_creation_date` | [Optional] An integer to record the age of the Firefox profile as the total number of days since the UNIX epoch. | :one:
+|`message_id` | [required] A string identifier of the message in Activity Stream Router. | :one:
+
+**Where:**
+
+:one: Firefox data
+:two: HTTP protocol data
+:three: server augmented data
+:four: User preferences encoding table
+
+
+Note: the following session-related fields are not yet implemented in the system-addon,
+but will likely be added in future versions:
+
+```js
+{
+  "total_bookmarks": 19,
+  "total_history_size": 9,
+  "highlights_size": 20
+}
+```
+
+This encoding mapping was defined in `system-addon/lib/TelemetryFeed.jsm`
+
+| Preference | Encoded value |
+| --- | --- |
+| `showSearch` | 1 |
+| `showTopSites` | 2 |
+| `showTopStories` | 4 |
+| `showHighlights` | 8 |
+| `showSnippets`   | 16 |
+| `showSponsored`  | 32 |
+
+Each item above could be combined with other items through bitwise OR operation
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/docs/v2-system-addon/data_events.md
@@ -0,0 +1,541 @@
+# Metrics we collect
+
+By default, the about:newtab and about:home pages in Firefox (the pages you see when you open a new tab and when you start the browser), will send data back to Mozilla servers about usage of these pages.  The intent is to collect data in order to improve the user's experience while using Activity Stream.  Data about your specific browsing behaior or the sites you visit is **never transmitted to any Mozilla server**.  At any time, it is easy to **turn off** this data collection by [opting out of Firefox telemetry](https://support.mozilla.org/kb/share-telemetry-data-mozilla-help-improve-firefox).
+
+Data is sent to our servers in the form of discreet HTTPS 'pings' or messages whenever you do some action on the Activity Stream about:home, about:newtab or about:welcome pages.  We try to minimize the amount and frequency of pings by batching them together.  Pings are sent in [JSON serialized format](http://www.json.org/).
+
+At Mozilla, [we take your privacy very seriously](https://www.mozilla.org/privacy/).  The Activity Stream page will never send any data that could personally identify you.  We do not transmit what you are browsing, searches you perform or any private settings.  Activity Stream does not set or send cookies, and uses [Transport Layer Security](https://en.wikipedia.org/wiki/Transport_Layer_Security) to securely transmit data to Mozilla servers.
+
+Data collected from Activity Stream is retained on Mozilla secured servers for a period of 30 days before being rolled up into an anonymous aggregated format.  After this period the raw data is deleted permanently.  Mozilla **never shares data with any third party**.
+
+The following is a detailed overview of the different kinds of data we collect in the Activity Stream. See [data_dictionary.md](data_dictionary.md) for more details for each field.
+
+## Health ping
+
+This is a heartbeat ping indicating whether Activity Stream is currently being used or not, it's submitted once upon the browser initialization.
+
+```js
+{
+  "client_id": "374dc4d8-0cb2-4ac5-a3cf-c5a9bc3c602e",
+  "locale": "en-US",
+  "version": "62.0a1",
+  "release_channel": "nightly",
+  "event": "AS_ENABLED",
+  "value": 10
+}
+```
+where the "value" is encoded as:
+  * Value 0: default
+  * Value 1: about:blank
+  * Value 2: web extension
+  * Value 3: other custom URL(s)
+Two encoded integers for about:newtab and about:home are combined in a bitwise fashion. For instance, if both about:home and about:newtab were set to about:blank, then `value = 5 = (1 | (1 << 2))`, i.e `value = (bitfield of about:newtab) | (bitfield of about:newhome << 2)`.
+
+## User event pings
+
+These pings are captured when a user **performs some kind of interaction** in the add-on.
+
+### Basic shape
+
+A user event ping includes some basic metadata (tab id, addon version, etc.) as well as variable fields which indicate the location and action of the event.
+
+```js
+{
+  // This indicates the type of interaction
+  "event": ["CLICK", "SEARCH", "BLOCK", "DELETE", "OPEN_NEW_WINDOW", "OPEN_PRIVATE_WINDOW", "BOOKMARK_DELETE", "BOOKMARK_ADD", "OPEN_NEWTAB_PREFS", "CLOSE_NEWTAB_PREFS"],
+
+  // Optional field indicating the UI component type
+  "source": "TOP_SITES",
+
+  // Optional field if there is more than one of a component type on a page.
+  // It is zero-indexed.
+  // For example, clicking the second Highlight would result in an action_position of 1
+  "action_position": 1,
+
+  // Basic metadata
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown" ],
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "action": "activity_stream_event",
+  "user_prefs": 7
+}
+```
+
+### Types of user interactions
+
+#### Performing a search
+
+```js
+{
+  "event": "SEARCH",
+
+  // Basic metadata
+  "action": "activity_stream_event",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "user_prefs": 7
+}
+```
+
+#### Clicking a top site item
+
+```js
+{
+  "event": "CLICK",
+  "source": "TOP_SITES",
+  "action_position": 2,
+  "value": {
+    "card_type": "pinned",
+    "icon_type": ["screenshot_with_icon" | "screenshot" | "tippytop" | "rich_icon" | "no_image"]
+  }
+
+  // Basic metadata
+  "action": "activity_stream_event",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "user_prefs": 7
+}
+```
+
+#### Deleting an item from history
+
+```js
+{
+  "event": "DELETE",
+  "source": "TOP_SITES",
+  "action_position": 2,
+  "value": {
+    "card_type": "pinned",
+    "icon_type": ["screenshot_with_icon" | "screenshot" | "tippytop" | "rich_icon" | "no_image"]
+  }
+
+  // Basic metadata
+  "action": "activity_stream_event",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "user_prefs": 7
+}
+```
+
+#### Blocking a site
+
+```js
+{
+  "event": "BLOCK",
+  "source": "TOP_SITES",
+  "action_position": 2,
+  "value": {
+    "card_type": "pinned",
+    "icon_type": ["screenshot_with_icon" | "screenshot" | "tippytop" | "rich_icon" | "no_image"]
+  }
+
+  // Basic metadata
+  "action": "activity_stream_event",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "user_prefs": 7
+}
+```
+
+#### Bookmarking a link
+
+```js
+{
+  "event": "BOOKMARK_ADD",
+  "source": "HIGHLIGHTS",
+  "action_position": 2,
+  "value": {
+    "card_type": "trending"
+  }
+  
+  // Basic metadata
+  "action": "activity_stream_event",
+  "page": ["about:newtab" | "about:home" | "about:welcome"],
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "user_prefs": 7
+}
+```
+
+#### Removing a bookmark from a link
+
+```js
+{
+  "event": "BOOKMARK_DELETE",
+  "source": "HIGHLIGHTS",
+  "action_position": 2,
+  "value": {
+    "card_type": "bookmark"
+  }
+
+  // Basic metadata
+  "action": "activity_stream_event",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "user_prefs": 7
+}
+```
+
+#### Opening a link in a new window
+
+```js
+{
+  "event": "OPEN_NEW_WINDOW",
+  "source": "TOP_SITES",
+  "action_position": 2,
+  "value": {
+    "card_type": "pinned",
+    "icon_type": ["screenshot_with_icon" | "screenshot" | "tippytop" | "rich_icon" | "no_image"]
+  }
+
+  // Basic metadata
+  "action": "activity_stream_event",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "user_prefs": 7
+}
+```
+
+#### Opening a link in a new private window
+
+```js
+{
+  "event": "OPEN_PRIVATE_WINDOW",
+  "source": "TOP_SITES",
+  "action_position": 2,
+  "value": {
+    "card_type": "pinned",
+    "icon_type": ["screenshot_with_icon" | "screenshot" | "tippytop" | "rich_icon" | "no_image"]
+  }
+
+  // Basic metadata
+  "action": "activity_stream_event",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "user_prefs": 7
+}
+```
+
+#### Opening the new tab preferences pane
+
+```js
+{
+  "event": "OPEN_NEWTAB_PREFS",
+
+  // Basic metadata
+  "action": "activity_stream_event",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "user_prefs": 7
+}
+```
+
+#### Closing the new tab preferences pane
+
+```js
+{
+  "event": "CLOSE_NEWTAB_PREFS",
+
+  // Basic metadata
+  "action": "activity_stream_event",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "user_prefs": 7
+}
+```
+
+#### Acknowledging a section disclaimer
+
+```js
+{
+  "event": "SECTION_DISCLAIMER_ACKNOWLEDGED",
+  "source": "TOP_STORIES",
+
+  // Basic metadata
+  "action": "activity_stream_event",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "user_prefs": 7
+}
+```
+
+#### Adding or editing a new TopSite
+
+```js
+{
+  "event": "TOP_SITES_EDIT",
+  "source": "TOP_SITES_SOURCE",
+  // "-1" Is used for prepending a new TopSite at the front of the list, while
+  // any other possible value is used for editing an existing TopSite slot.
+  "action_position": [-1 | "0..TOP_SITES_LENGTH"]
+}
+```
+
+#### Requesting a custom screenshot preview
+
+```js
+{
+  "event": "PREVIEW_REQUEST",
+  "source": "TOP_SITES"
+}
+```
+
+## Session end pings
+
+When a session ends, the browser will send a `"activity_stream_session"` ping to our metrics servers. This ping contains the length of the session, a unique reason for why the session ended, and some additional metadata.
+
+### Basic event
+
+All `"activity_stream_session"` pings have the following basic shape. Some fields are variable.
+
+```js
+{
+  "action": "activity_stream_session",
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
+  "session_duration": 4199,
+  "region": "US",
+  "profile_creation_date": 14786,
+  "user_prefs": 7
+}
+```
+
+### What causes a session end?
+
+Here are different scenarios that cause a session end event to be sent:
+
+1. After a search
+2. Clicking on something that causes navigation (top site, highlight, etc.)
+3. Closing the browser
+5. Refreshing
+6. Navigating to a new URL via the url bar or file menu
+
+
+### Session performance data
+
+This data is held in a child object of the `activity_stream_session` event called `perf`.  All fields suffixed by `_ts` are type `DOMHighResTimeStamp` (aka a double of milliseconds, with a 5 microsecond precision) with 0 being the [timeOrigin](https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp#The_time_origin) of the browser's hidden chrome window.
+
+An example might look like this:
+
+```javascript
+perf: {
+  // Timestamp of the action perceived by the user to trigger the load
+  // of this page.
+  //
+  // Not required at least for error cases where the
+  // observer event doesn't fire
+  "load_trigger_ts": 1,
+
+  // What was the perceived trigger of the load action:
+  "load_trigger_type": [
+    "first_window_opened" | // home only
+    "menu_plus_or_keyboard" | // newtab only
+    "unexpected" // sessions lacking actual start times
+  ],
+
+  // when the page itself receives an event that document.visibilityStat=visible
+  "visibility_event_rcvd_ts": 2,
+
+  // When did the topsites element finish painting?  Note that, at least for
+  // the first tab to be loaded, and maybe some others, this will be before
+  // topsites has yet to receive screenshots updates from the add-on code,
+  // and is therefore just showing placeholder screenshots.
+  "topsites_first_painted_ts": 5,
+
+  // The 6 different types of TopSites icons and how many of each kind did the
+  // user see.
+  "topsites_icon_stats": {
+    "custom_screenshot": 0,
+    "screenshot_with_icon": 2,
+    "screenshot": 1,
+    "tippytop": 2,
+    "rich_icon": 1,
+    "no_image": 0
+  },
+
+  // The number of Top Sites that are pinned.
+  "topsites_pinned": 3,
+
+  // How much longer the data took, in milliseconds, to be ready for display
+  // than it would have been in the ideal case. The user currently sees placeholder
+  // cards instead of real cards for approximately this length of time. This is
+  // sent when the first call of the component's `render()` method happens with
+  // `this.props.initialized` set to `false`, and the value is the amount of
+  // time in ms until `render()` is called with `this.props.initialized` set to `true`.
+  "highlights_data_late_by_ms": 67,
+  "topsites_data_late_by_ms": 35,
+
+  // Whether the page is preloaded or not.
+  "is_preloaded": [true|false],
+
+  // Whether the page is prerendered or not.
+  "is_prerendered": [true|false]
+}
+```
+
+## Top Story pings
+
+When Top Story (currently powered by Pocket) is enabled in Activity Stream, the browser will send following `activity_stream_impression_stats` to our metrics servers.
+
+### Impression stats
+
+This reports all the Pocket recommended articles (a list of `id`s) when the user opens a newtab.
+
+```js
+{
+  "action": "activity_stream_impression_stats",
+
+  // both "client_id" and "session_id" are set to "n/a" in this ping.
+  "client_id": "n/a",
+  "session_id": "n/a",
+  "impression_id": "{005deed0-e3e4-4c02-a041-17405fd703f6}",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "source": "pocket",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
+  "user_prefs": 7,
+  "tiles": [{"id": 10000}, {"id": 10001}, {"id": 10002}]
+}
+```
+
+### Click/block/save_to_pocket ping
+
+This reports the user's interaction with those Pocket tiles.
+
+```js
+{
+  "action": "activity_stream_impression_stats",
+
+  // both "client_id" and "session_id" are set to "n/a" in this ping.
+  "client_id": "n/a",
+  "session_id": "n/a",
+  "impression_id": "{005deed0-e3e4-4c02-a041-17405fd703f6}",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "source": "pocket",
+  "page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
+  "user_prefs": 7,
+
+  // "pos" is the 0-based index to record the tile's position in the Pocket section.
+  "tiles": [{"id": 10000, "pos": 0}],
+
+  // A 0-based index to record which tile in the "tiles" list that the user just interacted with.
+  "click|block|pocket": 0
+}
+```
+
+## Performance pings
+
+These pings are captured to record performance related events i.e. how long certain operations take to execute.
+
+### Domain affinity calculation
+
+This reports the duration of the domain affinity calculation in milliseconds.
+
+```js
+{
+  "action": "activity_stream_performance_event",
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "user_prefs": 7,
+  "event": "topstories.domain.affinity.calculation.ms",
+  "value": 43
+}
+```
+
+## Undesired event pings
+
+These pings record the undesired events happen in the addon for further investigation.
+
+### Addon initialization failure
+
+This reports when the addon fails to initialize
+
+```js
+{
+  "action": "activity_stream_undesired_event",
+  "client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "user_prefs": 7,
+  "event": "ADDON_INIT_FAILED",
+  "value": -1
+}
+```
+## Activity Stream Router pings
+
+These pings record the impression and user interactions within Activity Stream Router.
+
+### Impression ping
+
+This reports the impression of Activity Stream Router.
+
+```js
+{
+  "client_id": "n/a",
+  "action": ["snippets_user_event" | "onboarding_user_event"],
+  "impression_id": "{005deed0-e3e4-4c02-a041-17405fd703f6}",
+  "source": "pocket",
+  "addon_version": "1.0.12",
+  "locale": "en-US",
+  "source": "NEWTAB_FOOTER_BAR",
+  "message_id": "some_snippet_id",
+  "event": "IMPRESSION"
+}
+```
+
+
+### User interaction pings
+
+This reports the user's interaction with Activity Stream Router.
+
+```js
+{
+  "client_id": "n/a",
+  "action": ["snippets_user_event" | "onboarding_user_event"],
+  "addon_version": "1.0.12",
+  "impression_id": "{005deed0-e3e4-4c02-a041-17405fd703f6}",
+  "locale": "en-US",
+  "source": "NEWTAB_FOOTER_BAR",
+  "message_id": "some_snippet_id",
+  "event": ["CLICK_BUTTION" | "BLOCK"]
+}
+```
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/docs/v2-system-addon/mochitests.md
@@ -0,0 +1,84 @@
+We use [mochitests](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Mochitest) to do functional (and possibly integration) testing. Mochitests are part of Firefox and allow us to test activity stream literally as you would use it.
+
+Mochitests require a local checkout of the Firefox source code. This is because they are used to test a lot of Firefox, and you would usually run them inside Firefox. We are developing activity stream outside of Firefox, but still want to test it as part of Firefox, so we've borrowed the debugger.html infrastructure for using them.
+
+Mochitests live in `system-addon/test/functional/mochitest`, and as of this writing, they are all the [`browser-chrome`](https://developer.mozilla.org/en-US/docs/Mozilla/Browser_chrome_tests) flavor of mochitests.  They currently only run against the bootstrapped version of the add-on in system-addon, not the test pilot version at the top level directory.
+
+## Getting Started
+
+**Requirements**
+
+* mercurial ( `brew install mercurial` )
+* autoconf213 ( `brew install autoconf@2.13 && brew unlink autoconf` )
+
+If you haven't set up the mochitest environment yet, just run this:
+
+```bash
+./bin/prepare-mochitests-dev
+```
+
+This will set up everything you need. You should run this *every time* you start working on mochitests, as it makes sure your local copy of Firefox is up-to-date.
+
+On the first run, if you don't already have a mozilla-central repo as a sibling of your activity stream repo, this will download one and set up an [artifact build](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Artifact_builds) (just think of a super fast Firefox build). It may take a while (10-15 minutes) to download and build Firefox.
+
+If you do already have a mozilla-central repo, the script ask you if you're ok with losing any local changes in that repo, and, if so, it will merely update to  the latest bits and then export your current activity-stream repo to that
+mozilla-central.
+
+Now, you can run the mochitests like this:
+
+```
+npm run buildmc
+npm run mochitest
+```
+
+The reason we use npm to run them is because, as of this writing, both the
+add-on and the tests are turned off in the export to mozilla-central, so special arguments are needed to turn them both on.
+
+Visit the [mochitest](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Mochitest) and [`browser chrome`](https://developer.mozilla.org/en-US/docs/Mozilla/Browser_chrome_tests) MDN pages to learn more about mochitests. A few tips:
+
+* Doing ```npm run mochitest-debug``` will open a JavaScript debugger and allow you to debug the tests (sometimes can be fickle)
+
+### For Windows Developers
+
+*NOT YET TESTED FOR ACTIVITY STREAM*: The detailed instructions for setting up your environment to build Firefox for Windows can be found [here](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Windows_Prerequisites). You need to install the latest `MozBuild` package. You can open a unix-flavor shell by starting:
+
+```
+C:\mozilla-build\start-shell.bat
+```
+
+In the shell, navigate to the activity-stream project folder, and follow the Getting Started instructions as mentioned.
+
+
+## Making code changes
+
+The mochitests are running against the compiled activity-stream bundle inside the Firefox checkout. This means that you need to update the bundle whenever you make code changes. `./bin/prepare-mochitests-dev` does this for you initially, but you can manually update it with:
+
+```
+npm run buildmc
+```
+
+
+or have it automatically be updated whenever it changes if you leave ```npm run startmc``` running in a shell.
+
+
+## Adding New Tests
+
+If you add new tests, make sure to list them in the `browser.ini` file. You will see the other tests there. Add a new entry with the same format as the others. You can also add new JS or HTML files by listing in under `support-files`. Make sure to start your test name with "browser_", so that the test suite knows the pick it up. E.g: "browser_as_my_new_test.js".
+
+## Writing Tests
+
+Here are a few tips for writing mochitests:
+
+* Only write mochitests for testing the interaction of multiple components on the page and to make sure that the protocol is working.
+* If you need to access the content page, use `ContentTask.spawn`:
+
+```js
+ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
+  content.wrappedJSObject.foo();
+});
+```
+
+The above calls the function `foo` that exists in the page itself. You can also access the DOM this way: `content.document.querySelector`, if you want to click a button or do other things. You can even you use assertions inside this callback to check DOM state.
+
+* If you run into problems running tests in e10s, refer to the [wiki](https://wiki.mozilla.org/Electrolysis/e10s_test_tips) for tips
+* Nobody likes to see intermittent oranges in their tests, so read the [docs on how to avoid them](https://developer.mozilla.org/en-US/docs/Mozilla/QA/Avoiding_intermittent_oranges)!
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/docs/v2-system-addon/preferences.md
@@ -0,0 +1,78 @@
+# Preferences in Activity Stream
+
+## Preference branch
+
+The preference branch for activity stream is `browser.newtabpage.activity-stream.`.
+Any preferences defined in the preference configuration will be relative to that
+branch. For example, if a preference is defined with the name `foo`, the full
+preference as it is displayed in `about:config` will be `browser.newtabpage.activity-stream.foo`.
+
+## Defining new preferences
+
+All preferences for Activity Stream should be defined in the `PREFS_CONFIG` Array
+found in [lib/ActivityStream.jsm](../../system-addon/lib/ActivityStream.jsm).
+The configuration object should have a `name` (the name of the pref), a `title`
+that describes the functionality of the pref, and a `value`, the default value
+of the pref. Optionally a `getValue` function can be provided to dynamically
+generate a default pref value based on args, e.g., geo and locale. For
+developers-specific defaults, an optional `value_local_dev` will be used instead
+of `value`. For example:
+
+```js
+{
+  name: "telemetry.log",
+  title: "Log telemetry events in the console",
+  value: false,
+  value_local_dev: true,
+  getValue: ({geo}) => geo === "CA"
+}
+```
+
+### IMPORTANT: Setting test-specific values for Mozilla Central
+
+If a feed or feature behind a pref makes any network calls or would other be
+disruptive for automated tests and that pref is on by default, make sure you
+disable it for tests in Mozilla Central.
+
+You should create a bug in Bugzilla and a patch that adds lines to turn off your
+pref in the following files:
+- layout/tools/reftest/reftest-preferences.js
+- testing/profiles/prefs_general.js
+- testing/talos/talos/config.py
+
+You can see an example in [this patch](https://github.com/mozilla/activity-stream/pull/2977).
+
+## Reading, setting, and observing preferences from `.jsm`s
+
+To read/set/observe Activity Stream preferences, construct a `Prefs` instance found in [lib/ActivityStreamPrefs.jsm](../../system-addon/lib/ActivityStreamPrefs.jsm).
+
+```js
+// Import Prefs
+XPCOMUtils.defineLazyModuleGetter(this, "Prefs",
+  "resource://activity-stream/lib/ActivityStreamPrefs.jsm");
+
+// Create an instance
+const prefs = new Prefs();
+```
+
+The `Prefs` utility will set the Activity Stream branch for you by default, so you
+don't need to worry about prefixing every pref with `browser.newtabpage.activity-stream.`:
+
+```js
+const prefs = new Prefs();
+
+// This will return the value of browser.newtabpage.activity-stream.foo
+prefs.get("foo");
+
+// This will set the value of browser.newtabpage.activity-stream.foo to true
+prefs.set("foo", true)
+
+// This will call aCallback when browser.newtabpage.activity-stream.foo is changed
+prefs.observe("foo", aCallback);
+
+// This will stop listening to browser.newtabpage.activity-stream.foo
+prefs.ignore("foo", aCallback);
+```
+
+See [toolkit/modules/Preferences.jsm](https://dxr.mozilla.org/mozilla-central/source/toolkit/modules/Preferences.jsm)
+for more information about what methods are available.
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/docs/v2-system-addon/sections.md
@@ -0,0 +1,71 @@
+# Sections in Activity Stream
+
+Each section in Activity Stream displays data from a corresponding section feed
+in a standardised `Section` UI component. Each section feed is responsible for
+listening to events and updating the section options such as the title, icon,
+and rows (the cards for the section to display).
+
+The `Section` UI component displays the rows provided by the section feed. If no
+rows are available it displays an empty state consisting of an icon and a
+message. Optionally, the section may have a info option menu that is displayed
+when users hover over the info icon.
+
+On load, `SectionsManager` and `SectionsFeed` in `SectionsManager.jsm` add the
+sections configured in the `BUILT_IN_SECTIONS` map to the state. These sections
+are initially disabled, so aren't visible. The section's feed may use the
+methods provided by the `SectionsManager` to enable its section and update its
+properties.
+
+The section configuration in `BUILT_IN_SECTIONS` consists of a generator
+function keyed by the pref name for the section feed. The generator function
+takes an `options` argument as the only parameter, which is passed the object
+stored as serialised JSON in the pref `{feed_pref_name}.options`, or the empty
+object if this doesn't exist. The generator returns a section configuration
+object which may have the following properties:
+
+Property | Type | Description
+--- | --- | ---
+id | String | Non-optional unique id.
+title | Localisation object | Has property `id`, the string localisation id, and optionally a `values` object to fill in placeholders.
+icon | String | Icon id. New icons should be added in icons.scss.
+maxRows | Integer | Maximum number of rows of cards to display. Should be >= 1.
+contextMenuOptions | Array of strings | The menu options to provide in the card context menus.
+shouldHidePref | Boolean | If true, will the section preference in the preferences pane will not be shown.
+pref | Object | Configures the section preference to show in the preferences pane. Has properties `titleString` and `descString`.
+emptyState | Object | Configures the empty state of the section. Has properties `message` and `icon`.
+
+## Section feeds
+
+Each section feed should be controlled by the pref `feeds.section.{section_id}`.
+
+### Enabling the section
+
+The section feed must listen for the events `INIT` (dispatched when Activity
+Stream is initialised) and `FEED_INIT` (dispatched when a feed is re-enabled
+having been turned off, with the feed id as the `data`). On these events it must
+call `SectionsManager.enableSection(id)`. Care should be taken that this happens
+only once `SectionsManager` has also initialised; the feed can use the method
+`SectionsManager.onceInitialized()`.
+
+### Disabling the section
+
+The section feed must have an `uninit` method. This is called when the section
+feed is disabled by turning the section's pref off. In `uninit` the feed must
+call `SectionsManager.disableSection(id)`. This will remove the section's UI
+component from every existing Activity Stream page.
+
+### Updating the section rows
+
+The section feed can call `SectionsManager.updateSection(id, options)` to update
+section options. The `rows` array property of `options` stores the cards of
+sites to display. Each card object may have the following properties:
+
+```js
+{
+  type, // One of the types in Card/types.js, e.g. "Trending"
+  title, // Title string
+  description, // Description string
+  image, // Image url
+  url // Site url
+}
+```
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/docs/v2-system-addon/snippets.md
@@ -0,0 +1,125 @@
+# Snippets in ActivityStream
+
+## `gSnippetsMap`
+
+`gSnippetsMap` is available to all snippet templates and has methods that a
+regular `Map` has: `set`, `get`, `delete`, `clear`, etc.
+
+If you don't care about the completion of the transaction, you may simply use these
+methods synchronously:
+
+```js
+function setFoo() {
+  gSnippetsMap.set("foo", 123);
+  return gSnippetsMap.get("foo"); // returns 123
+}
+```
+
+However, unlike the previous version of snippets, `set`, `delete`, and `clear`
+all return a `Promise` that will resolve or reject when the `indexedDB` transaction
+is complete. For example:
+
+```js
+async function setFoo() {
+  await gSnippetsMap.set("foo", 123);
+  return gSnippetsMap.get("foo");
+}
+```
+
+### Methods on gSnippetsMap
+
+`.blockList`: (Array) An array of snippet IDs that have been blocked by the users, or an empty array if none have been blocked.
+
+`.blockSnippetById(id)`: (func) A function that adds an id to a blockList and returns
+a Promise that resolves when the blockList has been written to indexedDB.
+
+`.showFirefoxAccounts()`: (func) A function that opens the Firefox Accounts signup page
+(specifically `about:accounts?action=signup&entrypoint=snippets`)
+
+`.disableOnboarding()`: (func) A function that disables onboarding for future new tabs (until Firefox restarts).
+You should ensure `gSnippetsMap.get("appData.onboardingFinished")` is false before calling this. Note that this
+does not hide onboarding notifications on the **current** page, since that would be a disruptive user experience.
+
+`.getTotalBookmarksCount()`: (func) An async function that resolves with an integer representing the number of
+bookmarks a user has (including default bookmarks). Note that is value is only updated once per day or when a
+a user restarts the browser.
+
+`.getAddonsInfo()`:( func) An async function that resolves with an object `{isFullData: (bool), addons: (obj)}`.
+Note that at startup, we are sometimes unable to provide full data due to performance constraits (`.isFullData` will be `false`).
+E.g.
+
+```js
+{
+  isFullData: true,
+  addons: {
+      // This is the ID of the addon
+    "someaddon@mozilla.org": {
+      type: "extension",
+      isSystem: false,
+      isWebExtension: true,
+      version: "29.0.0"
+
+      // The following properties may not be available when the browser starts up
+      name: "Firefox Screenshots",
+      userDisabled: false,
+      installDate: Date 2018-02-27T19:33:33.440Z,
+    }
+  }
+}
+```
+
+### Expected values in gSnippetsMap
+
+Note that names and functionality of values in v4 snippets have been preserved
+where possible. You can access each value by calling `gSnippetsMap.get(id)`. For example,
+to find out if a user has a Firefox account, you would check `gSnippetsMap.get("appData.fxaccount")`.
+
+`snippets-cached-version`: (int) The version number of the snippets cached in `snippets`.
+
+`snippets-last-update`: (int) The last time snippets were updated.
+
+`snippets`: (str) The cached payload of the response from the snippets server.
+
+`appData.snippetsURL`: (str) The URL at from which snippets are fetched
+
+`appData.version`: (int) The current version of snippets
+
+`appData.profileCreatedWeeksAgo`: (int) The date the user's profile was created
+
+`appData.profileResetWeeksAgo`: (int) The date the user's profile was reset. `null` if the profile hasn't been reset.
+
+`appData.telemetryEnabled`: (bool) Is telemetry enabled for the user?
+
+`appData.onboardingFinished`: (bool) Has the onboarding tour been completed?
+
+`appData.fxaccount`: (bool) Does the user have a Firefox account?
+
+`appData.selectedSearchEngine`: (obj) An object containing a array of search
+engines and a search engine identifier for the currently selected search engine.
+For example:
+
+```js
+{
+  engines: ["searchEngine-google", "searchEngine-yahoo", "searchEngine-bing"],
+  searchEngineIdentifier : "google"
+}
+```
+
+`appData.defaultBrowser`: (bool) Is Firefox the user's default browser?
+If we could not determine the default browser, this value is `null`. Note that
+currently this value is only checked once when the browser is initialized.
+
+`appData.isDevtoolsUser`: (bool) Has the user ever used devtools?
+
+## Events
+
+ActivityStream dispatches custom DOM events on the window to allow snippets
+providers to respond to ActivityStream snippets events.
+
+### `Snippets:Enabled`
+
+Fired when the user chooses to enable snippets.
+
+### `Snippets:Disabled`
+
+Fired when the user chooses to disable snippets.
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/docs/v2-system-addon/telemetry.md
@@ -0,0 +1,19 @@
+# Adding/Changing Telemetry Checklist
+
+Adding telemetry generally involves a few steps:
+
+1. - [ ] File a "user story issue" [in ping-centre](https://github.com/mozilla/ping-centre) about who wants what question answered.  This will be used to track server-side data handling implementation (ETL, dashboard implementation...).
+
+    > As an engineer, I see the distribution of times between triggering a new tab load by tab menu entry, plus button or keyboard shortcut and when the visibility event is fired on that page, so that I can understand how long it takes before the page becomes visible and how close to instantaneous that feels.
+
+1. - [ ] File or update your existing client-side implementation bug so that it points to the "user story issue".
+1. - [ ] Talk to Marina (@emtwo) about the dashboard you're hoping to see from the data you're adding, and work with her to create a data model (or request her review on it after the fact).
+1. - [ ] Update `system-addon/test/schemas/pings.js` with a commented JOI schema of your changes, and add tests to system-addon/test/unit/TelemetryFeed.test.js to exercise the ping creation.
+1. - [ ] Update [data_events.md](data_events.md) with an example of the data in question
+1. - [ ] Update any fields that you've added, deleted, or changed in [data_dictionary.md](data_dictionary.md)
+1. - [ ] Get review from Nan (@ncloudioj) and/or Marina (@emtwo) on the data schema and the documentation changes.
+1. - [ ] Request `data-review` of your documentation changes from a [data steward](https://wiki.mozilla.org/Firefox/Data_Collection) to ensure suitability for collection controlled by the opt-out `datareporting.healthreport.uploadEnabled` pref. Download and fill out the [data review request form](https://github.com/mozilla/data-review/blob/master/request.md) and then attach it as a text file on Bugzilla so you can r? a data steward. We've been working with François Marier (:francois / @fmarier), so he's a good candidate as he's likely to have the most context.
+1. - [ ] Implement as usual...
+1. - [ ] After landing the implementation, check with Nan (@ncloudioj) to make sure the pings are making it to the database
+1. - [ ] Update the [ping-centre](https://github.com/mozilla/ping-centre/issues) user story issue for the dashboard, stating that the data should now be available for implementation, and removing any `blocked` tag if appropriate.
+
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/docs/v2-system-addon/test-merges.md
@@ -0,0 +1,26 @@
+## bin/test-merges.js documentation
+
+A script intended to be run from cron regularly.  It notices when a new PR has been merged to github, and then exports the code to a copy of mozilla-central and pushes it to pine, so that all the tests can be run.  It annotates the PR with the link to treeherder with the test results.
+
+Setup, needs to happen before first run:
+
+Ensure that mozilla/activity-stream has a label called pushed-to-pine.
+
+```bash
+# mkdir /home/monkey/as-pine-testing
+# cd /home/monkey/as-pine-testing
+# git clone https://github.com/mozilla/activity-stream.git
+# npm install
+```
+
+Example usage:
+
+```bash
+AS_PINE_TOKEN=01234567890 \
+AS_PINE_TEST_DIR=/home/monkey/as-pine-testing \
+node bin/test-merges.js
+```
+
+AS_PINE_TOKEN is a github token for accessing mozilla/activity-stream. We use a token from the github user that has access to the mozilla/activity-stream repo (in order to label issues), and nothing else.
+
+AS_PINE_TEST_DIR should be a single directory which will contain local copies of both the activity-stream github repo and mozilla-central.  It's highly advised that AS_PINE_TEST_DIR be used for nothing else, to avoid accidentally clobbering real work.
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/docs/v2-system-addon/unit_testing_guide.md
@@ -0,0 +1,153 @@
+# Unit testing in Activity Stream
+
+## Overview
+
+Our unit tests in Activity Stream are written with mocha, chai, and sinon, and run
+with karma. They include unit tests for both content code (React components, etc.)
+and `.jsm`s.
+
+You can find unit tests in `system-addon/tests/unit`.
+
+## Running tests
+
+To run the unit tests once, run `npm run testmc`.
+
+To run unit tests continuously (i.e. in "test-driven development" mode), you can
+run `npm run tddmc`.
+
+## Debugging tests
+
+To debug tests, you should run them in continous mode with `npm run tddmc`. In the
+Firefox window that is opened (it should say "Karma... - connected"), click the
+"debug" button and open your console to see test output, set breakpoints, etc.
+
+Unfortunately, source maps for tests do not currently work in Firefox. If you need
+to see line numbers, you can run the tests with Chrome by running
+`npm run tddmc -- --browsers Chrome`
+
+## Where to put new tests
+
+If you are creating a new test, add it to a subdirectory of the `system-addon/tests/unit`
+that corresponds to the file you are testing. Tests should end with `.test.js` or
+`.test.jsx` if the test includes any jsx.
+
+For example, if the file you are testing is `system-addon/lib/Foo.jsm`, the test
+file should be `system-addon/test/unit/lib/Foo.test.js`
+
+## Mocha tests
+
+All our unit tests are written with [mocha](https://mochajs.org), which injects
+globals like `describe`, `it`, `beforeEach`, and others. It can be used to write
+synchronous or asynchronous tests:
+
+```js
+describe("FooModule", () => {
+  // A synchronous test
+  it("should create an instance", () => {
+    assert.instanceOf(new FooModule(), FooModule);
+  });
+  describe("#meaningOfLife", () => {
+    // An asynchronous test
+    it("should eventually get the meaning of life", async () => {
+      const foo = new FooModule();
+      const result = await foo.meaningOfLife();
+      assert.equal(result, 42);
+    });
+  });
+});
+```
+
+## Assertions
+
+To write assertions, use the globally available `assert` object (this is provided
+by karma-chai, so you do not need to `require` it).
+
+For example:
+
+```js
+assert.equal(foo, 3);
+assert.propertyVal(someObj, "foo", 3);
+assert.calledOnce(someStub);
+```
+
+You can use any of the assertions from:
+
+- [`chai`](http://chaijs.com/api/assert/).
+- [`sinon-chai`](https://github.com/domenic/sinon-chai#assertions)
+
+### Custom assertions
+
+We have some custom assertions for checking various types of actions:
+
+#### `.isUserEventAction(action)`
+
+Asserts that a given `action` is a valid User Event, i.e. that it contains only
+expected/valid properties for User Events in Activity Stream.
+
+```js
+// This will pass
+assert.isUserEventAction(ac.UserEvent({event: "CLICK"}));
+
+// This will fail
+assert.isUserEventAction({type: "FOO"});
+
+// This will fail because BLOOP is not a valid event type
+assert.isUserEventAction(ac.UserEvent({event: "BLOOP"}));
+```
+
+## Overriding globals in `.jsm`s
+
+Most `.jsm`s you will be testing use `Cu.import` or `XPCOMUtils` to inject globals.
+In order to add mocks/stubs/fakes for these globals, you should use the `GlobalOverrider`
+utility in `system-addon/test/unit/utils`:
+
+```js
+const {GlobalOverrider} = require("test/unit/utils");
+describe("MyModule", () => {
+  let globals;
+  let sandbox;
+  beforeEach(() => {
+    globals = new GlobalOverrider();
+    sandbox = globals.sandbox; // this is a sinon sandbox
+    // This will inject a "AboutNewTab" global before each test
+    globals.set("AboutNewTab", {override: sandbox.stub()});
+  });
+  // globals.restore() clears any globals you added as well as the sinon sandbox
+  afterEach(() => globals.restore());
+});
+```
+
+## Testing React components
+
+You should use the [enzyme](https://github.com/airbnb/enzyme) suite of test utilities
+to test React Components for Activity Stream.
+
+Where possible, use the [shallow rendering method](https://github.com/airbnb/enzyme/blob/master/docs/api/shallow.md) (this will avoid unnecessarily
+rendering child components):
+
+```js
+const React = require("react");
+const {shallow} = require("enzyme");
+
+describe("<Foo>", () => {
+  it("should be hidden by default", () => {
+    const wrapper = shallow(<Foo />);
+    assert.isTrue(wrapper.find(".wrapper").props().hidden);
+  });
+});
+```
+
+If you need to, you can also do [Full DOM rendering](https://github.com/airbnb/enzyme/blob/master/docs/api/mount.md)
+with enzyme's `mount` utility.
+
+```js
+const React = require("react");
+const {mount} = require("enzyme");
+...
+const wrapper = mount(<Foo />);
+```
+
+### Rendering localized components
+
+If you need to render a component that contains localized components, use the
+`shallowWithIntl` and `mountWithIntl` functions in `system-addon/test/unit/utils`.
--- a/browser/extensions/activity-stream/install.rdf.in
+++ b/browser/extensions/activity-stream/install.rdf.in
@@ -3,17 +3,17 @@
 #filter substitution
 
 <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
   <Description about="urn:mozilla:install-manifest">
     <em:id>activity-stream@mozilla.org</em:id>
     <em:type>2</em:type>
     <em:bootstrap>true</em:bootstrap>
     <em:unpack>false</em:unpack>
-    <em:version>2018.06.06.1137-f6f92043</em:version>
+    <em:version>2018.06.06.1255-7e544945</em:version>
     <em:name>Activity Stream</em:name>
     <em:description>A rich visual history feed and a reimagined home page make it easier than ever to find exactly what you're looking for in Firefox.</em:description>
     <em:multiprocessCompatible>true</em:multiprocessCompatible>
 
     <em:targetApplication>
       <Description>
         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
         <em:minVersion>@MOZ_APP_VERSION@</em:minVersion>
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/karma.mc.config.js
@@ -0,0 +1,149 @@
+const path = require("path");
+
+const PATHS = {
+  // Where is the entry point for the unit tests?
+  testEntryFile: path.resolve(__dirname, "test/unit/unit-entry.js"),
+
+  // A glob-style pattern matching all unit tests
+  testFilesPattern: "test/unit/**/*.js",
+
+  // The base directory of all source files (used for path resolution in webpack importing)
+  moduleResolveDirectory: __dirname,
+
+  // a RegEx matching all Cu.import statements of local files
+  resourcePathRegEx: /^resource:\/\/activity-stream\//,
+
+  coverageReportingPath: "logs/coverage/"
+};
+
+// When tweaking here, be sure to review the docs about the execution ordering
+// semantics of the preprocessors array, as they are somewhat odd.
+const preprocessors = {};
+preprocessors[PATHS.testFilesPattern] = [
+  "webpack", // require("karma-webpack")
+  "sourcemap" // require("karma-sourcemap-loader")
+];
+
+module.exports = function(config) {
+  const isTDD = config.tdd;
+  const browsers = isTDD ? ["Firefox"] : ["FirefoxHeadless"]; // require("karma-firefox-launcher")
+  config.set({
+    singleRun: !isTDD,
+    browsers,
+    customLaunchers: {
+      FirefoxHeadless: {
+        base: "Firefox",
+        flags: ["--headless"]
+      }
+    },
+    frameworks: [
+      "chai", // require("chai") require("karma-chai")
+      "mocha", // require("mocha") require("karma-mocha")
+      "sinon" // require("sinon") require("karma-sinon")
+    ],
+    reporters: [
+      "coverage", // require("karma-coverage")
+      "mocha" // require("karma-mocha-reporter")
+    ],
+    coverageReporter: {
+      dir: PATHS.coverageReportingPath,
+      // This will make karma fail if coverage reporting is less than the minimums here
+      check: !isTDD && {
+        global: {
+          statements: 100,
+          lines: 100,
+          functions: 100,
+          branches: 90
+        }
+      },
+      reporters: [
+        {type: "html", subdir: "report-html"},
+        {type: "text", subdir: ".", file: "text.txt"},
+        {type: "text-summary", subdir: ".", file: "text-summary.txt"}
+      ]
+    },
+    files: [PATHS.testEntryFile],
+    preprocessors,
+    webpack: {
+      devtool: "inline-source-map",
+      // This loader allows us to override required files in tests
+      resolveLoader: {alias: {inject: path.join(__dirname, "loaders/inject-loader")}},
+      // This resolve config allows us to import with paths relative to the root directory, e.g. "lib/ActivityStream.jsm"
+      resolve: {
+        extensions: [".js", ".jsx"],
+        modules: [
+          PATHS.moduleResolveDirectory,
+          "node_modules"
+        ]
+      },
+      externals: {
+        // enzyme needs these for backwards compatibility with 0.13.
+        // see https://github.com/airbnb/enzyme/blob/master/docs/guides/webpack.md#using-enzyme-with-webpack
+        "react/addons": true,
+        "react/lib/ReactContext": true,
+        "react/lib/ExecutionEnvironment": true
+      },
+      module: {
+        rules: [
+          // This rule rewrites importing/exporting in .jsm files to be compatible with esmodules
+          {
+            test: /\.jsm$/,
+            exclude: [/node_modules/],
+            use: [{
+              loader: "babel-loader", // require("babel-core")
+              options: {
+                plugins: [
+                  // Converts .jsm files into common-js modules
+                  ["jsm-to-commonjs", {basePath: PATHS.resourcePathRegEx, replace: true}], // require("babel-plugin-jsm-to-commonjs")
+                  ["transform-async-to-module-method", {module: "co-task", method: "async"}], // require("babel-plugin-transform-async-to-module-method")
+                  "transform-es2015-modules-commonjs", // require("babel-plugin-transform-es2015-modules-commonjs")
+                  ["transform-object-rest-spread", {"useBuiltIns": true}] // require("babel-plugin-transform-object-rest-spread")
+                ]
+              }
+            }]
+          },
+          {
+            test: /\.js$/,
+            exclude: [/node_modules/, /test/],
+            use: [{
+              loader: "babel-loader",
+              options: {
+                plugins: [
+                  ["transform-async-to-module-method", {module: "co-task", method: "async"}],
+                  "transform-es2015-modules-commonjs",
+                  ["transform-object-rest-spread", {"useBuiltIns": true}]
+                ]
+              }
+            }]
+          },
+          {
+            test: /\.jsx$/,
+            exclude: /node_modules/,
+            loader: "babel-loader",
+            options: {
+              presets: ["react"], // require("babel-preset-react")
+              plugins: [["transform-object-rest-spread", {"useBuiltIns": true}]]
+            }
+          },
+          {
+            enforce: "post",
+            test: /\.jsm?$/,
+            loader: "istanbul-instrumenter-loader",
+            include: [
+              path.resolve("content-src"),
+              path.resolve("lib"),
+              path.resolve("common")
+            ],
+            exclude: [
+              path.resolve("test"),
+              path.resolve("vendor"),
+              path.resolve("lib/ASRouterTargeting.jsm")
+            ]
+          }
+        ]
+      }
+    },
+    // Silences some overly-verbose logging of individual module builds
+    webpackMiddleware: {noInfo: true}
+  });
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/loaders/inject-loader.js
@@ -0,0 +1,46 @@
+// Note: this is based on https://github.com/plasticine/inject-loader,
+// patched to make istanbul work properly
+
+const loaderUtils = require("loader-utils");
+const QUOTE_REGEX_STRING = "['|\"]{1}";
+
+const hasOnlyExcludeFlags = query => Object.keys(query).filter(key => query[key] === true).length === 0;
+const escapePath = path => path.replace("/", "\\/");
+
+function createRequireStringRegex(query) {
+  const regexArray = [];
+
+  // if there is no query then replace everything
+  if (Object.keys(query).length === 0) {
+    regexArray.push("([^\\)]+)");
+  } else if (hasOnlyExcludeFlags(query)) {
+  // if there are only negation matches in the query then replace everything
+  // except them
+    Object.keys(query).forEach(key => regexArray.push(`(?!${QUOTE_REGEX_STRING}${escapePath(key)})`));
+    regexArray.push("([^\\)]+)");
+  } else {
+    regexArray.push(`(${QUOTE_REGEX_STRING}(`);
+    regexArray.push(Object.keys(query).map(key => escapePath(key)).join("|"));
+    regexArray.push(`)${QUOTE_REGEX_STRING})`);
+  }
+
+  // Wrap the regex to match `require()`
+  regexArray.unshift("require\\(");
+  regexArray.push("\\)");
+
+  return new RegExp(regexArray.join(""), "g");
+}
+
+module.exports = function inject(src) {
+  if (this.cacheable) {
+    this.cacheable();
+  }
+  const regex = createRequireStringRegex(loaderUtils.parseQuery(this.query));
+
+  return `module.exports = function inject(injections) {
+  var module = {exports: {}};
+  var exports = module.exports;
+  ${src.replace(regex, "(injections[$1] || /* istanbul ignore next */ $&)")}
+  return module.exports;
+}\n`;
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ach/strings.properties
@@ -0,0 +1,175 @@
+newtab_page_title=Dirica matidi manyen
+
+header_top_sites=Kakube maloyo
+header_highlights=Wiye madito
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Lami tam obedo {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Yab jami ayera pi {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Kilimo
+type_label_bookmarked=Kiketo alamabuk
+type_label_recommended=Ma cuke lamal
+type_label_pocket=Kigwoko i Pocket
+type_label_downloaded=Ki gamo
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Alamabuk
+menu_action_remove_bookmark=Kwany alamabuk
+menu_action_open_new_window=Yab i dirica manyen
+menu_action_open_private_window=Yab i dirica manyen me mung
+menu_action_dismiss=Kwer
+menu_action_delete=Kwany ki ii gin mukato
+menu_action_pin=Mwon
+menu_action_unpin=War
+confirm_history_delete_p1=Imoko ni imito kwanyo nyig jami weng me potbuk man ki i gin mukato mamegi?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Pe ki twero gonyo tic man.
+menu_action_save_to_pocket=Gwoki i jaba
+menu_action_delete_pocket=Kwany ki ii Pocket
+menu_action_archive_pocket=Kan i Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Nyut i Gin nongo
+menu_action_show_file_windows=Yab boc manonge iyie
+menu_action_show_file_linux=Yab boc manonge iyie
+menu_action_show_file_default=Nyut Pwail
+menu_action_open_file=Yab Pwail
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Lok Kakube me Gam
+menu_action_go_to_download_page=Cit i Potbuk me Gam
+menu_action_remove_download=Kwany ki i Gin mukato
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Yeny
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Yeny me {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Yeny kakube
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Lok ma mit loyo i kakube, ki yero malube ki ngo ma ikwano. Ki ii Pocket, kombedi dong but Mozilla.
+section_disclaimer_topstories_linktext=Nong ngec kit ma tyo kwede.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Eyo, aniang
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Jami me Acakki Firefox
+prefs_home_description=Yer jami ma imito ii kio me Acakki Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_search_header=Yeny me kakube
+prefs_topsites_description=Kakube ma ilimo loyo
+prefs_topstories_description2=Jami mabeco loyo ki ii kakube, kiyubo piri
+prefs_topstories_options_sponsored_label=Lok ma kicwako
+prefs_topstories_sponsored_learn_more=Nong ngec mapol
+prefs_highlights_description=Yer me kakube ma igwoko nyo ilimo
+prefs_highlights_options_visited_label=Potbuk ma kilimo
+prefs_highlights_options_download_label=Gam ma cokcoki loyo
+prefs_highlights_options_pocket_label=Kigwoko potbuk i Pocket
+prefs_snippets_description=Ngec manyen ki bot Mozilla ki Firefox
+settings_pane_button_label=Yub potbuk me dirica matidi mamegi manyen
+settings_pane_topsites_header=Kakube ma gi loyo
+settings_pane_highlights_header=Wiye madito
+settings_pane_highlights_options_bookmarks=Alamabuk
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Kwena macek
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Yubi
+edit_topsites_edit_button=Yub kakube man
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Kakube maloyo manyen
+topsites_form_edit_header=Yub Kakube maloyo
+topsites_form_title_label=Wiye madit
+topsites_form_title_placeholder=Ket wiye
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL me cal ma kiyubo
+topsites_form_url_placeholder=Coo onyo mwon URL
+topsites_form_use_image_link=Tii ki cal ma kiyubo…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Nen
+topsites_form_add_button=Medi
+topsites_form_save_button=Gwoki
+topsites_form_cancel_button=Kwer
+topsites_form_url_validation=URL ma tye atir mite
+topsites_form_image_validation=Cano cal pe olare. Tem URL mukene.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Lok macuk gi lamal:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Nen Lok mapol
+
+highlights_empty_state=Cak yeny, ka wa binyuto coc akwana mabeco, video, ki potbuk mukene ma ilimo cokcokki onyo ma kiketo alamabuk kany.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Ityeko weng. Rot doki lacen pi lok madito mapol ki bot {provider}. Pe itwero kuro? Yer lok macuke lamal me nongo lok mabeco mapol ki i but kakube.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Tem Firefox ki alamabuk, gin mukato ki mung me donyo ki ii layeny mukene.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Pe Apwoyo
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Kel kombedi
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Aii, gin mo otime marac i cano jami man.
+error_fallback_default_refresh_suggestion=Nwo cano potbuk me temo odoco.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Kwany bute
+section_menu_action_collapse_section=Kan bute
+section_menu_action_expand_section=Yar bute
+section_menu_action_manage_section=Lo bute
+section_menu_action_add_topsite=Med Kakube maloyo
+section_menu_action_move_up=Kob Malo
+section_menu_action_move_down=Kob Piny
+section_menu_action_privacy_notice=Ngec me mung
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/an/strings.properties
@@ -0,0 +1,173 @@
+newtab_page_title=Nueva Pestanya
+
+header_top_sites=Mas freqüents
+header_highlights=Destacaus
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recomendau per {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Ubrir menú contextual pa {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Ubrir lo menú contextual d'a sección
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Vesitau
+type_label_bookmarked=Con marcapachinas
+type_label_recommended=Tendencia
+type_label_pocket=Alzau en Pocket
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Anyadir marcapachinas
+menu_action_remove_bookmark=Sacar lo marcapachinas
+menu_action_open_new_window=Ubrir en una nueva finestra
+menu_action_open_private_window=Ubrir en una nueva finestra privada
+menu_action_dismiss=Descartar
+menu_action_delete=Eliminar de l'historial
+menu_action_pin=Clavar
+menu_action_unpin=Desclavar
+confirm_history_delete_p1=Yes seguro que quiers borrar totas las instancias d'esta pachina en o tuyo historial?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Esta acción no se puede desfer.
+menu_action_save_to_pocket=Alzar en Pocket
+menu_action_delete_pocket=Borrar de Pocket
+menu_action_archive_pocket=Archivar en Pocket
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Mirar
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Mirar con {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Mirar en o Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Los articlos mas interesants d'o web, triaus en función d'o que gosas leyer. Gracias a lo Pocket, que agora ya fa parte de Mozilla.
+section_disclaimer_topstories_linktext=Aprende cómo funciona
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Entendiu
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Conteniu d'inicio de Firefox
+prefs_home_description=Tría qué contenisu quiers veyer en a tuya pachina d'inicio de Firefox.
+prefs_restore_defaults_button=Restaurar valors per defecto
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} ringlera;{num} ringleras
+prefs_search_header=Busqueda web
+prefs_topsites_description=Los puestos que mas vesitas
+prefs_topstories_description=Contenius d'alta calidat que no te quiers perder
+# LOCALIZATION NOTE (prefs_topstories_show_sponsored_label): {provider} is
+# replaced by the name of the content provider for this section, e.g., "Pocket"
+prefs_topstories_show_sponsored_label=Articlos patrocinaus per {provider}
+prefs_topstories_sponsored_learn_more=Saber-ne mas
+prefs_highlights_description=Una tría d'os puestos que has alzau u vesitau
+prefs_snippets_description=Actualizacions de Mozilla y Firefox
+settings_pane_button_label=Personaliza la tuya pachina de Nueva Pestanya
+settings_pane_header=Preferencias de Nueva Pestanya
+settings_pane_body2=Tría lo que veyes en esta pachina.
+settings_pane_search_header=Mirar
+settings_pane_search_body=Mirar la Web dende la tuya nueva pestanya.
+settings_pane_topsites_header=Puestos mas vesitaus
+settings_pane_topsites_body=Accede a los puestos web que mas vesitas.
+settings_pane_topsites_options_showmore=Amostrar dos ringleras
+settings_pane_highlights_header=Destacaus
+settings_pane_highlights_body2=Torna a trobar lo mas interesant que has vesitau en zagueras, u que has marcau con marcapchinas.
+settings_pane_highlights_options_bookmarks=Marcapachinas
+settings_pane_highlights_options_visited=Puestos vesitaus
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Retallos
+settings_pane_snippets_body=leye noticias curtas de Mozilla sobre lo Firefox, la cultura d'internet y, de cabo ta quan, bell meme.
+settings_pane_done_button=Feito
+settings_pane_topstories_options_sponsored=Amostrar articlos patrocinaus
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Editar
+edit_topsites_edit_button=Editar este puesto
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nuevo puesto popular
+topsites_form_edit_header=Editar lo puesto popular
+topsites_form_title_label=Titol
+topsites_form_title_placeholder=Escribir un titol
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL d'imachen personalizada
+topsites_form_url_placeholder=Triar u apegar una adreza web
+topsites_form_use_image_link=Usar una imachen personalizada…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Previsualizar
+topsites_form_add_button=Anyadir
+topsites_form_save_button=Alzar
+topsites_form_cancel_button=Cancelar
+topsites_form_url_validation=Fa falta una URL valida
+topsites_form_image_validation=Ha fallau la carga d'a imachen. Preba con una URL diferent.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Temas populars:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Amostrar mas articlos
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=Descubre gracias a Pocket, que dende agora fa parte de Mozilla, contenius d'alta calidat que d'atra manera te puetz perder.
+
+highlights_empty_state=Empecipia a navegar, y t'iremos amostrando aquí grans articlos, videos y atras pachinas que has vesitau u marcau en zagueras.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Ya ye tot per agora. Torna mas ta debant pa veyer mas articlos populars de {provider}. No i puetz aguardar? Tría un tema popular pa descubrir los articlos mas interesants de tot lo web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Preba lo Firefox con as adrezas d'interés, l'historial y las claus de belatro navegador.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=No, gracias
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importar-lo agora
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Oi, ha fallau bella cosa en a carga d'este conteniu.
+error_fallback_default_refresh_suggestion=Refrescar la pachina pa tornar-lo a intentar.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Borrar la sección
+section_menu_action_collapse_section=Plegar la sección
+section_menu_action_expand_section=Desplegar la sección
+section_menu_action_manage_section=Chestionar la sección
+section_menu_action_add_topsite=Anyadir un puesto popular
+section_menu_action_move_up=Puyar
+section_menu_action_move_down=Baixar
+section_menu_action_privacy_notice=Nota sobre privacidat
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ar/strings.properties
@@ -0,0 +1,177 @@
+newtab_page_title=لسان جديد
+
+header_top_sites=المواقع الأكثر زيارة
+header_highlights=أهم الأحداث
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=ينصح به {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=افتح قائمة {title} السياقية
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=افتح قائمة القسم السياقية
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=مُزارة
+type_label_bookmarked=معلّمة
+type_label_recommended=مُتداول
+type_label_pocket=حُفِظت في بوكِت
+type_label_downloaded=نُزّل
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=علّم
+menu_action_remove_bookmark=أزل العلامة
+menu_action_open_new_window=افتح في نافذة جديدة
+menu_action_open_private_window=افتح في نافذة خاصة جديدة
+menu_action_dismiss=ألغِ
+menu_action_delete=احذف من التأريخ
+menu_action_pin=ثبّت
+menu_action_unpin=أزل
+confirm_history_delete_p1=هل أنت متأكد أنك تريد حذف كل وجود لهذه الصفحة من تأريخك؟
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=لا يمكن التراجع عن هذا الإجراء.
+menu_action_save_to_pocket=احفظ في Pocket
+menu_action_delete_pocket=احذف من بوكِت
+menu_action_archive_pocket=أرشِف في بوكِت
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=أظهِر في فايندر
+menu_action_show_file_windows=افتح المجلد المحتوي
+menu_action_show_file_linux=افتح المجلد المحتوي
+menu_action_show_file_default=أظهِر الملف
+menu_action_open_file=افتح الملف
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=انسخ رابط التنزيل
+menu_action_go_to_download_page=انتقل إلى صفحة التنزيل
+menu_action_remove_download=احذف من التأريخ
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=ابحث
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=بحث {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=ابحث في الوِب
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=أكثر القصص تشويقًا على الإنترنت، مختارة بعناية بناء على ما تقرأه. من بوكِت، و الذي أصبح جزءًا من موزيلا.
+section_disclaimer_topstories_linktext=اطلع على طريقة عملها.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=حسنًا، فهمت
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=محتوى فَيَرفُكس الرئيسي
+prefs_home_description=اختر المحتوى الذي تريد عرضه في شاشة فَيَرفُكس الرئيسية.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option=صف واحد;صفان;{num} صفوف;{num} صفا;{num} صف;لا صفوف
+prefs_search_header=ابحث في الوِب
+prefs_topsites_description=أكثر المواقع المزارة
+prefs_topstories_description2=محتوى مميز من أرجاء الوِب انتقيناه لك أنت
+prefs_topstories_options_sponsored_label=الأخبار الممولة
+prefs_topstories_sponsored_learn_more=اطّلع على المزيد
+prefs_highlights_description=مجموعة المواقع التي حفظتها أو زرتها
+prefs_highlights_options_visited_label=الصفحات المزارة
+prefs_highlights_options_download_label=آخر ما نُزّل
+prefs_highlights_options_pocket_label=الصفحات المحفوظة في بوكِت
+prefs_snippets_description=التحديثات من موزيلا وفَيَرفُكس
+settings_pane_button_label=خصص صفحة اللسان الجديد
+settings_pane_topsites_header=المواقع الأكثر زيارة
+settings_pane_highlights_header=أهم الأحداث
+settings_pane_highlights_options_bookmarks=العلامات
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=المقتطفات
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=حرِّر
+edit_topsites_edit_button=حرّر هذا الموقع
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=موقع شائع جديد
+topsites_form_edit_header=حرّر الموقع الشائع
+topsites_form_title_label=العنوان
+topsites_form_title_placeholder=أدخل عنوانًا
+topsites_form_url_label=المسار
+topsites_form_image_url_label=مسار الصورة المخصصة
+topsites_form_url_placeholder=اكتب أو ألصق مسارًا
+topsites_form_use_image_link=استخدم صورة مخصصة…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=عايِن
+topsites_form_add_button=أضِفْ
+topsites_form_save_button=احفظ
+topsites_form_cancel_button=ألغِ
+topsites_form_url_validation=مطلوب مسار صالح
+topsites_form_image_validation=فشل تحميل الصورة. جرّب مسارا آخر.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=المواضيع الشائعة:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=اعرض المزيد من الأخبار
+
+highlights_empty_state=ابدأ التصفح وسنعرض أمامك بعض المقالات والفيديوهات والمواقع الأخرى التي زرتها حديثا أو أضفتها إلى العلامات هنا.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=لا جديد. تحقق لاحقًا للحصول على مزيد من أهم الأخبار من {provider}. لا يمكنك الانتظار؟ اختر موضوعًا شائعًا للعثور على المزيد من القصص الرائعة من جميع أنحاء الوِب.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=جرب فَيَرفُكس مع العلامات، و التأريخ، و كلمات السر من متصفح آخر.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=لا شكرًا
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=استورد الآن
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=أخ! حدث خطب ما أثناء تحميل المحتوى.
+error_fallback_default_refresh_suggestion=أنعِش الصفحة لإعادة المحاولة.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=أزِل القسم
+section_menu_action_collapse_section=اطوِ القسم
+section_menu_action_expand_section=وسّع القسم
+section_menu_action_manage_section=أدِر القسم
+section_menu_action_add_topsite=أضف موقعًا شائعًا
+section_menu_action_move_up=انقل لأعلى
+section_menu_action_move_down=انقل لأسفل
+section_menu_action_privacy_notice=تنويه الخصوصية
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ast/strings.properties
@@ -0,0 +1,171 @@
+newtab_page_title=Llingüeta nueva
+default_label_loading=Cargando…
+
+header_top_sites=Más visitaos
+header_stories=Histories destacaes
+header_highlights=Destacaos
+header_visit_again=Visitar de nueves
+header_bookmarks=Marcadores recientes
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recomendáu por {provider}
+# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
+# meant to inform that section contains no information because
+# the user hasn't added any bookmarks.
+header_bookmarks_placeholder=Entá nun tienes dengún marcador.
+# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
+# corresponding content (stories) provider
+header_stories_from=de
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visitóse
+type_label_bookmarked=Amestóse a marcadores
+type_label_synced=Sincronizóse dende otru preséu
+type_label_recommended=Tendencia
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=Abrir
+type_label_topic=Tema
+type_label_now=Agora
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Amestar a marcadores
+menu_action_remove_bookmark=Desaniciar marcador
+menu_action_copy_address=Copiar direición
+menu_action_email_link=Unviar enllaz per corréu…
+menu_action_open_new_window=Abrir nuna ventana nueva
+menu_action_open_private_window=Abrir nuna ventana privada nueva
+menu_action_dismiss=Escartar
+menu_action_delete=Desaniciar del historial
+menu_action_pin=Fixar
+menu_action_unpin=Desfixar
+confirm_history_delete_p1=¿De xuru que quies desaniciar cada instancia d'esta páxina del to historial?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Esta aición nun pue desfacese.
+menu_action_save_to_pocket=Guardar en Pocket
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with=Guetar {search_term} con:
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Guetar
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Gueta en {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Guetar na web
+search_settings=Camudar axustes de gueta
+
+# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the
+# (?) icon that would show a section's description with optional feedback link.
+section_info_option=Información
+section_info_send_feedback=Unviar comentarios
+section_info_privacy_notice=Nota de privacidá
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories_linktext=Deprendi cómo furrula.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Val, píllolo
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=Afáyate na llingüeta nueva
+welcome_body=Firefox usará esti espaciu p'amosate los marcadores, artículos, vídeos y páxines más relevantes que visitares apocayá, asina pues volver a ellos de mou cenciellu.
+welcome_label=Identificando los tos destacaos
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=<1m
+time_label_minute={number}m
+time_label_hour={number}h
+time_label_day={number}d
+
+# LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar.
+settings_pane_button_label=Personalizar páxina Llingüeta nueva
+settings_pane_header=Preferencies de Llingüeta nueva
+settings_pane_body2=Escueyi qué quies ver nesta páxina
+settings_pane_search_body=Restolar na Web dende la nueva llingüeta
+settings_pane_topsites_header=Más visitaos
+settings_pane_topsites_body=Acceder a les webs que más visites.
+settings_pane_topsites_options_showmore=Amosar dos fileres
+settings_pane_bookmarks_header=Marcadores recientes
+settings_pane_bookmarks_body=Los marcadores recién fechos, nun llugar accesible.
+settings_pane_visit_again_header=Visitar de nueves
+settings_pane_visit_again_body=Firefox va amosate partes del to historial de navegación que a lo meyor prestaríate remembrar o volver visitar.
+settings_pane_highlights_header=Destacaos
+settings_pane_highlights_body2=Atopa otra vegada les coses interesantes que yá visitaras o marcaras.
+settings_pane_highlights_options_bookmarks=Marcadores
+settings_pane_highlights_options_visited=Sitios visitaos
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Retayos
+settings_pane_snippets_body=Llei anovamientos curtios de Mozilla tocante a Firefox, la cultura d'internet y un meme de xemes en cuandu.
+settings_pane_done_button=Fecho
+settings_pane_topstories_options_sponsored=Amosar hestories patrocinaes
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Editar
+edit_topsites_button_label=Personalizar la seición de Más visitaos
+edit_topsites_showmore_button=Amosar más
+edit_topsites_showless_button=Amosar menos
+edit_topsites_done_button=Fecho
+edit_topsites_pin_button=Fixar esti sitiu
+edit_topsites_unpin_button=Desfixar esti sitiu
+edit_topsites_edit_button=Editar esti sitiu
+edit_topsites_dismiss_button=Escartar esti sitiu
+edit_topsites_add_button=Amestar
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nuevu Sitiu más visitáu
+topsites_form_edit_header=Editar Sitiu más visitáu
+topsites_form_title_placeholder=Introducir títulu
+topsites_form_url_placeholder=Escribi o apega una URL
+topsites_form_add_button=Amestar
+topsites_form_save_button=Guardar
+topsites_form_cancel_button=Encaboxar
+topsites_form_url_validation=Ríquese una URL válida
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Temes populares:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Ver más histories
+# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
+# to Pocket as part of the feedback form.
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane and
+# below (pocket_feedback_header) to provide more information about Pocket.
+
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Prueba Firefox colos marcadores, hestorial y contraseñes d'otru restolador.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Non, gracies
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importar agora
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/az/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Yeni Vərəq
+
+header_top_sites=Qabaqcıl Saytlar
+header_highlights=Seçilmişlər
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} məsləhət görür
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr={title} üçün kontekst menyusunu aç
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Kontekst menyusu bölməsini aç
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Ziyarət edilib
+type_label_bookmarked=Əlfəcinlənib
+type_label_recommended=Populyar
+type_label_pocket=Pocket-ə saxlandı
+type_label_downloaded=Endirildi
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Əlfəcinlə
+menu_action_remove_bookmark=Əlfəcini sil
+menu_action_open_new_window=Yeni Pəncərədə Aç
+menu_action_open_private_window=Yeni Məxfi Pəncərədə Aç
+menu_action_dismiss=Rədd et
+menu_action_delete=Tarixçədən Sil
+menu_action_pin=Bərkid
+menu_action_unpin=Çıxart
+confirm_history_delete_p1=Bu səhifənin bütün parçalarını tarixçənizdən silmək istədiyinizə əminsiniz?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Bu əməliyyat geri alına bilməz.
+menu_action_save_to_pocket=Pocket-ə Saxla
+menu_action_delete_pocket=Pocket-dən sil
+menu_action_archive_pocket=Pocket-də arxivləşdir
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Finder-də Göstər
+menu_action_show_file_windows=Yerləşdiyi Qovluğu Aç
+menu_action_show_file_linux=Yerləşdiyi Qovluğu Aç
+menu_action_show_file_default=Faylı Göster
+menu_action_open_file=Faylı Aç
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Endirmə Ünvanını Köçür
+menu_action_go_to_download_page=Endirmə səhifəsinə get
+menu_action_remove_download=Tarixçədən Sil
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Axtar
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} Axtarış
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=İnternetdə Axtar
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Nələr oxuduğunuza əsasən seçilmiş internetin ən maraqlı hekayələri. Pocket-dən, artıq Mozillanın bir hissəsi.
+section_disclaimer_topstories_linktext=Necə işlədiyini öyrənin.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Tamam, başa düşdüm
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox Ev Məzmunu
+prefs_home_description=Firefox Evdə hansı məzmunları görmək istədiyinizi seçin.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} sətir;{num} sətir
+prefs_search_header=Web Axtarış
+prefs_topsites_description=Ən çox ziyarət etdiyiniz saytlar
+prefs_topstories_description2=İnternetin ən yaxşı məzmunları, sizə görə fərdiləşdirilmiş
+prefs_topstories_options_sponsored_label=Sponsorlaşdırılmış Hekayələr
+prefs_topstories_sponsored_learn_more=Ətraflı öyrən
+prefs_highlights_description=Saxladığınız və ya ziyarət etdiyiniz saytlardan seçmələr
+prefs_highlights_options_visited_label=Baxılmış Səhifələr
+prefs_highlights_options_download_label=Son Endirmələr
+prefs_highlights_options_pocket_label=Pocket-ə Saxlanılan Səhifələr
+prefs_snippets_description=Mozilla və Firefoxdan yeniliklər
+settings_pane_button_label=Yeni Vərəq səhifənizi özəlləşdirin
+settings_pane_topsites_header=Qabaqcıl Saytlar
+settings_pane_highlights_header=Seçilmişlər
+settings_pane_highlights_options_bookmarks=Əlfəcinlər
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Hissələr
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Redaktə et
+edit_topsites_edit_button=Bu saytı düzəlt
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Yeni Qabaqcıl Saytlar
+topsites_form_edit_header=Qabaqcıl Saytları Dəyişdir
+topsites_form_title_label=Başlıq
+topsites_form_title_placeholder=Başlıq daxil et
+topsites_form_url_label=URL
+topsites_form_image_url_label=Fərdi şəkil ünvanı
+topsites_form_url_placeholder=Ünvanı yazın və ya yapışdırın
+topsites_form_use_image_link=Fərdi şəkil işlət…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Ön baxış
+topsites_form_add_button=Əlavə et
+topsites_form_save_button=Saxla
+topsites_form_cancel_button=Ləğv et
+topsites_form_url_validation=Doğru ünvan tələb olunur
+topsites_form_image_validation=Şəkli yükləmək mümkün olmadı. Fərqli ünvan yoxlayın.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Məşhur Mövzular:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Daha çox hekayə gör
+
+highlights_empty_state=İnternetdə gəzməyə başlayın, burada ziyarət edəcəyiniz və ya əlfəcinləyəcəyiniz məqalə, video və digər səhifələri göstərəcəyik.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Hamısını oxudunuz. Yeni {provider} məqalələri üçün daha sonra təkrar yoxlayın. Gözləyə bilmirsiz? Məşhur mövzu seçərək internetdən daha çox gözəl məqalələr tapın.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Firefox səyyahını digər səyyahlardan olan əlfəcin, tarixçə və parollar ilə yoxlayın.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Xeyr, Təşəkkürlər
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=İndi idxal et
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Uups, bu məzmunu yüklərkən nəsə səhv getdi.
+error_fallback_default_refresh_suggestion=Təkrar yoxlamaq üçün səhifəni yeniləyin.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Bölməni Sil
+section_menu_action_collapse_section=Bölməni Daralt
+section_menu_action_expand_section=Bölməni Genişlət
+section_menu_action_manage_section=Bölməni İdarə et
+section_menu_action_manage_webext=Uzantını idarə et
+section_menu_action_add_topsite=Qabaqcıl Sayt əlavə et
+section_menu_action_move_up=Yuxarı daşı
+section_menu_action_move_down=Aşağı daşı
+section_menu_action_privacy_notice=Məxfilik Bildirişi
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Firefox-u özünüzlə gəzdirin
+firstrun_content=Əlfəcin, tarixçə, parol və digər tənzimləmələrinizi bütün cihazlarınızda əldə edin.
+firstrun_learn_more_link=Firefox Hesabları haqqında ətraflı öyrənin
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=E-poçtunuzu daxil edin
+firstrun_form_sub_header=və Firefox Sync ilə davam edin.
+
+firstrun_email_input_placeholder=E-poçt
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Davam etməklə {terms} və {privacy} ilə razılaşmış olursuz.
+firstrun_terms_of_service=İstifadə Şərtləri
+firstrun_privacy_notice=Məxfilik Bildirişi
+
+firstrun_continue_to_login=Davam et
+firstrun_skip_login=Bu addımı keç
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/be/strings.properties
@@ -0,0 +1,192 @@
+newtab_page_title=Новая картка
+
+header_top_sites=Папулярныя сайты
+header_highlights=Выбранае
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Рэкамендавана {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Адкрыць кантэкстнае меню для {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Адкрыць кантэкстнае меню раздзела
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Наведанае
+type_label_bookmarked=У закладках
+type_label_recommended=Тэндэнцыі
+type_label_pocket=Захавана ў Pocket
+type_label_downloaded=Сцягнута
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=У закладкі
+menu_action_remove_bookmark=Выдаліць закладку
+menu_action_open_new_window=Адкрыць у новым акне
+menu_action_open_private_window=Адкрыць у новым прыватным акне
+menu_action_dismiss=Адхіліць
+menu_action_delete=Выдаліць з гісторыі
+menu_action_pin=Замацаваць
+menu_action_unpin=Адмацаваць
+confirm_history_delete_p1=Вы сапраўды жадаеце выдаліць усе запісы аб гэтай старонцы з гісторыі?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Гэта дзеянне немагчыма адмяніць.
+menu_action_save_to_pocket=Захаваць у Pocket
+menu_action_delete_pocket=Выдаліць з Pocket
+menu_action_archive_pocket=Архіваваць у Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Паказаць у Finder
+menu_action_show_file_windows=Адкрыць змяшчальную папку
+menu_action_show_file_linux=Адкрыць папку з файлам
+menu_action_show_file_default=Паказаць файл
+menu_action_open_file=Адкрыць файл
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Капіяваць спасылку сцягвання
+menu_action_go_to_download_page=Перайсці на старонку сцягвання
+menu_action_remove_download=Выдаліць з гісторыі
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Шукаць
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Шукаць у {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Пошук у Інтэрнэце
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Самыя цікавыя гісторыі з інтэрнэту на аснове таго, што вы чытаеце. Падборка ад Pocket, які цяпер частка Mozilla.
+section_disclaimer_topstories_linktext=Даведайцеся, як гэта працуе.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Зразумела
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Хатні экран Firefox
+prefs_home_description=Выберыце пажаданае змесціва для хатняга экрана Firefox.
+prefs_restore_defaults_button=Аднавіць прадвызначэнні
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} радок;{num} радкі;{num} радкоў
+prefs_search_header=Пошук у сеціве
+prefs_topsites_description=Сайты, якія вы наведваеце найчасцей
+prefs_topstories_description2=Выдатнае змесціва з усяго інтэрнэту, выбранае спецыяльна для вас
+prefs_topstories_options_sponsored_label=Артыкулы ад спонсараў
+prefs_topstories_sponsored_learn_more=Даведацца больш
+prefs_highlights_description=Выбраныя сайты, якія вы захавалі ці наведалі
+prefs_highlights_options_visited_label=Наведаныя старонкі
+prefs_highlights_options_download_label=Нядаўнія сцягванні
+prefs_highlights_options_pocket_label=Захаваныя ў Pocket старонкі
+prefs_snippets_description=Абнаўленні ад Mozilla і Firefox
+settings_pane_button_label=Наладзіць вашу старонку новай карткі
+settings_pane_header=Налады новай карткі
+settings_pane_body2=Выберыце тое, што вы бачыце на гэтай старонцы.
+settings_pane_search_header=Пошук
+settings_pane_search_body=Пошук у Сеціве з вашай новай карткі.
+settings_pane_topsites_header=Папулярныя сайты
+settings_pane_topsites_body=Доступ да сайтаў, якія вы часцей наведваеце.
+settings_pane_topsites_options_showmore=Паказваць два шэрагі
+settings_pane_highlights_header=Выбранае
+settings_pane_highlights_body2=Знайдзіце зваротны шлях да цікавых рэчаў, якія вы нядаўна наведалі або дадалі ў закладкі.
+settings_pane_highlights_options_bookmarks=Закладкі
+settings_pane_highlights_options_visited=Наведаныя сайты
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Урыўкі
+settings_pane_snippets_body=Чытайце кароткія і радасныя навіны ад Mozilla аб Firefox, інтэрнэт-культуру і выпадковыя мемы.
+settings_pane_done_button=Гатова
+settings_pane_topstories_options_sponsored=Паказаць артыкулы ад спонсараў
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Правіць
+edit_topsites_edit_button=Рэдагаваць гэты сайт
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Новы папулярны сайт
+topsites_form_edit_header=Рэдагаваць папулярны сайт
+topsites_form_title_label=Загаловак
+topsites_form_title_placeholder=Увядзіце назву
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL уласнага відарыса
+topsites_form_url_placeholder=Увядзіце або ўстаўце URL
+topsites_form_use_image_link=Выкарыстоўваць уласны відарыс…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Перадпрагляд
+topsites_form_add_button=Дадаць
+topsites_form_save_button=Захаваць
+topsites_form_cancel_button=Скасаваць
+topsites_form_url_validation=Патрабуецца сапраўдны URL
+topsites_form_image_validation=Не ўдалося атрымаць відарыс. Паспрабуйце іншы URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Папулярныя тэмы:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Іншыя навіны
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=Адкрыйце для сябе высакаякасны кантэнт, які вы маглі б прапусціць, з дапамогай Pocket, які стаў часткай Mozilla.
+
+highlights_empty_state=Пачніце агляданне, і мы пакажам вам тут некаторыя з найлепшых артыкулаў, відэаролікаў і іншых старонак, якія вы нядаўна наведалі або дадалі ў закладкі.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Гатова. Праверце пазней, каб убачыць больш матэрыялаў ад {provider}. Не жадаеце чакаць? Выберыце папулярную тэму, каб знайсці больш цікавых матэрыялаў з усяго Інтэрнэту.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Паспрабуйце Firefox з закладкамі, гісторыяй і паролямі з іншага браўзера.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Не, дзякуй
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Імпартаваць зараз
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ох, нешта пайшло не так пры загрузцы гэтага змесціва.
+error_fallback_default_refresh_suggestion=Абнавіць старонку, каб паўтарыць спробу.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Выдаліць раздзел
+section_menu_action_collapse_section=Згарнуць раздзел
+section_menu_action_expand_section=Разгарнуць раздзел
+section_menu_action_manage_section=Наладзіць раздзел
+section_menu_action_add_topsite=Дадаць папулярны сайт
+section_menu_action_move_up=Пасунуць вышэй
+section_menu_action_move_down=Пасунуць ніжэй
+section_menu_action_privacy_notice=Паведамленне аб прыватнасці
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/bg/strings.properties
@@ -0,0 +1,143 @@
+newtab_page_title=Нов раздел
+
+header_top_sites=Често посещавани
+header_highlights=Акценти
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Препоръчано от {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Отваряне на контекстуалното меню на {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Отваряне на контекстното меню на раздела
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Посетена
+type_label_bookmarked=Отметната
+type_label_recommended=Тенденции
+type_label_pocket=Запазено в Pocket
+type_label_downloaded=Изтеглено
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Отметка
+menu_action_remove_bookmark=Премахване на отметка
+menu_action_open_new_window=Отваряне в раздел
+menu_action_open_private_window=Отваряне в поверителен прозорец
+menu_action_dismiss=Отхвърляне
+menu_action_delete=Премахване
+menu_action_pin=Закачане
+menu_action_unpin=Откачане
+confirm_history_delete_p1=Сигурни ли сте, че желаете да премахнете страницата навсякъде от историята?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Действието е необратимо.
+menu_action_save_to_pocket=Запазване в Pocket
+menu_action_delete_pocket=Изтриване от Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Търсене
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Търсене с {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Търсене в интернет
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Най-интересните истории в Мрежата на основата на прочетеното от вас. От Pocket, вече част от Mozilla.
+section_disclaimer_topstories_linktext=Разберете как работи.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ясно, разбрах
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+settings_pane_button_label=Настройки на новия раздел
+settings_pane_topsites_header=Често посещавани
+settings_pane_highlights_header=Акценти
+settings_pane_highlights_options_bookmarks=Отметки
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Изрезки
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Редактиране
+edit_topsites_edit_button=Редактиране
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Нов често посещавана страница
+topsites_form_edit_header=Редактиране на често посещавана страница
+topsites_form_title_placeholder=Заглавие
+topsites_form_url_placeholder=Адрес
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Преглед
+topsites_form_add_button=Добавяне
+topsites_form_save_button=Запазване
+topsites_form_cancel_button=Отказ
+topsites_form_url_validation=Необходим е валиден URL
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Популярни теми:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Повече статии
+
+highlights_empty_state=Разглеждайте и тук ще ви покажем някои от най-добрите статии, видео и други страници, които сте посетили или отметнали наскоро.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Разгледахте всичко. Проверете по-късно за повече истории от {provider}. Нямате търпение? Изберете популярна тема, за да откриете повече истории из цялата Мрежа.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Опитайте Firefox с отметките, историята и паролите от друг четец.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Не, благодаря
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Внасяне
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_move_up=Преместване нагоре
+section_menu_action_move_down=Преместване надолу
+section_menu_action_privacy_notice=Политика за личните данни
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/bn-BD/strings.properties
@@ -0,0 +1,177 @@
+newtab_page_title=নতুন ট্যাব
+
+header_top_sites=শীর্ঘ সাইট
+header_highlights=হাইলাইটস
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} দ্বারা সুপারিশকৃত
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr={title} থেকে কনটেক্সট মেনু খুলুন
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=কনটেক্স মেন্যু তে সেকশনটি খুলুন
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=পরিদর্শিত
+type_label_bookmarked=বুকমার্ক করা হয়েছে
+type_label_recommended=ঝোঁক
+type_label_pocket=Pocket এ সংরক্ষণ করুন
+type_label_downloaded=ডাউনলোড হয়েছে
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=বুকমার্ক
+menu_action_remove_bookmark=বুকমার্ক মুছে দিন
+menu_action_open_new_window=নতুন উইন্ডোতে খুলুন
+menu_action_open_private_window=নতুন ব্যক্তিগত উইন্ডোতে খুলুন
+menu_action_dismiss=বাতিল
+menu_action_delete=ইতিহাস থেকে মুছে ফেলুন
+menu_action_pin=পিন
+menu_action_unpin=আনপিন
+confirm_history_delete_p1=আপনি কি নিশ্চিতভাবে আপনার ইতিহাস থেকে এই পাতার সকল কিছু মুছে ফেলতে চান?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=এই পরিবর্তনটি অপরিবর্তনীয়।
+menu_action_save_to_pocket=Pocket এ সংরক্ষণ করুন
+menu_action_delete_pocket=Pocket থেকে মুছে দিন
+menu_action_archive_pocket=Pocket এ আর্কাইভ করুন
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=ফাইন্ডারে প্রদর্শন করুন
+menu_action_show_file_windows=ধারণকারী ফোল্ডার খুলুন
+menu_action_show_file_linux=ধারণকারী ফোল্ডার খুলুন
+menu_action_show_file_default=ফাইল দেখান
+menu_action_open_file=ফাইল খুলুন
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=ডাউনলোডের লিঙ্ক অনুলিপি করুন
+menu_action_go_to_download_page=ডাউনলোড পাতায় যাও
+menu_action_remove_download=ইতিহাস থেকে মুছে ফেলুন
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=অনুসন্ধান
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} খুঁজুন
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=ওয়েবে সন্ধান করুন
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=মজার মজার সব গল্প নির্বাচিত হয়েছে, আপনি যেমনটা পড়েন। Pocket এখন থেকে Mozilla এর অংশ।
+section_disclaimer_topstories_linktext=কিভাবে কাজ করে জানুন।
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=ঠিক আছে, বুঝেছি
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox Home কনটেন্ট
+prefs_home_description=আপনার Firefox Home স্ক্রিনে যেসব কনটেন্ট রাখতে চান তা পছন্দ করুন।
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} সারি; {num} সারিগুলি
+prefs_search_header=ওয়েব অনুসন্ধান
+prefs_topsites_description=যে সাইটগুলিতে আপনি বেশি যান
+prefs_topstories_description2=ওয়েবের দারুন সব কন্টেন্ট, নিজের মত করে সাঁজিয়ে নিন
+prefs_topstories_options_sponsored_label=স্পন্সর করা স্টোরি
+prefs_topstories_sponsored_learn_more=আরও জানুন
+prefs_highlights_description=সাইটের একটি সেকশন যা আপনি সংরক্ষণ অথবা গিয়েছিলেন
+prefs_highlights_options_visited_label=ঘুরে আসা পেজ
+prefs_highlights_options_download_label=সর্বশেষ ডাউনলোড
+prefs_highlights_options_pocket_label=পেজটি Pocket এ সংরক্ষণ করা হয়েছে
+prefs_snippets_description=Mozilla and Firefox থেকে হালনাগাদ
+settings_pane_button_label=আপনার নতুন ট্যাব পেজটি কাস্টমাইজ করুন
+settings_pane_topsites_header=শীর্ষ সাইট
+settings_pane_highlights_header=হাইলাইটস
+settings_pane_highlights_options_bookmarks=বুকমার্ক
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=টুকিটাকি
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=সম্পাদনা
+edit_topsites_edit_button=সাইটটি সম্পাদনা করুন
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=নতুন শীর্ষ সাইট
+topsites_form_edit_header=শীর্ষ সাইট সম্পাদনা করুন
+topsites_form_title_label=শিরোনাম
+topsites_form_title_placeholder=নাম দিন
+topsites_form_url_label=URL
+topsites_form_image_url_label=কাস্টম ছবির URL
+topsites_form_url_placeholder=টাইপ করুন অথবা পেস্ট করুন URL
+topsites_form_use_image_link=কাস্টম ছবি ব্যবহার করুন…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=প্রাকদর্শন
+topsites_form_add_button=যোগ
+topsites_form_save_button=সংরক্ষণ
+topsites_form_cancel_button=বাতিল
+topsites_form_url_validation=কার্যকর URL প্রয়োজন
+topsites_form_image_validation=ছবি লোড করতে ব্যর্থ। ভিন্ন URL এ চেস্টা করুন।
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=জনপ্রিয় বিষয়:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=আরও গল্প দেখুন
+
+highlights_empty_state=ব্রাউজি করা শুরু করুন, এবং কিছু গুরুত্বপূর্ণ নিবন্ধ, ভিডিও, এবং আপনি সম্প্রতি পরিদর্শন বা বুকমার্ক করেছেন এমন কিছু পৃষ্ঠা আমরা এখানে প্রদর্শন করব।
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=কিছু একটা ঠিক নেই। {provider} এর শীর্ষ গল্পগুলো পেতে কিছুক্ষণ পর আবার দেখুন। অপেক্ষা করতে চান না? বিশ্বের সেরা গল্পগুলো পেতে কোন জনপ্রিয় বিষয় নির্বাচন করুন।
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=অন্য ব্রাউজার থেকে আনা বুকমার্ক, ইতিহাস এবং পাসওয়ার্ডগুলির সাথে ফায়ারফক্স ব্যবহার করে দেখুন।
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=প্রয়োজন নেই
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=এখনই ইম্পোর্ট করুন
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=ওহো, কনটেন্টটি লোড করতে কিছু ভুল হয়েছে।
+error_fallback_default_refresh_suggestion=পুনরায় চেস্টা করার জন্য পেজটি রিফ্রেশ করুন।
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=সেকশনটি সরান
+section_menu_action_collapse_section=সেকশনটি সংকোচন করুন
+section_menu_action_expand_section=সেকশনটি প্রসারিত করুন
+section_menu_action_manage_section=সেকশনটি পরিচালনা করুন
+section_menu_action_add_topsite=টপ সাইট যোগ করুন
+section_menu_action_move_up=উপরে উঠাও
+section_menu_action_move_down=নীচে নামাও
+section_menu_action_privacy_notice=গোপনীয়তা নীতি
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/bn-IN/strings.properties
@@ -0,0 +1,123 @@
+newtab_page_title=নতুন ট্যাব
+default_label_loading=লোড করা হচ্ছে…
+
+header_top_sites=শীর্ষ সাইটগুলি
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
+# meant to inform that section contains no information because
+# the user hasn't added any bookmarks.
+# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
+# corresponding content (stories) provider
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=দেখা হয়েছে
+type_label_bookmarked=বুকমার্ক করা হয়েছে
+type_label_synced=অন্য ডিভাইস থেকে সিঙ্ক করা হয়েছে
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=খুলুন
+type_label_topic=বিষয়
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=বুকমার্ক
+menu_action_remove_bookmark=বুকমার্ক সরান
+menu_action_copy_address=ঠিকানা কপি করুন
+menu_action_email_link=ই-মেইল লিংক…
+menu_action_open_new_window=নতুন উইন্ডোর মধ্যে খুলুন
+menu_action_open_private_window=নতুন প্রাইভেট উইন্ডোর মধ্যে খুলুন
+menu_action_dismiss=বাতিল
+menu_action_delete=তালিকা থেকে মুছে ফেলুন
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with={search_term} এর জন্য খুঁজুন সাথে:
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=অনুসন্ধান
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} এ অনুসন্ধান করুন
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=ওয়েবে সন্ধান করুন
+search_settings=সার্চ সেটিংস বদল করুন
+
+# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the
+# (?) icon that would show a section's description with optional feedback link.
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=নতুন ট্যাবে স্বাগতম
+welcome_body=আপনার সাথে মিলে এমন বুর্কমার্ক, নিবন্ধ, ভিডিও এবং পাতা যেগুলো আপনি সম্প্রতি ভ্রমণ করেছে তা Firefox এই জায়গায় দেখাবে, যাতে আপনি সেগুলো দ্রুত খুঁজে পান।
+welcome_label=আপনার হাইলাইট সমূহ চিহ্নিত করা হচ্ছে
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=<1মিনিট
+time_label_minute={number} মিনিট
+time_label_hour={number} ঘন্টা
+time_label_day={number} দিন
+
+# LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar.
+settings_pane_button_label=আপনার নতুন ট্যাব পেজটি কাস্টমাইজ করুন
+settings_pane_header=নতুন ট্যাব পছন্দসমূহ
+settings_pane_search_header=অনুসন্ধান
+settings_pane_search_body=আপনার নতুন ট্যাব থেকে ওয়েবে খুঁজুন।
+settings_pane_topsites_header=শীর্ষ সাইট
+settings_pane_topsites_body=আপনি যেসব সাইটে বেশি যান সেসব সাইটে প্রবেশ করুন।
+settings_pane_topsites_options_showmore=দুটি সারি দেখান
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_done_button=হয়েছে
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=সম্পাদনা
+edit_topsites_button_label=আপনার শীর্ষ সাইট সেকশন কাস্টমাইজ করুন
+edit_topsites_showmore_button=আরও দেখান
+edit_topsites_showless_button=কম দেখান
+edit_topsites_done_button=হয়েছে
+edit_topsites_pin_button=সাইটটি পিন করুন
+edit_topsites_edit_button=সাইটটি সম্পাদনা করুন
+edit_topsites_dismiss_button=সাইটটি মুছে দিন
+edit_topsites_add_button=যুক্ত করুন
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_title_placeholder=একটি শিরোনাম লিখুন
+topsites_form_cancel_button=বাতিল করুন
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
+# to Pocket as part of the feedback form.
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane and
+# below (pocket_feedback_header) to provide more information about Pocket.
+
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/br/strings.properties
@@ -0,0 +1,192 @@
+newtab_page_title=Ivinell nevez
+
+header_top_sites=Lec'hiennoù pennañ
+header_highlights=Mareoù pouezus
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Erbedet gant {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Digeriñ al lañser kemperzhel evit {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Digeriñ lañser kemperzhel al lodenn-mañ
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Gweladennet
+type_label_bookmarked=Lakaet er sinedoù
+type_label_recommended=Brudet
+type_label_pocket=Enrollet e Pocket
+type_label_downloaded=Pellgarget
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Sined
+menu_action_remove_bookmark=Dilemel ar sined
+menu_action_open_new_window=Digeriñ e-barzh ur prenestr nevez
+menu_action_open_private_window=Digeriñ e-barzh ur prenestr merdeiñ prevez nevez
+menu_action_dismiss=Argas
+menu_action_delete=Dilemel eus ar roll istor
+menu_action_pin=Spilhennañ
+menu_action_unpin=Dispilhennañ
+confirm_history_delete_p1=Sur oc'h e fell deoc'h dilemel kement eriol eus ar bajenn-mañ diouzh ho roll istor?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Ne c'haller ket dizober ar gwezh-mañ.
+menu_action_save_to_pocket=Enrollañ etrezek Pocket
+menu_action_delete_pocket=Dilemel eus Pocket
+menu_action_archive_pocket=Diellaouiñ e Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Diskouez e Finder
+menu_action_show_file_windows=Digeriñ an teuliad a endalc'h ar restr
+menu_action_show_file_linux=Digeriñ an teuliad a endalc'h ar restr
+menu_action_show_file_default=Diskouez ar restr
+menu_action_open_file=Digeriñ ar restr
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Eilañ ere ar pellgargadur
+menu_action_go_to_download_page=Mont da bajenn ar pellgargadur
+menu_action_remove_download=Dilemel diwar ar roll
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Klask
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Klask {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Klask er web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=An istorioù dedennusañ er web, dibabet hervez ar pezh a lennit. Diwar Pocket, ul lodenn eus Mozilla.
+section_disclaimer_topstories_linktext=Deskit penaos ec'h a en-dro.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Mat eo, komprenet am eus
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Endalc'had Degemer Firefox
+prefs_home_description=Dibabit peseurt endalc'had a fell deoc'h kaout war ho skramm Firefox Degemer.
+prefs_restore_defaults_button=Assav an arventennoù dre ziouer
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} renk;{num} renk;{num} renk;{num} a renkoù;{num} renk
+prefs_search_header=Klask web
+prefs_topsites_description=Al lec'hiennoù a weladennit ar muiañ
+prefs_topstories_description2=Danvez eus an dibab eus pep lec'h er web, personelaet evidoc'h
+prefs_topstories_options_sponsored_label=Istorioù kevelet
+prefs_topstories_sponsored_learn_more=Gouzout hiroc'h
+prefs_highlights_description=Un dibab a lec'hiennoù ho peus enrollet pe gweladennet
+prefs_highlights_options_visited_label=Pajennoù gweladennet
+prefs_highlights_options_download_label=Pellgargadurioù nevez
+prefs_highlights_options_pocket_label=Pajennoù enrollet e Pocket
+prefs_snippets_description=Keleier eus Mozilla ha Firefox
+settings_pane_button_label=Personelait ho pajenn Ivinell Nevez
+settings_pane_header=Gwellvezioù an ivinell nevez
+settings_pane_body2=Dibabit petra a welit war ar bajenn-mañ.
+settings_pane_search_header=Klask
+settings_pane_search_body=Klask er web adalek an ivinell nevez.
+settings_pane_topsites_header=Lec'hiennoù gwellañ
+settings_pane_topsites_body=Kit war al lec'hiennoù gweladennet ar muiañ ganeoc'h.
+settings_pane_topsites_options_showmore=Diskouez daou vann
+settings_pane_highlights_header=Mareoù pouezus
+settings_pane_highlights_body2=Adkavit an traoù dedennus gweladennet pe lakaet er sinedoù nevez ’zo.
+settings_pane_highlights_options_bookmarks=Sinedoù
+settings_pane_highlights_options_visited=Lec'hiennoù gweladennet
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Notennigoù
+settings_pane_snippets_body=Lennit an hizivadurioù berr ha dous graet gant Mozilla evit Firefox, sevenadur ar genrouedad, hag ur mem dre-zegouezh ur wech an amzer.
+settings_pane_done_button=Graet
+settings_pane_topstories_options_sponsored=Diskouez an istorioù kevelet
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Embann
+edit_topsites_edit_button=Embann al lec'hienn-mañ
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Lec'hiennoù gwellañ nevez
+topsites_form_edit_header=Embann al Lec'hiennoù Gwellañ
+topsites_form_title_label=Titl
+topsites_form_title_placeholder=Enankañ un titl
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL ar skeudenn personelaet
+topsites_form_url_placeholder=Skrivit pe pegit un URL
+topsites_form_use_image_link=Ober gant ur skeudenn personelaet…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Alberz
+topsites_form_add_button=Ouzhpennañ
+topsites_form_save_button=Enrollañ
+topsites_form_cancel_button=Nullañ
+topsites_form_url_validation=URL talvoudek azgoulennet
+topsites_form_image_validation=N'haller ket kargan ar skeudenn. Klaskit gant un URL disheñvel.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Danvezioù brudet:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Gwelet muioc'h a istorioù
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=Dizoloit pennadoù eus an dibab ho pije gellout c'hwitout a-hent all warno, a-drugarez da bPocket, hag a zo bremañ ul lodenn deus Mozilla.
+
+highlights_empty_state=Krogit da verdeiñ hag e tiskouezimp deoc’h pennadoù, videoioù ha pajennoù all gweladennet pe lakaet er sinedoù nevez ’zo.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Aet oc'h betek penn. Distroit diwezhatoc'h evit muioc’h a istorioù digant {provider}. N’oc'h ket evit gortoz? Dibabit un danvez brudet evit klask muioc’h a bennadoù dedennus eus pep lec’h er web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Amprouit Firefox gant sinedoù, roll istor ha gerioù-tremen ur merdeer all.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=N'am bo ket
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Emporzhiañ bremañ
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Chaous, un dra bennak a zo a-dreuz en ur gargañ an endalc'had.
+error_fallback_default_refresh_suggestion=Adkargit ar bajenn evit klask en-dro.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Dilemel ar gevrenn
+section_menu_action_collapse_section=Bihanaat ar gevrenn
+section_menu_action_expand_section=Astenn ar gevrenn
+section_menu_action_manage_section=Merañ ar gevrenn
+section_menu_action_add_topsite=Ouzhpennañ ul lec'hienn gwellañ din
+section_menu_action_move_up=Dilec'hiañ etrezek ar c'hrec'h
+section_menu_action_move_down=Dilec'hiañ etrezek an traoñ
+section_menu_action_privacy_notice=Evezhiadennoù a-fet buhez prevez
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/bs/strings.properties
@@ -0,0 +1,192 @@
+newtab_page_title=Novi tab
+
+header_top_sites=Najposjećenije stranice
+header_highlights=Istaknuto
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Preporučeno od {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Otvorite kontekstni meni za {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Otvorite kontekstni meni sekcije
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Posjećeno
+type_label_bookmarked=Zabilježeno
+type_label_recommended=Popularno
+type_label_pocket=Sačuvano u Pocket
+type_label_downloaded=Preuzeto
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Zabilježi
+menu_action_remove_bookmark=Ukloni zabilješku
+menu_action_open_new_window=Otvori u novom prozoru
+menu_action_open_private_window=Otvori u novom privatnom prozoru
+menu_action_dismiss=Odbaci
+menu_action_delete=Izbriši iz historije
+menu_action_pin=Zakači
+menu_action_unpin=Otkači
+confirm_history_delete_p1=Jeste li sigurni da želite izbrisati sve primjere ove stranice iz vaše historije?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Ova radnja se ne može opozvati.
+menu_action_save_to_pocket=Sačuvaj na Pocket
+menu_action_delete_pocket=Izbriši iz Pocketa
+menu_action_archive_pocket=Arhiviraj u Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Prikaži u Finderu
+menu_action_show_file_windows=Otvori direktorij u kojem se nalazi
+menu_action_show_file_linux=Otvori direktorij u kojem se nalazi
+menu_action_show_file_default=Prikaži datoteku
+menu_action_open_file=Otvori datoteku
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Kopiraj link za preuzimanje
+menu_action_go_to_download_page=Idi na stranicu za preuzimanje
+menu_action_remove_download=Ukloni iz historije
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Traži
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} pretraga
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Pretraži web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Najinteresantnije priče na webu, odabrane na osnovu onoga što ste pročitali. Od Pocket-a, koji je sada dio Mozille.
+section_disclaimer_topstories_linktext=Saznajte kako radi.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=U redu, razumijem
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox početni sadržaj
+prefs_home_description=Odaberite koji sadržaj želite na vašem početnom ekranu Firefoxa.
+prefs_restore_defaults_button=Vrati na izvorne vrijednosti
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} red;{num} redovi
+prefs_search_header=Web pretraga
+prefs_topsites_description=Stranice koje najviše posjećujete
+prefs_topstories_description2=Sjajan sadržaj s cijelog weba, personalizovan za vas
+prefs_topstories_options_sponsored_label=Sponzorisane priče
+prefs_topstories_sponsored_learn_more=Saznajte više
+prefs_highlights_description=Izbor stranica koje ste sačuvali ili posjetili
+prefs_highlights_options_visited_label=Posjećene stranice
+prefs_highlights_options_download_label=Najnovija preuzimanja
+prefs_highlights_options_pocket_label=Stranice spremljene u Pocket
+prefs_snippets_description=Ažuriranja od Mozille i Firefoxa
+settings_pane_button_label=Prilagodite svoju početnu stranicu novog taba
+settings_pane_header=Postavke novog taba
+settings_pane_body2=Izaberite šta želite vidjeti na ovoj stranici.
+settings_pane_search_header=Traži
+settings_pane_search_body=Pretražite web iz novog taba.
+settings_pane_topsites_header=Najposjećenije stranice
+settings_pane_topsites_body=Pristupite stranicama koje najčešće posjećujete.
+settings_pane_topsites_options_showmore=Prikaži dva reda
+settings_pane_highlights_header=Istaknuto
+settings_pane_highlights_body2=Pronađite put natrag do zanimljivih stvari koje ste nedavno posjetili ili zabilježili.
+settings_pane_highlights_options_bookmarks=Zabilješke
+settings_pane_highlights_options_visited=Posjećene stranice
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Isječci
+settings_pane_snippets_body=Pročitajte kratke i slatke obavijesti od Mozille o Firefoxu, internet kulturi i povremenim nasumičnim temama.
+settings_pane_done_button=Gotovo
+settings_pane_topstories_options_sponsored=Prikaži sponzorisane priče
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Uredi
+edit_topsites_edit_button=Uredi ovu stranicu
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nova najbolja stranica
+topsites_form_edit_header=Uredi najbolju stranicu
+topsites_form_title_label=Naslov
+topsites_form_title_placeholder=Unesi naslov
+topsites_form_url_label=URL
+topsites_form_image_url_label=Prilagođena URL slika
+topsites_form_url_placeholder=Upišite ili zalijepite URL
+topsites_form_use_image_link=Koristite prilagođenu sliku…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Pregled
+topsites_form_add_button=Dodaj
+topsites_form_save_button=Sačuvaj
+topsites_form_cancel_button=Otkaži
+topsites_form_url_validation=Potrebno je unijeti ispravan URL
+topsites_form_image_validation=Neuspjelo učitavanje slike. Probajte drugi URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Popularne teme:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Prikaži više priča
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=Otkrijte visoko kvalitetan sadržaj koji ste možda propustili, uz pomoć Pocketa koji je sada dio Mozille.
+
+highlights_empty_state=Započnite pretraživati i pokazat ćemo vam neke od izvrsnih članaka, videa i drugih web stranica prema vašim nedavno posjećenim stranicama ili zabilješkama.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Provjerite kasnije za više najpopularnijih priča od {provider}. Ne možete čekati? Odaberite popularne teme kako biste pronašli više kvalitetnih priča s cijelog weba.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Probajte Firefox s zabilješkama, historijom i lozinkama iz drugog pretraživača.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Ne, hvala
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Uvezi sada
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ups, došlo je do greške pri učitavanju ovog sadržaja.
+error_fallback_default_refresh_suggestion=Osvježite stranicu da biste pokušali ponovo.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Ukloni sekciju
+section_menu_action_collapse_section=Skupi sekciju
+section_menu_action_expand_section=Proširi sekciju
+section_menu_action_manage_section=Upravljaj sekcijom
+section_menu_action_add_topsite=Dodajte omiljenu stranicu
+section_menu_action_move_up=Pomjeri gore
+section_menu_action_move_down=Pomjeri dole
+section_menu_action_privacy_notice=Polica privatnosti
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ca/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Pestanya nova
+
+header_top_sites=Llocs principals
+header_highlights=Destacats
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recomanat per {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Obre el menú contextual de {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Obre el menú contextual de la secció
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visitat
+type_label_bookmarked=A les adreces d'interès
+type_label_recommended=Tendència
+type_label_pocket=Desat al Pocket
+type_label_downloaded=Baixat
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Afegeix a les adreces d'interès
+menu_action_remove_bookmark=Elimina l'adreça d'interès
+menu_action_open_new_window=Obre en una finestra nova
+menu_action_open_private_window=Obre en una finestra privada nova
+menu_action_dismiss=Descarta
+menu_action_delete=Elimina de l'historial
+menu_action_pin=Fixa
+menu_action_unpin=No fixis
+confirm_history_delete_p1=Segur que voleu suprimir de l'historial totes les instàncies d'aquesta pàgina?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Aquesta acció no es pot desfer.
+menu_action_save_to_pocket=Desa al Pocket
+menu_action_delete_pocket=Suprimeix del Pocket
+menu_action_archive_pocket=Arxiva en el Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Mostra-ho en el Finder
+menu_action_show_file_windows=Obre la carpeta on es troba
+menu_action_show_file_linux=Obre la carpeta on es troba
+menu_action_show_file_default=Mostra el fitxer
+menu_action_open_file=Obre el fitxer
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Copia l'enllaç de la baixada
+menu_action_go_to_download_page=Vés a la pàgina de la baixada
+menu_action_remove_download=Suprimeix de l'historial
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Cerca
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Cerca de {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Cerca al web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Els articles més interessants del web, seleccionats en funció d'allò que llegiu. Gràcies al Pocket, que ara és part de Mozilla.
+section_disclaimer_topstories_linktext=Vegeu com funciona.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Entesos
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Contingut d'inici del Firefox
+prefs_home_description=Trieu el contingut que voleu a la pantalla d'inici del Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} fila;{num} files
+prefs_search_header=Cerca web
+prefs_topsites_description=El llocs que visiteu més sovint
+prefs_topstories_description2=El contingut més interessant de tot el web, personalitzat per a vós
+prefs_topstories_options_sponsored_label=Articles patrocinats
+prefs_topstories_sponsored_learn_more=Més informació
+prefs_highlights_description=Una selecció dels llocs que heu desat o visitat
+prefs_highlights_options_visited_label=Pàgines visitades
+prefs_highlights_options_download_label=Baixada més recent
+prefs_highlights_options_pocket_label=Pàgines desades al Pocket
+prefs_snippets_description=Actualitzacions de Mozilla i del Firefox
+settings_pane_button_label=Personalitzeu la pàgina de pestanya nova
+settings_pane_topsites_header=Llocs principals
+settings_pane_highlights_header=Destacats
+settings_pane_highlights_options_bookmarks=Adreces d'interès
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Retalls
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Edita
+edit_topsites_edit_button=Edita aquest lloc
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Lloc principal nou
+topsites_form_edit_header=Edita el lloc principal
+topsites_form_title_label=Títol
+topsites_form_title_placeholder=Escriviu el títol
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL d'imatge personalitzada
+topsites_form_url_placeholder=Escriviu o enganxeu un URL
+topsites_form_use_image_link=Utilitza una imatge personalitzada…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Previsualització
+topsites_form_add_button=Afegeix
+topsites_form_save_button=Desa
+topsites_form_cancel_button=Cancel·la
+topsites_form_url_validation=Es necessita un URL vàlid
+topsites_form_image_validation=S'ha produït un error en carregar la imatge. Proveu un altre URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Temes populars:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Mostra més articles
+
+highlights_empty_state=Comenceu a navegar i aquí us mostrarem els millors articles, vídeos i altres pàgines que hàgiu visitat o afegit a les adreces d'interès recentment.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Ja esteu al dia. Torneu més tard per veure més articles populars de {provider}. No podeu esperar? Trieu un tema popular per descobrir els articles més interessants de tot el web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Proveu el Firefox amb les adreces d'interès, l'historial i les contrasenyes d'un altre navegador.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=No, gràcies
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importa-ho ara
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Vaja, s'ha produït un error en carregar aquest contingut.
+error_fallback_default_refresh_suggestion=Actualitzeu la pàgina per tornar-ho a provar.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Elimina la secció
+section_menu_action_collapse_section=Redueix la secció
+section_menu_action_expand_section=Amplia la secció
+section_menu_action_manage_section=Gestiona la secció
+section_menu_action_manage_webext=Gestiona l'extensió
+section_menu_action_add_topsite=Afegeix com a lloc principal
+section_menu_action_move_up=Mou cap amunt
+section_menu_action_move_down=Mou cap avall
+section_menu_action_privacy_notice=Avís de privadesa
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=El vostre Firefox, a tot arreu
+firstrun_content=Accediu a les vostres adreces d'interès, historial, contrasenyes i preferències en tots els vostres dispositius.
+firstrun_learn_more_link=Més informació sobre el Compte del Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Introduïu la vostra adreça electrònica
+firstrun_form_sub_header=per continuar al Firefox Sync.
+
+firstrun_email_input_placeholder=Adreça electrònica
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Si continueu, accepteu les {terms} i l'{privacy}.
+firstrun_terms_of_service=Condicions del servei
+firstrun_privacy_notice=Avís de privadesa
+
+firstrun_continue_to_login=Continua
+firstrun_skip_login=Omet aquest pas
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/cak/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=K'ak'a' ruwi'
+
+header_top_sites=Utziläj taq Ruxaq K'amaya'l
+header_highlights=Taq k'ewachinïk
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Chilab'en ruma {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Tijar ri ruk'utsamaj k'ojlem richin {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Tijaq ruperaj rokem k'utsamaj
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Tz'eton
+type_label_bookmarked=Yakon retal
+type_label_recommended=Rujawaxik
+type_label_pocket=Yakon pa Pocket
+type_label_downloaded=Xqasäx
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Yaketal
+menu_action_remove_bookmark=Tiyuj el ri yaketal
+menu_action_open_new_window=Tijaq pa jun K'ak'a' Tzuwäch
+menu_action_open_private_window=Tijaq pa jun K'ak'a' Ichinan Tzuwäch
+menu_action_dismiss=Tichup ruwäch
+menu_action_delete=Tiyuj el pa ri Natab'äl
+menu_action_pin=Ximoj
+menu_action_unpin=Tosq'opïx
+confirm_history_delete_p1=¿La kan nawajo ye'ayüj el ronojel ri kib'eyal re taq ruxaq re' chi kikojol ri anatab'al?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Man yatikïr ta najäl re b'anïk re'.
+menu_action_save_to_pocket=Tiyak pa Pocket
+menu_action_delete_pocket=Tiyuj el pa Pocket
+menu_action_archive_pocket=Tiyak pa Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Tik'ut pan Finder
+menu_action_show_file_windows=Tijaq K'wayöl Yakwuj
+menu_action_show_file_linux=Tijaq K'wayöl Yakwuj
+menu_action_show_file_default=Tik'ut Yakb'äl
+menu_action_open_file=Tijaq Yakb'äl
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Tiwachib'ëx Ruximonel Qasanïk
+menu_action_go_to_download_page=Tib'e pa Ruxaq Qasanïk
+menu_action_remove_download=Tiyuj el pa Natab'äl
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Tikanöx
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} Tikanöx
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Tikanöx pa Ajk'amaya'l
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Ri nimaläj taq b'anob'äl pan ajk'amaya'l, cha'on rik'in ri ruxe'el ri nasik'ij. Matyox chi re ri Pocket, wakami k'o rik'in ri Mozilla.
+section_disclaimer_topstories_linktext=Tetamäx rub'eyal nisamäj.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ütz, xno' pa nuwi'
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Etamab'äl pa ri Rutikirib'al Firefox
+prefs_home_description=Tacha' achike etamab'äl nawajo' pa ri Rutikirib'al Firefox ruwäch.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} cholaj:{num} taq cholaj
+prefs_search_header=Ajk'amaya'l Kanoxïk
+prefs_topsites_description=Taq ruxaq yalan ye'atz'ët
+prefs_topstories_description2=Nïm rupam chijun ri ajk'amaya'l, ichinan awuma rat
+prefs_topstories_options_sponsored_label=To'on taq B'anob'äl
+prefs_topstories_sponsored_learn_more=Tetamäx ch'aqa' chik
+prefs_highlights_description=Jun rucha'onem ruxaq, ri xayäk o xatz'ët
+prefs_highlights_options_visited_label=Taq Ruxaq Etz'eton
+prefs_highlights_options_download_label=K'a B'a' Keqasäx
+prefs_highlights_options_pocket_label=Taq Ruxaq Eyakon pa Pocket
+prefs_snippets_description=Kik'exoj Mozilla chuqa' Firefox
+settings_pane_button_label=Tawichinaj ri ruxaq richin K'ak'a' Ruwi'
+settings_pane_topsites_header=Utziläj taq ruxaq K'amaya'l
+settings_pane_highlights_header=Taq k'ewachinïk
+settings_pane_highlights_options_bookmarks=Taq yaketal
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Taq pir
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Tinuk'
+edit_topsites_edit_button=Tinuk' re ruxaq k'amaya'l re'
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=K'ak'a' Utziläj Ruxaq K'amaya'l
+topsites_form_edit_header=Tinuk' re Utziläj Ruxaq K'amaya'l re'
+topsites_form_title_label=B'i'aj
+topsites_form_title_placeholder=Tatz'ib'aj jun b'i'aj
+topsites_form_url_label=URL
+topsites_form_image_url_label=Ichinan Ruwachib'al URL
+topsites_form_url_placeholder=Tatz'ib'aj o tatz'ajb'a' jun URL
+topsites_form_use_image_link=Tokisäx jun ichinan ruwachib'al…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Nab'ey tzub'al
+topsites_form_add_button=Titz'aqatisäx
+topsites_form_save_button=Tiyak
+topsites_form_cancel_button=Tiq'at
+topsites_form_url_validation=Ütz URL k'atzinel
+topsites_form_image_validation=Man xsamajib'ëx ta ri wachib'äl. Titojtob'ëx rik'in jun chik URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Nima'q taq Na'oj:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Ketz'et ch'aqa' chik taq B'anob'äl
+
+highlights_empty_state=Katok pa k'amaya'l richin niqak'üt chawäch jeb'ël taq cholna'oj, taq silowachib'äl, chuqa' ch'aqa' chik taq ruxaq k'a b'a' ke'atz'ët o aya'on kan ketal wawe'.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Xaq'i'. Katzolin chik pe richin ye'ak'ül ri utziläj taq rub'anob'al {provider}. ¿La man noyob'en ta? Tacha' jun ütz na'oj richin nawïl ch'aqa' chik taq b'anob'äl e k'o chi rij ri ajk'amaya'l.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Tatojtob'ej Firefox kik'in ri taq ruyaketal, runatab'äl chuqa' taq ewan rutzij jun chik okik'amaya'l.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Mani matyox
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Tijik' pe
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Uy, k'o jun itzel xel toq nisamajib'ëx re rupam re'.
+error_fallback_default_refresh_suggestion=Titzolïx ruxaq richin nitojtob'ëx chik.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Tiyuj Tanaj
+section_menu_action_collapse_section=Tiwulüx Peraj
+section_menu_action_expand_section=Tirik' Peraj
+section_menu_action_manage_section=Tinuk'samajïx Peraj
+section_menu_action_manage_webext=Tinuk'samajïx K'amal
+section_menu_action_add_topsite=Titz'aqatisäx K'ïy Ruwinaq Ruxaq K'amaya'l
+section_menu_action_move_up=Tijotob'äx
+section_menu_action_move_down=Tiqasäx qa
+section_menu_action_privacy_notice=Ichinan na'oj
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Tak'waj ri Firefox Awik'in
+firstrun_content=Ke'ak'waj ri taq yaketal, natab'äl, ewan taq tzij chuqa' ch'aqa' chik taq nuk'ulem pa ronojel taq awokisaxel.
+firstrun_learn_more_link=Tawetamaj ch'aqa' chik pa ruwi' ri Firefox Taqoya'l
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Tatz'ib'aj ri ataqoya'l
+firstrun_form_sub_header=richin yatok pa Firefox Sync.
+
+firstrun_email_input_placeholder=Taqoya'l
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Toq nasamajij qa, nawojqaj ri {terms} chuqa' {privacy}.
+firstrun_terms_of_service=Kojqanem Samaj
+firstrun_privacy_notice=Ichinan Na'oj
+
+firstrun_continue_to_login=Titikïr chik el
+firstrun_skip_login=Tixakalüx re jun ruxak re'
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/crh/strings.properties
@@ -0,0 +1,167 @@
+newtab_page_title=Yañı İlmek
+
+header_top_sites=Zirvedeki Saytlar
+header_highlights=Yüksek-ışıtmalar
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} tevsiyeli
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr={title} içün bağlam menüsini aç
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Bölüm bağlam menüsini aç
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Ziyaret etilgen
+type_label_bookmarked=Saifeimlengen
+type_label_recommended=Trendli
+type_label_pocket=Pocket'ke saqlanğan
+type_label_downloaded=Endirilgen
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Saifeimi
+menu_action_remove_bookmark=Saifeimini Çetleştir
+menu_action_open_new_window=Yañı Bir Pencerede Aç
+menu_action_open_private_window=Yañı bir Hususiy Pencerede Aç
+menu_action_dismiss=Sav
+menu_action_delete=Keçmişten sil
+menu_action_pin=Tüyre
+menu_action_unpin=Tüyrelmegen yap
+confirm_history_delete_p1=Bu saifeniñ her danesini keçmişiñizden silmege istegeniñizden eminsiñizmi?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Bu amel keri yapılalmaz.
+menu_action_save_to_pocket=Pocket'ke Saqla
+menu_action_delete_pocket=Pocket’ten sil
+menu_action_archive_pocket=Pocket’te arhivle
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Tapıcıda Köster
+menu_action_show_file_windows=İhtiva Etken Cilbentni Aç
+menu_action_show_file_linux=İhtiva Etken Cilbentni Aç
+menu_action_show_file_default=Dosyeni Köster
+menu_action_open_file=Dosyeni Aç
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Endirme İlişimini Kopiyala
+menu_action_go_to_download_page=Endirme Saifesine Bar
+menu_action_remove_download=Keçmişten Çetleştir
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Qıdır
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} Qıdırması
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Ağ'da qıdır
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Tamam, añladım
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox Ev Muhtevası
+prefs_home_description=Firefox Ev saifesinde körmege istegeniñiz muhtevanı saylañız.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} satır;{num} satır
+prefs_search_header=Ağ Qıdırması
+prefs_topsites_description=En çoq ziyaret etkeniñiz saytlar
+prefs_topstories_description2=İnternet etrafından mükemmel muhteva, siziñ içün şahsiyleştirilgen
+prefs_topstories_options_sponsored_label=Sponsorlı Hikâyeler
+prefs_topstories_sponsored_learn_more=Daha çoq ögren
+prefs_highlights_description=Saqlağan yaki ziyaret etken olğanıñız saytlarnıñ bir saylamı
+prefs_highlights_options_visited_label=Ziyaret etilgen saifeler
+prefs_highlights_options_download_label=Eñ Deminki Endirme
+prefs_highlights_options_pocket_label=Pocket’ke Saqlanğan Saifeler
+prefs_snippets_description=Mozilla ve Firefox’tan Yañartmalar
+settings_pane_button_label=Yañı İlmek saifeñizni Özelleştiriñiz
+settings_pane_topsites_header=Eñ Üst Saytlar
+settings_pane_highlights_header=Yüksek-ışıtmalar
+settings_pane_highlights_options_bookmarks=Saifeimleri
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Qırpıntılar
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Tahrir Et
+edit_topsites_edit_button=Bu saytnı tahrir et
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Yañı Üst Sayt
+topsites_form_edit_header=Üst Saytnı Tahrir Et
+topsites_form_title_label=Serlevha
+topsites_form_title_placeholder=Bir serlevha kirset
+topsites_form_url_label=URL
+topsites_form_image_url_label=Özel Suret URL'si
+topsites_form_url_placeholder=Bir URL tuşlañız yaki yapıştırıñız
+topsites_form_use_image_link=Özel bir suret qullan…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Ögbaqış
+topsites_form_add_button=Ekle
+topsites_form_save_button=Saqla
+topsites_form_cancel_button=Vazgeç
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Popülâr Mevzular:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Daha Çoq Hikâye Köster
+
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Hayır, Teşekkürler
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Kesimni Çetleştir
+section_menu_action_collapse_section=Kesimni Eştir
+section_menu_action_expand_section=Kesimni Cayıldır
+section_menu_action_manage_section=Kesimni İdare Et
+section_menu_action_add_topsite=Zirvedeki Sayt Ekle
+section_menu_action_move_up=Yuqarı Avuştır
+section_menu_action_move_down=Aşağı Avuştır
+section_menu_action_privacy_notice=Hususiyat Tebliği
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/cs/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Nový panel
+
+header_top_sites=Top stránky
+header_highlights=Vybrané
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Doporučení ze služby {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Otevřít kontextovou nabídku pro {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Otevřít kontextovou nabídku sekce
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Navštívené
+type_label_bookmarked=V záložkách
+type_label_recommended=Populární
+type_label_pocket=Uloženo do služby Pocket
+type_label_downloaded=Staženo
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Přidat do záložek
+menu_action_remove_bookmark=Odebrat záložku
+menu_action_open_new_window=Otevřít v novém okně
+menu_action_open_private_window=Otevřít v novém anonymním okně
+menu_action_dismiss=Skrýt
+menu_action_delete=Smazat z historie
+menu_action_pin=Připnout
+menu_action_unpin=Odepnout
+confirm_history_delete_p1=Opravdu chcete smazat všechny výskyty této stránky z vaší historie?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Tuto akci nelze vzít zpět.
+menu_action_save_to_pocket=Uložit do služby Pocket
+menu_action_delete_pocket=Smazat ze služby Pocket
+menu_action_archive_pocket=Archivovat do služby Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Zobrazit ve Finderu
+menu_action_show_file_windows=Otevřít složku
+menu_action_show_file_linux=Otevřít složku
+menu_action_show_file_default=Ukázat soubor
+menu_action_open_file=Otevřít soubor
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Kopírovat stahovaný odkaz
+menu_action_go_to_download_page=Přejít na stránku stahování
+menu_action_remove_download=Odebrat z historie
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Vyhledat
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Vyhledat pomocí {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Vyhledat na webu
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Nejzajímavější příběhy na webu vybrané podle toho, co sami čtete. To je služba Pocket od Mozilly.
+section_disclaimer_topstories_linktext=Zjistit, jak to funguje.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ok, rozumím
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Obsah domovské stránky Firefoxu
+prefs_home_description=Vyberte obsah, který chcete mít na výchozí domovské stránce Firefoxu.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} řádek;{num} řádky;{num} řádků
+prefs_search_header=Vyhledávání na webu
+prefs_topsites_description=Nejnavštěvovanější stránky
+prefs_topstories_description2=Skvělý obsah z celého webu, vybraný speciálně pro vás
+prefs_topstories_options_sponsored_label=Sponzorované příběhy
+prefs_topstories_sponsored_learn_more=Zjistit více
+prefs_highlights_description=Výběr z uložených nebo navštívených stránek
+prefs_highlights_options_visited_label=Navštívené stránky
+prefs_highlights_options_download_label=Nedávná stahování
+prefs_highlights_options_pocket_label=Stránky uložené do služby Pocket
+prefs_snippets_description=Informace od Mozilly a o Firefoxu
+settings_pane_button_label=Přizpůsobení stránky nového panelu
+settings_pane_topsites_header=Top stránky
+settings_pane_highlights_header=Vybrané
+settings_pane_highlights_options_bookmarks=Záložky
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Útržky
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Upravit
+edit_topsites_edit_button=Upravit tuto stránku
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nová top stránka
+topsites_form_edit_header=Upravit top stránku
+topsites_form_title_label=Nadpis
+topsites_form_title_placeholder=Zadejte název
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL adresa vlastního obrázku
+topsites_form_url_placeholder=Zadejte nebo vložte URL adresu
+topsites_form_use_image_link=Použít vlastní obrázek…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Náhled
+topsites_form_add_button=Přidat
+topsites_form_save_button=Uložit
+topsites_form_cancel_button=Zrušit
+topsites_form_url_validation=Je vyžadována platná URL
+topsites_form_image_validation=Obrázek se nepodařilo načíst. Zkuste jinou URL adresu.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Populární témata:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Zobrazit více příběhů
+
+highlights_empty_state=Začněte prohlížet a my vám zde ukážeme některé skvělé články, videa a další stránky, které jste nedávno viděli nebo uložili do záložek.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Už jste všechno přečetli. Další příběhy ze služby {provider} tu najdete zase později. Ale pokud se nemůžete dočkat, vyberte své oblíbené téma a podívejte se na další velké příběhy z celého webu.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Vyzkoušejte Firefox se záložkami, historií a hesly z jiného vašeho prohlížeče.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Ne, děkuji
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importovat nyní
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Jejda, při načítání tohoto obsahu se něco pokazilo.
+error_fallback_default_refresh_suggestion=Obnovte prosím stránku a zkuste to znovu.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Odebrat sekci
+section_menu_action_collapse_section=Sbalit sekci
+section_menu_action_expand_section=Rozbalit sekci
+section_menu_action_manage_section=Nastavení sekce
+section_menu_action_manage_webext=Správa rozšíření
+section_menu_action_add_topsite=Přidat mezi top stránky
+section_menu_action_move_up=Posunout nahoru
+section_menu_action_move_down=Posunout dolů
+section_menu_action_privacy_notice=Zásady ochrany osobních údajů
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Vezměte si Firefox s sebou
+firstrun_content=Mějte své záložky, historii i uložená hesla s sebou na všech svých zařízeních.
+firstrun_learn_more_link=Zjistěte více o účtech Firefoxu
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Zadejte svoji e-mailovou adresu
+firstrun_form_sub_header=a používejte službu Firefox Sync.
+
+firstrun_email_input_placeholder=E-mail
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Pokračováním souhlasíte s {terms} a {privacy}.
+firstrun_terms_of_service=Podmínkami používání služby
+firstrun_privacy_notice=Zásadami ochrany soukromí
+
+firstrun_continue_to_login=Pokračovat
+firstrun_skip_login=Přeskočit tento krok
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/cy/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Tab Newydd
+
+header_top_sites=Hoff Wefannau
+header_highlights=Goreuon
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Argymhellwyd gan {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Agor dewislen cynnwys {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Agor dewislen cyd-destun yr adran
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Ymwelwyd
+type_label_bookmarked=Nod Tudalen
+type_label_recommended=Trendio
+type_label_pocket=Wedi ei gadw i Pocket
+type_label_downloaded=Wedi eu Llwytho i Lawr
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Nod Tudalen
+menu_action_remove_bookmark=Tynnu Nod Tudalen
+menu_action_open_new_window=Agor Ffenestr Newydd
+menu_action_open_private_window=Agor mewn Ffenestr Preifat Newydd
+menu_action_dismiss=Cau
+menu_action_delete=Dileu o'r Hanes
+menu_action_pin=Pinio
+menu_action_unpin=Dad-binio
+confirm_history_delete_p1=Ydych chi'n siŵr eich bod chi am ddileu pob enghraifft o'r dudalen hon o'ch hanes?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Nid oes modd dadwneud hyn.
+menu_action_save_to_pocket=Cadw i Pocket
+menu_action_delete_pocket=Dileu o Pocket
+menu_action_archive_pocket=Archifo i Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Dangos yn Finder
+menu_action_show_file_windows=Agor Ffolder Cynhwysol
+menu_action_show_file_linux=Agor Ffolder Cynhwysol
+menu_action_show_file_default=Dangos Ffeil
+menu_action_open_file=Agor Ffeil
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Copïo Dolen Llwytho i Lawr
+menu_action_go_to_download_page=Mynd i'r Dudalen Llwytho i Lawr
+menu_action_remove_download=Tynnu o'r Hanes
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Chwilio
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} Chwilio
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Chwilio'r We
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Y straeon mwyaf diddorol ar y we, wedi eu dewis ar sail yr hyn rydych yn eu darllen. Gan Pocket, sydd nawr yn rhan o Mozilla.
+section_disclaimer_topstories_linktext=Dyma sut mae'n gweithio...
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Iawn, deall
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Cynnwys Cartref Firefox
+prefs_home_description=Dewis pa gynnwys rydych eisiau ar eich sgrin Firefox Cartref.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} rhes;{num} rhes
+prefs_search_header=Chwilio'r We
+prefs_topsites_description=Y gwefannau rydych yn ymweld â nhw amlaf
+prefs_topstories_description2=Cynnwys gwych o ar draws y we, wedi ei ddewis yn arbennig i chi
+prefs_topstories_options_sponsored_label=Straeon wedi eu Noddi
+prefs_topstories_sponsored_learn_more=Dysgu rhagor
+prefs_highlights_description=Detholiad o wefannau rydych wedi eu cadw neu ymweld â nhw
+prefs_highlights_options_visited_label=Tudalennau Ymwelwyd â Nhw
+prefs_highlights_options_download_label=Llwytho i Lawr Mwyaf Diweddar
+prefs_highlights_options_pocket_label=Tudalennau wedi eu Cadw i Pocket
+prefs_snippets_description=Diweddariadau gan Mozilla a Firefox
+settings_pane_button_label=Cyfaddasu eich tudalen Tab Newydd
+settings_pane_topsites_header=Hoff Wefannau
+settings_pane_highlights_header=Goreuon
+settings_pane_highlights_options_bookmarks=Nodau Tudalen
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Tameidiau
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Golygu
+edit_topsites_edit_button=Golygu'r wefan
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Hoff Wefan Newydd
+topsites_form_edit_header=Golygu'r Hoff Wefan
+topsites_form_title_label=Teitl
+topsites_form_title_placeholder=Rhoi teitl
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL Delwedd Gyfaddas
+topsites_form_url_placeholder=Teipio neu ludo URL
+topsites_form_use_image_link=Defnyddio delwedd gyfaddas…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Rhagolwg
+topsites_form_add_button=Ychwanegu
+topsites_form_save_button=Cadw
+topsites_form_cancel_button=Diddymu
+topsites_form_url_validation=Mae angen URL Ddilys
+topsites_form_image_validation=Methodd y ddelwedd â llwytho. Defnyddiwch URL gwahanol.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Pynciau Poblogaidd:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Gweld Rhagor o Straeon
+
+highlights_empty_state=Cychwynnwch bori ac fe ddangoswn rhai erthyglau, fideos a thudalennau eraill difyr rydych wedi ymweld â nhw'n ddiweddar neu wedi gosod nod tudalen arnyn nhw yma.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Rydych wedi dal i fynDewch nôl rhywbryd eto am fwy o'r straeon pwysicaf gan {provider}. Methu aros? Dewiswch bwnc poblogaidd i ganfod straeon da o ar draws y we. 
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Profwch Firefox gyda nodau tudalen, hanes a chyfrineiriau o borwr arall.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Dim Diolch
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Mewnforio Nawr
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Wps, aeth rhywbeth o'i le wrth llwytho'r cynnwys hwn.
+error_fallback_default_refresh_suggestion=Adnewyddu'r dudalen i geisio eto.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Tynnu'r Adran
+section_menu_action_collapse_section=Cau'r Adran
+section_menu_action_expand_section=Estyn yr Adran
+section_menu_action_manage_section=Rheoli'r Adran
+section_menu_action_manage_webext=Rheoli Estyniad
+section_menu_action_add_topsite=Ychwanegu Hoff Wefan
+section_menu_action_move_up=Symud i Fyny
+section_menu_action_move_down=Symud i Lawr
+section_menu_action_privacy_notice=Hysbysiad Preifatrwydd
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Mynd â Firefox gyda Chi
+firstrun_content=Cewch eich nodau tudalen, hanes, cyfrineiriau a gosodiadau eraill ar eich holl ddyfeisiau.
+firstrun_learn_more_link=Dysgu rhagor am Gyfrif Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Rhowch eich e-bost
+firstrun_form_sub_header=i barhau i Firefox Sync.
+
+firstrun_email_input_placeholder=E-bost
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Gan barhau, rydych yn cytuno i delerau'r {terms} a'r {privacy}.
+firstrun_terms_of_service=Amodau Gwasanaeth
+firstrun_privacy_notice=Hysbysiad Preifatrwydd
+
+firstrun_continue_to_login=Parhau
+firstrun_skip_login=Hepgor y cam hwn
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/da/strings.properties
@@ -0,0 +1,216 @@
+newtab_page_title=Nyt faneblad
+
+header_top_sites=Mest besøgte websider
+header_highlights=Fremhævede
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Anbefalet af {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Åbn genvejsmenuen for {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Åbn genvejsmenuen afsnit
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Besøgt
+type_label_bookmarked=Bogmærket
+type_label_recommended=Populært
+type_label_pocket=Gemt til Pocket
+type_label_downloaded=Hentet
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Bogmærk
+menu_action_remove_bookmark=Fjern bogmærke
+menu_action_open_new_window=Åbn i et nyt vindue
+menu_action_open_private_window=Åbn i et nyt privat vindue
+menu_action_dismiss=Afvis
+menu_action_delete=Slet fra historik
+menu_action_pin=Fastgør
+menu_action_unpin=Frigør
+confirm_history_delete_p1=Er du sikker på, at du vil slette alle forekomster af denne side fra din historik?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Denne handling kan ikke fortrydes.
+menu_action_save_to_pocket=Gem til Pocket
+menu_action_delete_pocket=Slet fra Pocket
+menu_action_archive_pocket=Arkiver i Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Vis i Finder
+menu_action_show_file_windows=Åbn hentningsmappe
+menu_action_show_file_linux=Åbn hentningsmappe
+menu_action_show_file_default=Vis fil
+menu_action_open_file=Åbn fil
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Kopier linkadresse
+menu_action_go_to_download_page=Gå til siden, filen blev hentet fra
+menu_action_remove_download=Fjern fra historik
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Søg
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name}-søgning
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Søg på internettet
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=De mest interessante historier på nettet, udvalgt på baggrund af det, du læser. Fra Pocket, nu en del af Mozilla.
+section_disclaimer_topstories_linktext=Læs hvordan det fungerer.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ok, forstået
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Indhold på Firefox' startside
+prefs_home_description=Vælg det indhold, du vil have vist på din startside i Firefox.
+prefs_restore_defaults_button=Gendan standarder
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} række;{num} rækker
+prefs_search_header=Søgning på internettet
+prefs_topsites_description=Mest besøgte websider
+prefs_topstories_description2=Spændende indhold fra nettet, specielt udvalgt til dig
+prefs_topstories_options_sponsored_label=Sponsorerede historier
+prefs_topstories_sponsored_learn_more=Læs mere
+prefs_highlights_description=Et afsnit med sider, du har gemt eller besøgt
+prefs_highlights_options_visited_label=Besøgte sider
+prefs_highlights_options_download_label=Seneste filhentninger
+prefs_highlights_options_pocket_label=Sider gemt til Pocket
+prefs_snippets_description=Nyheder fra Mozilla og Firefox
+settings_pane_button_label=Tilpas siden Nyt faneblad
+settings_pane_header=Indstillinger for Nyt faneblad
+settings_pane_body2=Vælg, hvad du vil se på denne side.
+settings_pane_search_header=Søgning
+settings_pane_search_body=Søg på nettet fra Nyt faneblad.
+settings_pane_topsites_header=Mest besøgte websider
+settings_pane_topsites_body=Adgang til de websider, du besøger oftest.
+settings_pane_topsites_options_showmore=Vis to rækker
+settings_pane_highlights_header=Fremhævede
+settings_pane_highlights_body2=Find tilbage til interessant indhold, du har besøgt eller gemt et bogmærke til for nylig.
+settings_pane_highlights_options_bookmarks=Bogmærker
+settings_pane_highlights_options_visited=Besøgte websider
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Notitser
+settings_pane_snippets_body=Læs korte opdateringer fra Mozilla om Firefox, internet-kultur og lidt underholdning fra tid til anden.
+settings_pane_done_button=Færdig
+settings_pane_topstories_options_sponsored=Vis sponsorerede historier
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Rediger
+edit_topsites_edit_button=Rediger denne webside
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Ny webside
+topsites_form_edit_header=Rediger mest besøgte webside
+topsites_form_title_label=Titel
+topsites_form_title_placeholder=Indtast en titel
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL til selvvalgt billede
+topsites_form_url_placeholder=Indtast eller indsæt en URL
+topsites_form_use_image_link=Brug selvvalgt billede…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Vis prøve
+topsites_form_add_button=Tilføj
+topsites_form_save_button=Gem
+topsites_form_cancel_button=Annuller
+topsites_form_url_validation=Gyldig URL påkrævet
+topsites_form_image_validation=Kunne ikke indlæse billede. Prøv en anden URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Populære emner:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Se flere historier
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=Opdag indhold af høj kvalitet, som du måske ellers ikke ville have opdaget. Indholdet kommer fra Pocket, der nu er en del af Mozilla.
+
+highlights_empty_state=Gå i gang med at browse, så vil vi vise dig nogle af de artikler, videoer og andre sider, du har besøgt eller gemt et bogmærke til for nylig.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Der er ikke flere nye historier. Kom tilbage senere for at se flere tophistorier fra {provider}. Kan du ikke vente? Vælg et populært emne og find flere spændende historier fra hele verden.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Prøv Firefox med bogmærkerne, historikken og adgangskoderne fra en anden browser.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Nej tak
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importer nu
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Hovsa. Noget gik galt ved indlæsning af indholdet.
+error_fallback_default_refresh_suggestion=Prøv igen ved at genindlæse siden.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Fjern afsnit
+section_menu_action_collapse_section=Sammenfold afsnit
+section_menu_action_expand_section=Udvid afsnit
+section_menu_action_manage_section=Håndter afsnit
+section_menu_action_manage_webext=Håndter udvidelse
+section_menu_action_add_topsite=Tilføj ny webside
+section_menu_action_move_up=Flyt op
+section_menu_action_move_down=Flyt ned
+section_menu_action_privacy_notice=Privatlivspolitik
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Tag Firefox med dig
+firstrun_content=Få adgang til din historik, dine bogmærker, adgangskoder og andre indstillinger på alle dine enheder.
+firstrun_learn_more_link=Læs mere om Firefox-konti
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Indtast din mailadresse
+firstrun_form_sub_header=for at fortsætte til Firefox Sync.
+
+firstrun_email_input_placeholder=Mailadresse
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Ved at fortsætte godkender du vores {terms} og {privacy}.
+firstrun_terms_of_service=tjenestevilkår
+firstrun_privacy_notice=privatlivspolitik
+
+firstrun_continue_to_login=Fortsæt
+firstrun_skip_login=Spring dette trin over
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/de/strings.properties
@@ -0,0 +1,192 @@
+newtab_page_title=Neuer Tab
+
+header_top_sites=Wichtige Seiten
+header_highlights=Überblick
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Empfohlen von {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Kontextmenü für {title} öffnen
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Kontextmenü des Abschnitts öffnen
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Besucht
+type_label_bookmarked=Lesezeichen
+type_label_recommended=Beliebt
+type_label_pocket=Bei Pocket gespeichert
+type_label_downloaded=Heruntergeladen
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Lesezeichen
+menu_action_remove_bookmark=Lesezeichen entfernen
+menu_action_open_new_window=In neuem Fenster öffnen
+menu_action_open_private_window=In neuem privaten Fenster öffnen
+menu_action_dismiss=Entfernen
+menu_action_delete=Aus Chronik löschen
+menu_action_pin=Anheften
+menu_action_unpin=Ablösen
+confirm_history_delete_p1=Soll wirklich jede Instanz dieser Seite aus Ihrer Chronik gelöscht werden?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Diese Aktion kann nicht rückgängig gemacht werden.
+menu_action_save_to_pocket=Bei Pocket speichern
+menu_action_delete_pocket=Aus Pocket löschen
+menu_action_archive_pocket=In Pocket archivieren
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Im Finder anzeigen
+menu_action_show_file_windows=Beinhaltenden Ordner öffnen
+menu_action_show_file_linux=Ziel-Ordner öffnen
+menu_action_show_file_default=Datei anzeigen
+menu_action_open_file=Datei öffnen
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Download-Link kopieren
+menu_action_go_to_download_page=Zur Download-Seite gehen
+menu_action_remove_download=Aus Chronik entfernen
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Suchen
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name}-Suche
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Das Web durchsuchen
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Die interessanten Geschichten im Internet, ausgewählt nach Ihrem Geschmack. Von Pocket, jetzt Teil von Mozilla.
+section_disclaimer_topstories_linktext=Erfahren Sie, wie es funktioniert.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ok, verstanden
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Inhalte des Firefox-Startbildschirms
+prefs_home_description=Wählen Sie, welche Inhalte auf Ihrem Firefox-Startbildschirm angezeigt werden sollen.
+prefs_restore_defaults_button=Standard wiederherstellen
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} Zeile;{num} Zeilen
+prefs_search_header=Internetsuche
+prefs_topsites_description=Die von die Ihnen am meisten besuchten Websites
+prefs_topstories_description2=Tolle Inhalte aus dem ganzen Internet, für Sie personalisiert
+prefs_topstories_options_sponsored_label=Gesponserte Geschichten
+prefs_topstories_sponsored_learn_more=Weitere Informationen
+prefs_highlights_description=Eine Auswahl von Websites, die Sie gespeichert oder besucht haben
+prefs_highlights_options_visited_label=Besuchte Seiten
+prefs_highlights_options_download_label=Neueste Downloads
+prefs_highlights_options_pocket_label=Bei Pocket gespeicherte Seiten
+prefs_snippets_description=Neuigkeiten von Mozilla und Firefox
+settings_pane_button_label=Einstellungen für neue Tabs anpassen
+settings_pane_header=Einstellungen für neue Tabs
+settings_pane_body2=Wählen Sie aus, was auf dieser Seite angezeigt wird.
+settings_pane_search_header=Suche
+settings_pane_search_body=Suchen Sie aus einem neuen Tab im Internet.
+settings_pane_topsites_header=Wichtige Seiten
+settings_pane_topsites_body=Schneller Zugriff auf Ihre meistbesuchten Websites.
+settings_pane_topsites_options_showmore=Zwei Reihen anzeigen
+settings_pane_highlights_header=Überblick
+settings_pane_highlights_body2=Finden Sie schnell wieder zu den wichtigen Seiten zurück, die Sie kürzlich besucht oder als Lesezeichen gespeichert haben.
+settings_pane_highlights_options_bookmarks=Lesezeichen
+settings_pane_highlights_options_visited=Besuchte Websites
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Kurzinformationen
+settings_pane_snippets_body=Lesen Sie kurze Neuigkeiten von Mozilla über Firefox, die Internetkultur und gelegentlich mal ein Meme.
+settings_pane_done_button=Fertig
+settings_pane_topstories_options_sponsored=Gesponserte Geschichten anzeigen
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Bearbeiten
+edit_topsites_edit_button=Diese Website bearbeiten
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Neue wichtige Seite
+topsites_form_edit_header=Wichtige Seite bearbeiten
+topsites_form_title_label=Titel
+topsites_form_title_placeholder=Name eingeben
+topsites_form_url_label=Adresse
+topsites_form_image_url_label=URL von benutzerdefinierter Grafik
+topsites_form_url_placeholder=Eine Adresse eingeben oder einfügen
+topsites_form_use_image_link=Eine benutzerdefinierte Grafik verwenden…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Vorschau
+topsites_form_add_button=Hinzufügen
+topsites_form_save_button=Speichern
+topsites_form_cancel_button=Abbrechen
+topsites_form_url_validation=Gültige URL erforderlich
+topsites_form_image_validation=Grafik konnte nicht geladen werden. Verwenden Sie eine andere URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Beliebte Themen:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Weitere Nachrichten ansehen
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=Entdecken Sie qualitativ hochwertige Inhalte mithilfe von Pocket (jetzt Teil von Mozilla), die Sie ansonsten verpassen würden.
+
+highlights_empty_state=Surfen Sie los und wir zeigen Ihnen hier einige der interessanten Artikel, Videos und anderen Seiten, die Sie kürzlich besucht oder als Lesezeichen gespeichert haben.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Jetzt kennen Sie die Neuigkeiten. Schauen Sie später wieder vorbei, um neue Informationen von {provider} zu erhalten. Können Sie nicht warten? Wählen Sie ein beliebtes Thema und lesen Sie weitere interessante Geschichten aus dem Internet.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Probieren Sie Firefox aus und importieren Sie die Lesezeichen, Chronik und Passwörter eines anderen Browsers.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Nein, danke
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Jetzt importieren
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Beim Laden dieses Inhalts ist ein Fehler aufgetreten.
+error_fallback_default_refresh_suggestion=Aktualisieren Sie die Seite, um es erneut zu versuchen.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Abschnitt entfernen
+section_menu_action_collapse_section=Abschnitt einklappen
+section_menu_action_expand_section=Abschnitt ausklappen
+section_menu_action_manage_section=Abschnitt verwalten
+section_menu_action_add_topsite=Wichtige Seite hinzufügen
+section_menu_action_move_up=Nach oben schieben
+section_menu_action_move_down=Nach unten schieben
+section_menu_action_privacy_notice=Datenschutzhinweis
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/dsb/strings.properties
@@ -0,0 +1,192 @@
+newtab_page_title=Nowy rejtark
+
+header_top_sites=Nejcesćej woglědane sedła
+header_highlights=Wjerški
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Wót {provider} dopórucony
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Kontekstowy meni za {title} wócyniś
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Kontekstowy meni wótrězka wócyniś
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Woglědany
+type_label_bookmarked=Ako cytańske znamje skłaźony
+type_label_recommended=Popularny
+type_label_pocket=Do Pocket skłaźony
+type_label_downloaded=Ześěgnjony
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Ako cytańske znamje składowaś
+menu_action_remove_bookmark=Cytańske znamje wótpóraś
+menu_action_open_new_window=W nowem woknje wócyniś
+menu_action_open_private_window=W nowem priwatnem woknje wócyniś
+menu_action_dismiss=Zachyśiś
+menu_action_delete=Z historije lašowaś
+menu_action_pin=Pśipěś
+menu_action_unpin=Wótpěś
+confirm_history_delete_p1=Cośo napšawdu kuždu instancu toś togo boka ze swójeje historije lašowaś?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Toś ta akcija njedajo se anulěrowaś.
+menu_action_save_to_pocket=Pla Pocket składowaś
+menu_action_delete_pocket=Z Pocket wulašowaś
+menu_action_archive_pocket=W Pocket archiwěrowaś
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=W Finder pokazaś
+menu_action_show_file_windows=Wopśimujucy zarědnik wócyniś
+menu_action_show_file_linux=Wopśimujucy zarědnik wócyniś
+menu_action_show_file_default=Dataju pokazaś
+menu_action_open_file=Dataju wócyniś
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Ześěgnjeński wótkaz kopěrowaś
+menu_action_go_to_download_page=K ześěgnjeńskemu bokoju pśejś
+menu_action_remove_download=Z historije wótwónoźeś
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Pytaś
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Z {search_engine_name} pytaś
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Web pśepytaś
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Nejzajmnjejše tšojenja we webje, wubrane na zakłaźe togo, což sćo cytał. Z Pocket, něnto źěl Mozilla.
+section_disclaimer_topstories_linktext=Zgóńśo, kak to funkcioněrujo.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=W pórěźe, som zrozměł
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Wopśimjeśe startowego boka Firefox
+prefs_home_description=Wubjeŕśo, kótare wopśimjeśe cośo na swójej startowej wobrazowce Firefox měś.
+prefs_restore_defaults_button=Standard wótnowiś
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} smužka;{num} smužce;{num}smužki;{num} smužkow
+prefs_search_header=Webpytanje
+prefs_topsites_description=Sedła, ku kótarymž se nejcesćej woglědujośo
+prefs_topstories_description2=Wjelicne wopśimjeśe z cełego weba, wubrane specielnje za was
+prefs_topstories_options_sponsored_label=Sponsorowane tšojenja pokazaś
+prefs_topstories_sponsored_learn_more=Dalšne informacije
+prefs_highlights_description=Wuběrk websedłow, kótarež sćo składował abo se woglědał
+prefs_highlights_options_visited_label=Woglědane boki
+prefs_highlights_options_download_label=Nejnowše ześěgnjenje
+prefs_highlights_options_pocket_label=Boki skłaźone do Pocket
+prefs_snippets_description=Aktualizacije wót Mozilla a Firefox
+settings_pane_button_label=Bok wašogo nowego rejtarka pśiměriś
+settings_pane_header=Nastajenja nowego rejtarka składowaś
+settings_pane_body2=Wubjeŕśo, což se na toś tom boku pokazujo.
+settings_pane_search_header=Pytaś
+settings_pane_search_body=Pśepytajśo web ze swójogo nowego rejtarka.
+settings_pane_topsites_header=Nejcesćej woglědane sedła
+settings_pane_topsites_body=Wócyńśo websedła, kótarež sćo se nejcesćej woglědał.
+settings_pane_topsites_options_showmore=Dwě smužki pokazaś
+settings_pane_highlights_header=Wjerški
+settings_pane_highlights_body2=Namakajśo swóju drogu slědk k zajmnym bokam, kótarež sćo se njedawno woglědał abo ako cytańske znamjenja składł.
+settings_pane_highlights_options_bookmarks=Cytańske znamjenja
+settings_pane_highlights_options_visited=Woglědane sedła
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Kuski
+settings_pane_snippets_body=Cytajśo krotke aktualizacije wót Mozilla wó Firefox, internetnej kulturje a casy meme.
+settings_pane_done_button=Gótowo
+settings_pane_topstories_options_sponsored=Sponsorowane tšojenja pokazaś
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Wobźěłaś
+edit_topsites_edit_button=Toś to sedło wobźěłaś
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nowe nejcesćej woglědane sedło
+topsites_form_edit_header=Nejcesćej woglědane sedło wobźěłaś
+topsites_form_title_label=Titel
+topsites_form_title_placeholder=Titel zapódaś
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL swójskego wobraza
+topsites_form_url_placeholder=URL zapódaś abo zasajźiś
+topsites_form_use_image_link=Swójski wobraz wužywaś…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Pśeglěd
+topsites_form_add_button=Pśidaś
+topsites_form_save_button=Składowaś
+topsites_form_cancel_button=Pśetergnuś
+topsites_form_url_validation=Płaśiwy URL trěbny
+topsites_form_image_validation=Wobraz njedajo se zacytaś. Wopytajśo drugi URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Woblubowane temy:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Dalšne powěźeńki se woglědaś
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=Namakajśo wopśimjeśe wusokeje kwality, kótarež by hować wjelgin felowało, z pomocu Pocket, kótaryž jo něnto źěl Mozilla.
+
+highlights_empty_state=Zachopśo pśeglědowaś, a pokažomy někotare wjelicne nastawki, wideo a druge boki, kótarež sćo se njedawno woglědał abo how ako cytańske znamjenja składował.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=To jo nachylu wšykno. Wrośćo se pózdźej wjelicnych tšojeńkow dla wót {provider}. Njamóžośo cakaś? Wubjeŕśo woblubowanu temu, aby dalšne wjelicne tšojeńka we webje namakał.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Wopytajśo Firefox z cytanskimi znamjenjami, historiju a gronidłami z drugego wobglědowaka.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Ně, źěkujom se
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Něnto importěrowaś
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Hopla, pśi cytanju toś togo wopśimjeśa njejo se něco raźiło.
+error_fallback_default_refresh_suggestion=Aktualizěrujśo bok, aby hyšći raz wopytał.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Wótrězk wótwónoźeś
+section_menu_action_collapse_section=Wótrězk schowaś
+section_menu_action_expand_section=Wótrězk pokazaś
+section_menu_action_manage_section=Wótrězk zastojaś
+section_menu_action_add_topsite=Woblubowane sedło pśidaś
+section_menu_action_move_up=Górjej
+section_menu_action_move_down=Dołoj
+section_menu_action_privacy_notice=Powěźeńka priwatnosći
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/el/strings.properties
@@ -0,0 +1,183 @@
+newtab_page_title=Νέα καρτέλα
+
+header_top_sites=Κορυφαίες ιστοσελίδες
+header_highlights=Κορυφαίες στιγμές
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Προτεινόμενο από τον πάροχο {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Άνοιγμα μενού επιλογών για το {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Άνοιγμα του μενού επιλογών ενότητας
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Από ιστορικό
+type_label_bookmarked=Από σελιδοδείκτες
+type_label_recommended=Τάσεις
+type_label_pocket=Αποθηκεύτηκε στο Pocket
+type_label_downloaded=Λήψεις
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Προσθήκη σελιδοδείκτη
+menu_action_remove_bookmark=Αφαίρεση σελιδοδείκτη
+menu_action_open_new_window=Άνοιγμα σε νέο παράθυρο
+menu_action_open_private_window=Άνοιγμα σε νέο ιδιωτικό παράθυρο
+menu_action_dismiss=Απόρριψη
+menu_action_delete=Διαγραφή από ιστορικό
+menu_action_pin=Καρφίτσωμα
+menu_action_unpin=Ξεκαρφίτσωμα
+confirm_history_delete_p1=Θέλετε σίγουρα να διαγράψετε κάθε παρουσία της σελίδας αυτής από το ιστορικό σας;
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Αυτή η ενέργεια δεν μπορεί να αναιρεθεί.
+menu_action_save_to_pocket=Αποθήκευση στο Pocket
+menu_action_delete_pocket=Διαγραφή από το Pocket
+menu_action_archive_pocket=Αρχειοθέτηση στο Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Εμφάνιση στο Finder
+menu_action_show_file_default=Προβολή αρχείου
+menu_action_open_file=Άνοιγμα αρχείου
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_remove_download=Αφαίρεση από το ιστορικό
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Αναζήτηση
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Αναζήτηση {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Αναζήτηση στον ιστό
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Οι πιο ενδιαφέρουσες ιστορίες στο διαδίκτυο, επιλεγμένες βάσει όσων διαβάζετε. Από το Pocket, πλέον μέλος της Mozilla.
+section_disclaimer_topstories_linktext=Μάθετε πώς λειτουργεί.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Εντάξει, το 'πιασα
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Περιεχόμενο αρχικής σελίδας Firefox
+prefs_home_description=Επιλέξτε τι περιεχόμενο θέλετε στην αρχική σελίδα του Firefox σας.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} σειρά;{num} σειρές
+prefs_search_header=Αναζήτηση ιστού
+prefs_topsites_description=Οι ιστοσελίδες που επισκέπτεστε περισσότερο
+prefs_topstories_options_sponsored_label=Χορηγούμενες ιστορίες
+prefs_topstories_sponsored_learn_more=Μάθετε περισσότερα
+prefs_highlights_description=Μια συλλογή ιστοσελίδων που έχετε αποθηκεύσει ή επισκεφθεί
+prefs_snippets_description=Ενημερώσεις από τη Mozilla και το Firefox
+settings_pane_button_label=Προσαρμογή της σελίδας Νέας Καρτέλας
+settings_pane_topsites_header=Κορυφαίες ιστοσελίδες
+settings_pane_highlights_header=Κορυφαίες στιγμές
+settings_pane_highlights_options_bookmarks=Σελιδοδείκτες
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Αποσπάσματα
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Επεξεργασία
+edit_topsites_edit_button=Επεξεργασία ιστοσελίδας
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Νέα κορυφαία ιστοσελίδα
+topsites_form_edit_header=Επεξεργασία κορυφαίας ιστοσελίδας
+topsites_form_title_label=Τίτλος
+topsites_form_title_placeholder=Εισάγετε έναν τίτλο
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL προσαρμοσμένης εικόνας
+topsites_form_url_placeholder=Πληκτρολόγηση ή επικόλληση ενός URL
+topsites_form_use_image_link=Χρήση προσαρμοσμένης εικόνας…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Προεπισκόπηση
+topsites_form_add_button=Προσθήκη
+topsites_form_save_button=Αποθήκευση
+topsites_form_cancel_button=Ακύρωση
+topsites_form_url_validation=Απαιτείται έγκυρο URL
+topsites_form_image_validation=Αποτυχία φόρτωσης εικόνας. Δοκιμάστε ένα διαφορετικό URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Δημοφιλή θέματα:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Προβολή περισσότερων ιστοριών
+
+highlights_empty_state=Ξεκινήστε την περιήγηση και θα σάς δείξουμε μερικά υπέροχα άρθρα, βίντεο και άλλες σελίδες που έχετε επισκεφθεί πρόσφατα ή έχετε προσθέσει στους σελιδοδείκτες σας.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Δεν υπάρχει κάτι νεότερο. Ελέγξτε αργότερα για περισσότερες ιστορίες από τον πάροχο {provider}. Δεν μπορείτε να περιμένετε; Διαλέξτε κάποιο από τα δημοφιλή θέματα και ανακαλύψτε ενδιαφέρουσες ιστορίες από όλο τον Ιστό.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Δοκιμάστε το Firefox με τους σελιδοδείκτες, το ιστορικό και τους κωδικούς πρόσβασης από ένα άλλο πρόγραμμα περιήγησης.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Όχι ευχαριστώ
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Εισαγωγή τώρα
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ωχ, κάτι πήγε στραβά κατά τη φόρτωση του περιεχομένου.
+error_fallback_default_refresh_suggestion=Ανανεώστε τη σελίδα για να δοκιμάσετε ξανά.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Αφαίρεση ενότητας
+section_menu_action_collapse_section=Σύμπτυξη ενότητας
+section_menu_action_expand_section=Επέκταση ενότητας
+section_menu_action_manage_section=Διαχείριση ενότητας
+section_menu_action_add_topsite=Προσθήκη κορυφαίας ιστοσελίδας
+section_menu_action_move_up=Μετακίνηση επάνω
+section_menu_action_move_down=Μετακίνηση κάτω
+section_menu_action_privacy_notice=Σημείωση απορρήτου
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+
+firstrun_email_input_placeholder=Email
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+
+firstrun_continue_to_login=Συνέχεια
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/en-CA/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=New Tab
+
+header_top_sites=Top Sites
+header_highlights=Highlights
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recommended by {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Open context menu for {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Open the section context menu
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visited
+type_label_bookmarked=Bookmarked
+type_label_recommended=Trending
+type_label_pocket=Saved to Pocket
+type_label_downloaded=Downloaded
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Bookmark
+menu_action_remove_bookmark=Remove Bookmark
+menu_action_open_new_window=Open in a New Window
+menu_action_open_private_window=Open in a New Private Window
+menu_action_dismiss=Dismiss
+menu_action_delete=Delete from History
+menu_action_pin=Pin
+menu_action_unpin=Unpin
+confirm_history_delete_p1=Are you sure you want to delete every instance of this page from your history?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=This action cannot be undone.
+menu_action_save_to_pocket=Save to Pocket
+menu_action_delete_pocket=Delete from Pocket
+menu_action_archive_pocket=Archive in Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Show in Finder
+menu_action_show_file_windows=Open Containing Folder
+menu_action_show_file_linux=Open Containing Folder
+menu_action_show_file_default=Show File
+menu_action_open_file=Open File
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Copy Download Link
+menu_action_go_to_download_page=Go to Download Page
+menu_action_remove_download=Remove from History
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Search
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} Search
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Search the Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.
+section_disclaimer_topstories_linktext=Learn how it works.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Okay, got it
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox Home Content
+prefs_home_description=Choose what content you want on your Firefox Home screen.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} row;{num} rows
+prefs_search_header=Web Search
+prefs_topsites_description=The sites you visit most
+prefs_topstories_description2=Great content from around the web, personalized for you
+prefs_topstories_options_sponsored_label=Sponsored Stories
+prefs_topstories_sponsored_learn_more=Learn more
+prefs_highlights_description=A selection of sites that you’ve saved or visited
+prefs_highlights_options_visited_label=Visited Pages
+prefs_highlights_options_download_label=Most Recent Download
+prefs_highlights_options_pocket_label=Pages Saved to Pocket
+prefs_snippets_description=Updates from Mozilla and Firefox
+settings_pane_button_label=Customize your New Tab page
+settings_pane_topsites_header=Top Sites
+settings_pane_highlights_header=Highlights
+settings_pane_highlights_options_bookmarks=Bookmarks
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Snippets
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Edit
+edit_topsites_edit_button=Edit this site
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Top Sites
+topsites_form_edit_header=Edit Top Site
+topsites_form_title_label=Title
+topsites_form_title_placeholder=Enter a title
+topsites_form_url_label=URL
+topsites_form_image_url_label=Custom Image URL
+topsites_form_url_placeholder=Type or paste a URL
+topsites_form_use_image_link=Use a custom image…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Preview
+topsites_form_add_button=Add
+topsites_form_save_button=Save
+topsites_form_cancel_button=Cancel
+topsites_form_url_validation=Valid URL required
+topsites_form_image_validation=Image failed to load. Try a different URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Popular Topics:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=View More Stories
+
+highlights_empty_state=Start browsing, and we’ll show some of the great articles, videos, and other pages you’ve recently visited or bookmarked here.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=You’ve caught up. Check back later for more top stories from {provider}. Can’t wait? Select a popular topic to find more great stories from around the web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Try Firefox with the bookmarks, history and passwords from another browser.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=No Thanks
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Import Now
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Oops, something went wrong loading this content.
+error_fallback_default_refresh_suggestion=Refresh page to try again.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Remove Section
+section_menu_action_collapse_section=Collapse Section
+section_menu_action_expand_section=Expand Section
+section_menu_action_manage_section=Manage Section
+section_menu_action_manage_webext=Manage Extension
+section_menu_action_add_topsite=Add Top Site
+section_menu_action_move_up=Move Up
+section_menu_action_move_down=Move Down
+section_menu_action_privacy_notice=Privacy Notice
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Take Firefox with You
+firstrun_content=Get your bookmarks, history, passwords and other settings on all your devices.
+firstrun_learn_more_link=Learn more about Firefox Accounts
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Enter your email
+firstrun_form_sub_header=to continue to Firefox Sync.
+
+firstrun_email_input_placeholder=Email
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=By proceeding, you agree to the {terms} and {privacy}.
+firstrun_terms_of_service=Terms of Service
+firstrun_privacy_notice=Privacy Notice
+
+firstrun_continue_to_login=Continue
+firstrun_skip_login=Skip this step
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/en-GB/strings.properties
@@ -0,0 +1,173 @@
+newtab_page_title=New Tab
+
+header_top_sites=Top Sites
+header_highlights=Highlights
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recommended by {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Open context menu for {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Open the section context menu
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visited
+type_label_bookmarked=Bookmarked
+type_label_recommended=Trending
+type_label_pocket=Saved to Pocket
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Bookmark
+menu_action_remove_bookmark=Remove Bookmark
+menu_action_open_new_window=Open in a New Window
+menu_action_open_private_window=Open in a New Private Window
+menu_action_dismiss=Dismiss
+menu_action_delete=Delete from History
+menu_action_pin=Pin
+menu_action_unpin=Unpin
+confirm_history_delete_p1=Are you sure you want to delete every instance of this page from your history?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=This action cannot be undone.
+menu_action_save_to_pocket=Save to Pocket
+menu_action_delete_pocket=Delete from Pocket
+menu_action_archive_pocket=Archive in Pocket
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Search
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} Search
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Search the Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.
+section_disclaimer_topstories_linktext=Learn how it works.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Okay, got it
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox Home Content
+prefs_home_description=Choose what content you want on your Firefox Home screen.
+prefs_restore_defaults_button=Restore Defaults
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} row;{num} rows
+prefs_search_header=Web Search
+prefs_topsites_description=The sites you visit most
+prefs_topstories_description=High-quality content you might otherwise miss
+# LOCALIZATION NOTE (prefs_topstories_show_sponsored_label): {provider} is
+# replaced by the name of the content provider for this section, e.g., "Pocket"
+prefs_topstories_show_sponsored_label={provider} Sponsored Stories
+prefs_topstories_sponsored_learn_more=Learn more
+prefs_highlights_description=A selection of sites that you’ve saved or visited
+prefs_snippets_description=Updates from Mozilla and Firefox
+settings_pane_button_label=Customise your New Tab page
+settings_pane_header=New Tab Preferences
+settings_pane_body2=Choose what you see on this page.
+settings_pane_search_header=Search
+settings_pane_search_body=Search the Web from your new tab.
+settings_pane_topsites_header=Top Sites
+settings_pane_topsites_body=Access the web sites you visit most.
+settings_pane_topsites_options_showmore=Show two rows
+settings_pane_highlights_header=Highlights
+settings_pane_highlights_body2=Find your way back to interesting things you’ve recently visited or bookmarked.
+settings_pane_highlights_options_bookmarks=Bookmarks
+settings_pane_highlights_options_visited=Visited Sites
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Snippets
+settings_pane_snippets_body=Read short and sweet updates from Mozilla about Firefox, internet culture, and the occasional random meme.
+settings_pane_done_button=Done
+settings_pane_topstories_options_sponsored=Show Sponsored Stories
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Edit
+edit_topsites_edit_button=Edit this site
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Top Sites
+topsites_form_edit_header=Edit Top Site
+topsites_form_title_label=Title
+topsites_form_title_placeholder=Enter a title
+topsites_form_url_label=URL
+topsites_form_image_url_label=Custom Image URL
+topsites_form_url_placeholder=Type or paste a URL
+topsites_form_use_image_link=Use a custom image…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Preview
+topsites_form_add_button=Add
+topsites_form_save_button=Save
+topsites_form_cancel_button=Cancel
+topsites_form_url_validation=Valid URL required
+topsites_form_image_validation=Image failed to load. Try a different URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Popular Topics:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=View More Stories
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=Discover high-quality content you might otherwise miss, with help from Pocket, now part of Mozilla.
+
+highlights_empty_state=Start browsing, and we’ll show some of the great articles, videos, and other pages you’ve recently visited or bookmarked here.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=You’ve caught up. Check back later for more top stories from {provider}. Can’t wait? Select a popular topic to find more great stories from around the web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Try Firefox with the bookmarks, history and passwords from another browser.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=No Thanks
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Import Now
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Oops, something went wrong loading this content.
+error_fallback_default_refresh_suggestion=Refresh page to try again.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Remove Section
+section_menu_action_collapse_section=Collapse Section
+section_menu_action_expand_section=Expand Section
+section_menu_action_manage_section=Manage Section
+section_menu_action_add_topsite=Add Top Site
+section_menu_action_move_up=Move Up
+section_menu_action_move_down=Move Down
+section_menu_action_privacy_notice=Privacy Notice
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/en-US/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=New Tab
+
+header_top_sites=Top Sites
+header_highlights=Highlights
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recommended by {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Open context menu for {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Open the section context menu
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visited
+type_label_bookmarked=Bookmarked
+type_label_recommended=Trending
+type_label_pocket=Saved to Pocket
+type_label_downloaded=Downloaded
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Bookmark
+menu_action_remove_bookmark=Remove Bookmark
+menu_action_open_new_window=Open in a New Window
+menu_action_open_private_window=Open in a New Private Window
+menu_action_dismiss=Dismiss
+menu_action_delete=Delete from History
+menu_action_pin=Pin
+menu_action_unpin=Unpin
+confirm_history_delete_p1=Are you sure you want to delete every instance of this page from your history?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=This action cannot be undone.
+menu_action_save_to_pocket=Save to Pocket
+menu_action_delete_pocket=Delete from Pocket
+menu_action_archive_pocket=Archive in Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Show in Finder
+menu_action_show_file_windows=Open Containing Folder
+menu_action_show_file_linux=Open Containing Folder
+menu_action_show_file_default=Show File
+menu_action_open_file=Open File
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Copy Download Link
+menu_action_go_to_download_page=Go to Download Page
+menu_action_remove_download=Remove from History
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Search
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} Search
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Search the Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.
+section_disclaimer_topstories_linktext=Learn how it works.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Okay, got it
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox Home Content
+prefs_home_description=Choose what content you want on your Firefox Home screen.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} row;{num} rows
+prefs_search_header=Web Search
+prefs_topsites_description=The sites you visit most
+prefs_topstories_description2=Great content from around the web, personalized for you
+prefs_topstories_options_sponsored_label=Sponsored Stories
+prefs_topstories_sponsored_learn_more=Learn more
+prefs_highlights_description=A selection of sites that you’ve saved or visited
+prefs_highlights_options_visited_label=Visited Pages
+prefs_highlights_options_download_label=Most Recent Download
+prefs_highlights_options_pocket_label=Pages Saved to Pocket
+prefs_snippets_description=Updates from Mozilla and Firefox
+settings_pane_button_label=Customize your New Tab page
+settings_pane_topsites_header=Top Sites
+settings_pane_highlights_header=Highlights
+settings_pane_highlights_options_bookmarks=Bookmarks
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Snippets
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Edit
+edit_topsites_edit_button=Edit this site
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=New Top Site
+topsites_form_edit_header=Edit Top Site
+topsites_form_title_label=Title
+topsites_form_title_placeholder=Enter a title
+topsites_form_url_label=URL
+topsites_form_image_url_label=Custom Image URL
+topsites_form_url_placeholder=Type or paste a URL
+topsites_form_use_image_link=Use a custom image…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Preview
+topsites_form_add_button=Add
+topsites_form_save_button=Save
+topsites_form_cancel_button=Cancel
+topsites_form_url_validation=Valid URL required
+topsites_form_image_validation=Image failed to load. Try a different URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Popular Topics:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=View More Stories
+
+highlights_empty_state=Start browsing, and we’ll show some of the great articles, videos, and other pages you’ve recently visited or bookmarked here.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=You’ve caught up. Check back later for more top stories from {provider}. Can’t wait? Select a popular topic to find more great stories from around the web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Try Firefox with the bookmarks, history and passwords from another browser.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=No Thanks
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Import Now
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Oops, something went wrong loading this content.
+error_fallback_default_refresh_suggestion=Refresh page to try again.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Remove Section
+section_menu_action_collapse_section=Collapse Section
+section_menu_action_expand_section=Expand Section
+section_menu_action_manage_section=Manage Section
+section_menu_action_manage_webext=Manage Extension
+section_menu_action_add_topsite=Add Top Site
+section_menu_action_move_up=Move Up
+section_menu_action_move_down=Move Down
+section_menu_action_privacy_notice=Privacy Notice
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Take Firefox with You
+firstrun_content=Get your bookmarks, history, passwords and other settings on all your devices.
+firstrun_learn_more_link=Learn more about Firefox Accounts
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Enter your email
+firstrun_form_sub_header=to continue to Firefox Sync.
+
+firstrun_email_input_placeholder=Email
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=By proceeding, you agree to the {terms} and {privacy}.
+firstrun_terms_of_service=Terms of Service
+firstrun_privacy_notice=Privacy Notice
+
+firstrun_continue_to_login=Continue
+firstrun_skip_login=Skip this step
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/eo/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Nova langeto
+
+header_top_sites=Plej vizititaj
+header_highlights=Elstaraĵoj
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Rekomendita de {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Malfermi kuntekstan menu por {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Malfermi sekcion de kunteksta menuo
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Vizitita
+type_label_bookmarked=Kun legosigno
+type_label_recommended=Tendencoj
+type_label_pocket=Konservita en Pocket
+type_label_downloaded=Elŝutita
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Aldoni legosignon
+menu_action_remove_bookmark=Forigi legosignon
+menu_action_open_new_window=Malfermi en nova fenestro
+menu_action_open_private_window=Malfermi en nova privata fenestro
+menu_action_dismiss=Ignori
+menu_action_delete=Forigi el historio
+menu_action_pin=Alpingli
+menu_action_unpin=Depingli
+confirm_history_delete_p1=Ĉu vi certe volas forigi ĉiun aperon de tiu ĉi paĝo el via historio?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Tiu ĉi ago ne estas malfarebla.
+menu_action_save_to_pocket=Konservi en Pocket
+menu_action_delete_pocket=Forigi el Pocket
+menu_action_archive_pocket=Arĥivi en Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Montri en Finder
+menu_action_show_file_windows=Malfermi entenantan dosierujon
+menu_action_show_file_linux=Malfermi entenantan dosierujon
+menu_action_show_file_default=Montri dosieron
+menu_action_open_file=Malfermi dosieron
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Kopii elŝutan ligilon
+menu_action_go_to_download_page=Iri al la paĝo de elŝuto
+menu_action_remove_download=Forigi el la historio
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Serĉi
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Serĉo de {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Serĉi la reton
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=La plej interesaj artikoloj en la reto, elektitaj surbaze de tio, kion vi legas. Hecho por Pocket, kiu estas nun parto de Mozilla.
+section_disclaimer_topstories_linktext=Vidi kiel tio funkcias.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=En ordo, mi komprenis
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Enhavo de la hejmekrano de Firefox
+prefs_home_description=Elektu la enhavon, kiun vi volas en via hejmekrano de Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} vico;{num} vicoj
+prefs_search_header=Serĉo en la reto
+prefs_topsites_description=Viaj plej vizititaj retejoj
+prefs_topstories_description2=Bonega enhavo de la tuta Teksaĵo, personecigita por vi
+prefs_topstories_options_sponsored_label=Patronitaj artikoloj
+prefs_topstories_sponsored_learn_more=Pli da informo
+prefs_highlights_description=Retejoj elektitaj inter tiuj, kiun vi vizitis aŭ konservis
+prefs_highlights_options_visited_label=Vizititaj paĝoj
+prefs_highlights_options_download_label=Lasta elŝuto
+prefs_highlights_options_pocket_label=Paĝoj konservitaj en Pocket
+prefs_snippets_description=Ĝisdatigoj de Mozilla kaj Firefox
+settings_pane_button_label=Personecigi la paĝon por novaj langetoj
+settings_pane_topsites_header=Plej vizitaj
+settings_pane_highlights_header=Elstaraĵoj
+settings_pane_highlights_options_bookmarks=Legosignoj
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Fragmentoj
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Redakti
+edit_topsites_edit_button=Redakti ĉi tiun retejon
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nova ofta retejo
+topsites_form_edit_header=Redakti oftan retejon
+topsites_form_title_label=Titolo
+topsites_form_title_placeholder=Tajpu titolon
+topsites_form_url_label=Retadreso
+topsites_form_image_url_label=Personecitiga retadreso de bildo
+topsites_form_url_placeholder=Tajpu aŭ alguu retadreson
+topsites_form_use_image_link=Uzi personecigitan bildon…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Antaŭvidi
+topsites_form_add_button=Aldoni
+topsites_form_save_button=Konservi
+topsites_form_cancel_button=Nuligi
+topsites_form_url_validation=Valida retadreso estas postulata
+topsites_form_image_validation=Ne eblis ŝargi la bildon. Klopodu alian retadreson.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Ĉefaj temoj:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Montri pli da artikoloj
+
+highlights_empty_state=Komencu retumi kaj ĉi tie ni montros al vi kelkajn el la plej bonaj artikoloj, filmetoj kaj aliaj paĝoj, kiujn vi antaŭ nelonge vizits aŭ por kiuj vi aldonis legosignon.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Vi legis ĉion. Kontrolu denove poste ĉu estas pli da novaĵon de {provider}. Ĉu vi ne povas atendi? Elektu popularan temon por trovi pli da interesaj artikoloj en la tuta teksaĵo.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Provu Firefox kun la legosignoj, historio kaj pasvortoj de alia retumilo.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Ne, dankon
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importi nun
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Fuŝ', io malbona okazis dum ŝargo de tiu ĉi enhavo.
+error_fallback_default_refresh_suggestion=Refreŝigi paĝon por klopodi denove.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Forigi sekcion
+section_menu_action_collapse_section=Faldi sekcion
+section_menu_action_expand_section=Malfaldi sekcion
+section_menu_action_manage_section=Administri sekcion
+section_menu_action_manage_webext=Administri etendaĵon
+section_menu_action_add_topsite=Aldoni oftan retejon
+section_menu_action_move_up=Movi supren
+section_menu_action_move_down=Movi malsupren
+section_menu_action_privacy_notice=Rimarko pri privateco
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Portu Firefox kun vi
+firstrun_content=Ricevu viajn legosignojn, historion, pasvortojn kaj aliajn agordojn en ĉiuj viaj aparatoj.
+firstrun_learn_more_link=Pli da informo pri la kontoj de Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Tajpu vian retpoŝtan adreson
+firstrun_form_sub_header=por pluiri al Spegulado de Firefox.
+
+firstrun_email_input_placeholder=Retpoŝta adreso
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Se vi daŭrigas vi akceptas la {terms} kaj {privacy}.
+firstrun_terms_of_service=kondiĉojn de uzo
+firstrun_privacy_notice=rimarkon pri privateco
+
+firstrun_continue_to_login=Daŭrigi
+firstrun_skip_login=Pretersalti tiun ĉi paŝon
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/es-AR/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Nueva pestaña
+
+header_top_sites=Más visitados
+header_highlights=Destacados
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recomendado por {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Abrir el menú para {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Abrir el menú contextual de la sección
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visitados
+type_label_bookmarked=Marcados
+type_label_recommended=Tendencias
+type_label_pocket=Guardado en Pocket
+type_label_downloaded=Descargada
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Marcador
+menu_action_remove_bookmark=Eliminar marcador
+menu_action_open_new_window=Abrir en nueva ventana
+menu_action_open_private_window=Abrir en nueva ventana privada
+menu_action_dismiss=Descartar
+menu_action_delete=Borrar del historial
+menu_action_pin=Pegar
+menu_action_unpin=Despegar
+confirm_history_delete_p1=¿Está seguro de querer borrar cualquier instancia de esta página del historial?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Esta acción no puede deshacerse.
+menu_action_save_to_pocket=Guardar en Pocket
+menu_action_delete_pocket=Borrar de Pocket
+menu_action_archive_pocket=Archivar en Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Mostrar en Finder
+menu_action_show_file_windows=Abrir Carpeta contenedora
+menu_action_show_file_linux=Abrir Carpeta contenedora
+menu_action_show_file_default=Mostrar Archivo
+menu_action_open_file=Abrir Archivo
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Copiar Dirección del enlace
+menu_action_go_to_download_page=Ir a la página de descarga
+menu_action_remove_download=Eliminar del Historial
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Buscar
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Buscar con {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Buscar en la web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Las historias más interesantes en la web, seleccionadas en base a lo que lees. Gracias a Pocket, ahora parte de Mozilla.
+section_disclaimer_topstories_linktext=Aprendé cómo funciona.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Listo, lo entendí
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Contenido de la página de inicio de Firefox
+prefs_home_description=Elija qué contenido desea en la Pantalla de inicio de Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option=fila de {num}; filas de {num}
+prefs_search_header=Búsqueda en la web
+prefs_topsites_description=Los sitios que más visita
+prefs_topstories_description2=El mejor contenido de toda la web, personalizado para usted
+prefs_topstories_options_sponsored_label=Historias patrocinadas
+prefs_topstories_sponsored_learn_more=Conocer más
+prefs_highlights_description=Una selección de sitios que guardó o visitó
+prefs_highlights_options_visited_label=Sitios visitados
+prefs_highlights_options_download_label=Descargado recientemente
+prefs_highlights_options_pocket_label=Páginas guardadas en Pocket
+prefs_snippets_description=Actualizaciones de Mozilla y Firefox
+settings_pane_button_label=Personalizar la página nueva pestaña
+settings_pane_topsites_header=Más visitados
+settings_pane_highlights_header=Destacados
+settings_pane_highlights_options_bookmarks=Marcadores
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Recortes
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Editar
+edit_topsites_edit_button=Editar este sitio
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nuevo sitio más visitado
+topsites_form_edit_header=Editar sitio más visitado
+topsites_form_title_label=Título
+topsites_form_title_placeholder=Ingresar un título
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL de Imagen personalizada
+topsites_form_url_placeholder=Escribir o pegar URL
+topsites_form_use_image_link=Usar imagen personalizada…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Vista previa
+topsites_form_add_button=Agregar
+topsites_form_save_button=Guardar
+topsites_form_cancel_button=Cancelar
+topsites_form_url_validation=Se requiere URL válida
+topsites_form_image_validation=La imagen no se pudo cargar. Pruebe una URL diferente.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Tópicos populares:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Ver más historias
+
+highlights_empty_state=Comenzá a navegar y te mostraremos algunos de los mejores artículos, videos y otras páginas que hayás visitado o marcado acá.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Ya te pusiste al día. Volvé más tarde para más historias de {provider}. ¿No podés esperar? Seleccioná un tema popular para encontrar más historias de todo el mundo.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Probá Firefox con los marcadores, historial y contraseñas de otro navegador.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=No gracias
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importar ahora
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Epa, algo salió mal al cargar este contenido.
+error_fallback_default_refresh_suggestion=Refrescar la página para reintentar.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Eliminar sección
+section_menu_action_collapse_section=Colapsar sección
+section_menu_action_expand_section=Expandir sección
+section_menu_action_manage_section=Administrar sección
+section_menu_action_manage_webext=Administrar extensión
+section_menu_action_add_topsite=Agregar Sitio más visitado
+section_menu_action_move_up=Subir
+section_menu_action_move_down=Bajar
+section_menu_action_privacy_notice=Nota de privacidad
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Lleve Firefox con usted
+firstrun_content=Acceda a sus marcadores, historial, contraseñas y más ajustes en todos sus dispositivos.
+firstrun_learn_more_link=Descubra más sobre las Cuentas de Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Ingrese su correo electrónico
+firstrun_form_sub_header=para pasar a Firefox Sync.
+
+firstrun_email_input_placeholder=Correo electrónico
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Al proceder, acepta los {terms} y {privacy}.
+firstrun_terms_of_service=Términos del servicio
+firstrun_privacy_notice=Anuncio de privacidad
+
+firstrun_continue_to_login=Continuar
+firstrun_skip_login=Saltear este paso
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/es-CL/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Nueva pestaña
+
+header_top_sites=Sitios frecuentes
+header_highlights=Destacados
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recomendado por {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Abrir menú contextual para {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Abrir sección del menú contextual
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visitado
+type_label_bookmarked=Marcado
+type_label_recommended=Popular
+type_label_pocket=Guardado en Pocket
+type_label_downloaded=Descargado
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Marcador
+menu_action_remove_bookmark=Remover marcador
+menu_action_open_new_window=Abrir en una nueva ventana
+menu_action_open_private_window=Abrir en una nueva ventana privada
+menu_action_dismiss=Descartar
+menu_action_delete=Eliminar del historial
+menu_action_pin=Fijar
+menu_action_unpin=Soltar
+confirm_history_delete_p1=¿Estás seguro de que quieres eliminar cada instancia de esta página de tu historial?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Esta acción no puede ser deshecha.
+menu_action_save_to_pocket=Guardar en Pocket
+menu_action_delete_pocket=Eliminar de Pocket
+menu_action_archive_pocket=Archivar en Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Mostrar en Finder
+menu_action_show_file_windows=Abrir carpeta contenedora
+menu_action_show_file_linux=Abrir carpeta contenedora
+menu_action_show_file_default=Mostrar archivo
+menu_action_open_file=Abrir archivo
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Copiar enlace de descarga
+menu_action_go_to_download_page=Ir a la página de descarga
+menu_action_remove_download=Eliminar del historial
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Buscar
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Búsqueda de {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Buscar en la Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Las historias más interesantes en la web, seleccionadas en base a lo que tu lees. Por Pocket, ahora parte de Mozilla.
+section_disclaimer_topstories_linktext=Aprender cómo funciona.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ok, ¡ya caché!
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Contenido de la página de inicio de Firefox
+prefs_home_description=Elige qué contenido quieres en tu pantalla de inicio de Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} fila;{num} filas
+prefs_search_header=Búsqueda web
+prefs_topsites_description=Los sitios que más visitas
+prefs_topstories_description2=El mejor contenido de toda la web, seleccionado para ti
+prefs_topstories_options_sponsored_label=Historias patrocinadas
+prefs_topstories_sponsored_learn_more=Aprender más
+prefs_highlights_description=Una selección de sitios que guardaste o visitaste
+prefs_highlights_options_visited_label=Páginas visitadas
+prefs_highlights_options_download_label=Descarga más reciente
+prefs_highlights_options_pocket_label=Páginas guardadas en Pocket
+prefs_snippets_description=Actualizaciones de Mozilla y Firefox
+settings_pane_button_label=Personaliza tu página de Nueva pestaña
+settings_pane_topsites_header=Sitios frecuentes
+settings_pane_highlights_header=Destacados
+settings_pane_highlights_options_bookmarks=Marcadores
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Fragmentos
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Editar
+edit_topsites_edit_button=Editar este sitio
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nuevo sitio frecuente
+topsites_form_edit_header=Editar sitio frecuente
+topsites_form_title_label=Título
+topsites_form_title_placeholder=Ingresar un título
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL de imagen personalizada
+topsites_form_url_placeholder=Escribe o pega una URL
+topsites_form_use_image_link=Utilizar una imagen personalizada…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Vista previa
+topsites_form_add_button=Añadir
+topsites_form_save_button=Guardar
+topsites_form_cancel_button=Cancelar
+topsites_form_url_validation=URL válida requerida
+topsites_form_image_validation=Falló la carga de la imagen. Prueba una URL diferente.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Temas populares:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Ver más historias
+
+highlights_empty_state=Empieza a navegar, y nosotros te mostraremos aquí algunos de los mejores artículos, videos y otras páginas que hayas visitado recientemente o marcado.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Te has puesto al día. Revisa más tarde para ver más historias de {provider}. ¿No puedes esperar? Selecciona un tema popular para encontrar más historias de todo el mundo.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Prueba Firefox con los marcadores, historial y contraseñas de otro navegador.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=No, gracias
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importar ahora
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Chuta, algo se fue a las pailas al cargar este contenido.
+error_fallback_default_refresh_suggestion=Recarga la página para volver a intentarlo.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Eliminar sección
+section_menu_action_collapse_section=Contraer sección
+section_menu_action_expand_section=Expandir sección
+section_menu_action_manage_section=Gestionar sección
+section_menu_action_manage_webext=Gestionar extensión
+section_menu_action_add_topsite=Añadir sitio frecuente
+section_menu_action_move_up=Subir
+section_menu_action_move_down=Bajar
+section_menu_action_privacy_notice=Aviso de privacidad
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Lleva a Firefox contigo
+firstrun_content=Ten tus marcadores, historial, contraseñas y otros ajustes en todos tus dispositivos.
+firstrun_learn_more_link=Aprende más sobre Firefox Accounts
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Ingresa tu correo
+firstrun_form_sub_header=para conectarte a Firefox Sync.
+
+firstrun_email_input_placeholder=Correo
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Al proceder, aceptas los {terms} y la {privacy}.
+firstrun_terms_of_service=Términos del servicio
+firstrun_privacy_notice=Política de privacidad
+
+firstrun_continue_to_login=Continuar
+firstrun_skip_login=Saltar este paso
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/es-ES/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Nueva pestaña
+
+header_top_sites=Sitios favoritos
+header_highlights=Destacados
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recomendado por {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Abrir menú de contexto para {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Abrir la sección menú contextual
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visitados
+type_label_bookmarked=En marcadores
+type_label_recommended=Tendencias
+type_label_pocket=Guardado en Pocket
+type_label_downloaded=Descargado
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Marcador
+menu_action_remove_bookmark=Eliminar marcador
+menu_action_open_new_window=Abrir en una nueva ventana
+menu_action_open_private_window=Abrir en una nueva ventana privada
+menu_action_dismiss=Ignorar
+menu_action_delete=Eliminar del historial
+menu_action_pin=Fijar
+menu_action_unpin=Soltar
+confirm_history_delete_p1=¿Está seguro de que quiere eliminar de su historial todas las instancias de esta página?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Esta acción no se puede deshacer.
+menu_action_save_to_pocket=Guardar en Pocket
+menu_action_delete_pocket=Eliminar de Pocket
+menu_action_archive_pocket=Archivar en Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Mostrar en Finder
+menu_action_show_file_windows=Abrir la carpeta que lo contiene
+menu_action_show_file_linux=Abrir la carpeta que lo contiene
+menu_action_show_file_default=Mostrar archivo
+menu_action_open_file=Abrir archivo
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Copiar el enlace de descarga
+menu_action_go_to_download_page=Ir a la página de descarga
+menu_action_remove_download=Eliminar del historial
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Buscar
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Búsqueda de {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Buscar en la Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Las historias más interesantes de la web, seleccionadas en base a lo que lee. Gracias a Pocket , ahora parte de Mozilla.
+section_disclaimer_topstories_linktext=Aprenda cómo funciona.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ok, entendido
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Contenido de la página de inicio de Firefox
+prefs_home_description=Seleccione el contenido que desea en la pantalla de inicio de Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} fila;{num} filas
+prefs_search_header=Búsqueda web
+prefs_topsites_description=Los sitios que más visita
+prefs_topstories_description2=El mejor contenido de toda la web, personalizado para usted
+prefs_topstories_options_sponsored_label=Historias patrocinadas
+prefs_topstories_sponsored_learn_more=Más información
+prefs_highlights_description=Una selección de sitios que ha guardado o visitado
+prefs_highlights_options_visited_label=Páginas visitadas
+prefs_highlights_options_download_label=Descargas recientes
+prefs_highlights_options_pocket_label=Páginas guardadas en Pocket
+prefs_snippets_description=Actualizaciones de Mozilla y Firefox
+settings_pane_button_label=Personalizar la página Nueva pestaña
+settings_pane_topsites_header=Sitios populares
+settings_pane_highlights_header=Destacados
+settings_pane_highlights_options_bookmarks=Marcadores
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Fragmentos de código
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Editar
+edit_topsites_edit_button=Editar este sitio
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nuevo sitio popular
+topsites_form_edit_header=Editar sitio popular
+topsites_form_title_label=Título
+topsites_form_title_placeholder=Introducir título
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL de imagen personalizada
+topsites_form_url_placeholder=Escribir o pegar una URL
+topsites_form_use_image_link=Utilizar una imagen personalizada…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Vista preliminar
+topsites_form_add_button=Agregar
+topsites_form_save_button=Guardar
+topsites_form_cancel_button=Cancelar
+topsites_form_url_validation=Se requiere una URL válida
+topsites_form_image_validation=No se ha podido cargar la imagen. Pruebe con una URL diferente.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Temas populares:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Ver más historias
+
+highlights_empty_state=Empiece a navegar y nosotros le mostraremos aquí algunos de los mejores artículos, videos y otras páginas que haya visitado recientemente o agregado a marcadores.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Ya está al día. Vuelva luego y busque más historias de {provider}. ¿No puede esperar? Seleccione un tema popular y encontrará más historias alucinantes por toda la web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Prueba Firefox con los marcadores, historial y contraseñas de otro navegador.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=No, gracias
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importar ahora
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Lo sentimos, algo salió mal al cargar el contenido.
+error_fallback_default_refresh_suggestion=Recargue la página e inténtelo de nuevo.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Eliminar sección
+section_menu_action_collapse_section=Contraer sección
+section_menu_action_expand_section=Expandir sección
+section_menu_action_manage_section=Gestionar sección
+section_menu_action_manage_webext=Gestionar extensión
+section_menu_action_add_topsite=Añadir sitio popular
+section_menu_action_move_up=Subir
+section_menu_action_move_down=Bajar
+section_menu_action_privacy_notice=Aviso de privacidad
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Llévese Firefox consigo
+firstrun_content=Acceda a sus marcadores, historial, contraseñas y más ajustes en todos sus dispositivos.
+firstrun_learn_more_link=Descubra más sobre las Cuentas de Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Introduzca su correo electrónico
+firstrun_form_sub_header=para acceder a Firefox Sync.
+
+firstrun_email_input_placeholder=Correo electrónico
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Al continuar aceptas los {terms} y el {privacy}.
+firstrun_terms_of_service=Términos del servicio
+firstrun_privacy_notice=Aviso de privacidad
+
+firstrun_continue_to_login=Continuar
+firstrun_skip_login=Saltar este paso
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/es-MX/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Nueva pestaña
+
+header_top_sites=Sitios favoritos
+header_highlights=Destacados
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recomendado por {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Abrir menú contextual para {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Abrir la sección menú contextual
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visitados
+type_label_bookmarked=Marcados
+type_label_recommended=Tendencias
+type_label_pocket=Guardado en Pocket
+type_label_downloaded=Descargado
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Marcador
+menu_action_remove_bookmark=Eliminar marcador
+menu_action_open_new_window=Abrir en una Nueva Ventana
+menu_action_open_private_window=Abrir en una Nueva Ventana Privada
+menu_action_dismiss=Descartar
+menu_action_delete=Eliminar del historial
+menu_action_pin=Anclar
+menu_action_unpin=Desanclar
+confirm_history_delete_p1=¿Estás seguro de que quieres eliminar de tu historial todas las instancias de esta página?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Esta acción no se puede deshacer.
+menu_action_save_to_pocket=Guardar en Pocket
+menu_action_delete_pocket=Eliminar de Pocket
+menu_action_archive_pocket=Archivar en Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Mostrar en Finder
+menu_action_show_file_windows=Abrir carpeta contenedora
+menu_action_show_file_linux=Abrir carpeta contenedora
+menu_action_show_file_default=Mostrar archivo
+menu_action_open_file=Abrir archivo
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Copiar enlace de descarga
+menu_action_go_to_download_page=Ir a la página de descarga
+menu_action_remove_download=Eliminar del historial
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Buscar
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Buscar {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Buscar en la Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Las más interesantes historias en la web, seleccionadas basándonos en los que lees. Desde Pocket, ahora parte de Mozilla.
+section_disclaimer_topstories_linktext=Saber como trabaja.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Está bien, lo entiendo
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Contenido de la página de inicio de Firefox
+prefs_home_description=Selecciona el contenido que desea en la pantalla de inicio de Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} fila;{num} filas
+prefs_search_header=Búsqueda web
+prefs_topsites_description=Los sitios que más visitas
+prefs_topstories_description2=El mejor contenido de la web, personalizado para ti
+prefs_topstories_options_sponsored_label=Artículos patrocinados
+prefs_topstories_sponsored_learn_more=Saber más
+prefs_highlights_description=Una selección de sitios que has guardado o visitado
+prefs_highlights_options_visited_label=Páginas visitadas
+prefs_highlights_options_download_label=Descargado recientemente
+prefs_highlights_options_pocket_label=Páginas guardadas en Pocket
+prefs_snippets_description=Actualizaciones de Mozilla y Firefox
+settings_pane_button_label=Personalizar tu página de nueva pestaña
+settings_pane_topsites_header=Sitios populares
+settings_pane_highlights_header=Destacados
+settings_pane_highlights_options_bookmarks=Marcadores
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Fragmentos
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Editar
+edit_topsites_edit_button=Editar este sitio
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nuevo sitio popular
+topsites_form_edit_header=Editar sitio popular
+topsites_form_title_label=Título
+topsites_form_title_placeholder=Introducir un título
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL de imagen personalizada
+topsites_form_url_placeholder=Escribir o pegar una URL
+topsites_form_use_image_link=Utilizar una imagen personalizada…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Vista previa
+topsites_form_add_button=Agregar
+topsites_form_save_button=Guardar
+topsites_form_cancel_button=Cancelar
+topsites_form_url_validation=Se requiere una URL válida
+topsites_form_image_validation=La imagen no se pudo cargar. Intente una URL diferente.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Temas populares:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Ver más historias
+
+highlights_empty_state=Empieza a navegar, y nosotros te mostraremos aquí algunos de los mejores artículos, videos y otras páginas que hayas visitado recientemente o marcado.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Ya estás al día. Vuelve luego y busca más historias de {provider}. ¿No puedes esperar? Selecciona un tema popular y encontrarás más historias interesantes por toda la web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Prueba Firefox con los marcadores, historial y contraseñas de otro navegador.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=No, gracias
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importar ahora
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ups, algo salió mal mientras se cargaba el contenido.
+error_fallback_default_refresh_suggestion=Actualiza la página e intenta de nuevo.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Eliminar sección
+section_menu_action_collapse_section=Sección de colapso
+section_menu_action_expand_section=Ampliar la sección
+section_menu_action_manage_section=Administrar sección
+section_menu_action_manage_webext=Gestionar extensión
+section_menu_action_add_topsite=Agregar sitio popular
+section_menu_action_move_up=Más
+section_menu_action_move_down=Bajar
+section_menu_action_privacy_notice=Política de privacidad
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Lleva a Firefox contigo
+firstrun_content=Accede a tus marcadores, historial, contraseñas y más ajustes en todos tus dispositivos.
+firstrun_learn_more_link=Conoce más acerca de Firefox Accounts
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Ingresa tu correo electrónico
+firstrun_form_sub_header=para acceder a Firefox Sync.
+
+firstrun_email_input_placeholder=Correo electrónico
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Al proceder, aceptas los {terms} y la {privacy}.
+firstrun_terms_of_service=Términos del servicio
+firstrun_privacy_notice=Política de privacidad
+
+firstrun_continue_to_login=Continuar
+firstrun_skip_login=Saltar este paso
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/et/strings.properties
@@ -0,0 +1,192 @@
+newtab_page_title=Uus kaart
+
+header_top_sites=Top saidid
+header_highlights=Esiletõstetud
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} soovitab
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Ava {title} kontekstimenüü
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Ava osa kontekstimenüü
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Külastatud
+type_label_bookmarked=Järjehoidjatest
+type_label_recommended=Menukad
+type_label_pocket=Salvestatud Pocketisse
+type_label_downloaded=Allalaaditud
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Lisa järjehoidjatesse
+menu_action_remove_bookmark=Eemalda järjehoidja
+menu_action_open_new_window=Ava uues aknas
+menu_action_open_private_window=Ava uues privaatses aknas
+menu_action_dismiss=Peida
+menu_action_delete=Kustuta ajaloost
+menu_action_pin=Kinnita
+menu_action_unpin=Eemalda kohakinnitus
+confirm_history_delete_p1=Kas oled kindel, et soovid ajaloost kõik selle lehe kohta käivad kirjed kustutada?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Seda tegevust pole võimalik tagasi võtta.
+menu_action_save_to_pocket=Salvesta Pocketisse
+menu_action_delete_pocket=Kustuta Pocketist
+menu_action_archive_pocket=Arhiveeri Pocketis
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Kuva Finderis
+menu_action_show_file_windows=Ava faili sisaldav kaust
+menu_action_show_file_linux=Ava faili sisaldav kaust
+menu_action_show_file_default=Kuva fail
+menu_action_open_file=Ava fail
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Kopeeri allalaadimislink
+menu_action_go_to_download_page=Mine allalaadimise lehele
+menu_action_remove_download=Eemalda ajaloost
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Otsi
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Otsi veebist
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Huvitavamad veebilood, mis on valitud sinu loetu põhjal. Pocketilt, mis on nüüd Mozilla osa.
+section_disclaimer_topstories_linktext=Vaata, kuidas see töötab.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Olgu, sain aru
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefoxi avalehe sisu
+prefs_home_description=Vali sisu, mida soovid Firefoxi avalehel näha.
+prefs_restore_defaults_button=Taasta vaikeväärtused
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} rida;{num} rida
+prefs_search_header=Veebiotsing
+prefs_topsites_description=Enim külastatud saidid
+prefs_topstories_description2=Parim veebisisu sinu huvidest lähtuvalt
+prefs_topstories_options_sponsored_label=Sponsitud postitused
+prefs_topstories_sponsored_learn_more=Rohkem teavet
+prefs_highlights_description=Valik saitidest, mille oled salvestanud või mida oled külastanud
+prefs_highlights_options_visited_label=Külastatud lehed
+prefs_highlights_options_download_label=Viimane allalaadimine
+prefs_highlights_options_pocket_label=Pocketisse salvestatud lehed
+prefs_snippets_description=Uuendused Mozillalt ja Firefoxilt
+settings_pane_button_label=Kohanda uue kaardi lehte
+settings_pane_header=Uue kaardi sätted
+settings_pane_body2=Vali asjad, mida soovid sellel lehel näha.
+settings_pane_search_header=Otsing
+settings_pane_search_body=Veebis otsimine uuel kaardil.
+settings_pane_topsites_header=Top saidid
+settings_pane_topsites_body=Ligipääs enim külastatud veebilehtedele.
+settings_pane_topsites_options_showmore=Kuvatakse kahel real
+settings_pane_highlights_header=Esiletõstetud
+settings_pane_highlights_body2=Leia tee tagasi asjade juurde, mida hiljuti külastasid või järjehoidjatesse lisasid.
+settings_pane_highlights_options_bookmarks=Järjehoidjad
+settings_pane_highlights_options_visited=Külastatud saidid
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Infokillud
+settings_pane_snippets_body=Loe lühikesi ja mõnusaid infokilde Mozillalt Firefoxi, interneti kultuuri ja vahel ka juhuslike netimeemide kohta.
+settings_pane_done_button=Valmis
+settings_pane_topstories_options_sponsored=Kuvatakse sponsitud postitusi
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Muuda
+edit_topsites_edit_button=Muuda seda saiti
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Uue top saidi lisamine
+topsites_form_edit_header=Top saidi muutmine
+topsites_form_title_label=Pealkiri
+topsites_form_title_placeholder=Sisesta pealkiri
+topsites_form_url_label=URL
+topsites_form_image_url_label=Kohandatud pildi URL
+topsites_form_url_placeholder=Sisesta või aseta URL
+topsites_form_use_image_link=Kasuta kohandatud pilti…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Eelvaade
+topsites_form_add_button=Lisa
+topsites_form_save_button=Salvesta
+topsites_form_cancel_button=Tühista
+topsites_form_url_validation=URL peab olema korrektne
+topsites_form_image_validation=Pildi laadimine ebaõnnestus. Proovi teistsugust URLi.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Populaarsed teemad:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Rohkem lugusid
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=Avasta Pocketi (nüüd osa Mozillast) abiga kõrgkvaliteetset sisu, mis muidu võib märkamata jääda.
+
+highlights_empty_state=Alusta veebilehitsemist ja me näitame siin häid artikleid, videoid ja muid lehti, mida hiljuti külastasid või järjehoidjatesse lisasid.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Vaata hiljem uuesti, et näha parimaid postitusi teenusepakkujalt {provider}. Ei suuda oodata? Vali populaarne teema, et leida veel suurepärast sisu internetist.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Proovi Firefoxi teisest brauserist pärinevate järjehoidjate, ajaloo ja paroolidega.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Ei soovi
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Impordi kohe
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ups, selle sisu laadimisel läks midagi viltu.
+error_fallback_default_refresh_suggestion=Uuesti proovimiseks laadi leht uuesti.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Eemalda osa
+section_menu_action_collapse_section=Ahenda osa
+section_menu_action_expand_section=Laienda osa
+section_menu_action_manage_section=Halda osa
+section_menu_action_add_topsite=Lisa top sait
+section_menu_action_move_up=Liiguta üles
+section_menu_action_move_down=Liiguta alla
+section_menu_action_privacy_notice=Privaatsuspoliitika
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/eu/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Fitxa berria
+
+header_top_sites=Gune erabilienak
+header_highlights=Nabarmendutakoak
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} hornitzaileak gomendatuta
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Ikusi {title} gunerako testuinguru-menua
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Ireki atalaren testuinguru-menua
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Bisitatuta
+type_label_bookmarked=Laster-marka eginda
+type_label_recommended=Joerak
+type_label_pocket=Pocket-en gordeta
+type_label_downloaded=Deskargatuta
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Egin laster-marka
+menu_action_remove_bookmark=Kendu laster-marka
+menu_action_open_new_window=Ireki leiho berri batean
+menu_action_open_private_window=Ireki leiho pribatu berrian
+menu_action_dismiss=Baztertu
+menu_action_delete=Ezabatu historiatik
+menu_action_pin=Ainguratu
+menu_action_unpin=Desainguratu
+confirm_history_delete_p1=Ziur zaude orri honen agerpen guztiak ezabatu nahi dituzula historiatik?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Ekintza hau ezin da desegin.
+menu_action_save_to_pocket=Gorde Pocket-en
+menu_action_delete_pocket=Ezabatu Pocket-etik
+menu_action_archive_pocket=Artxibatu Pocket-en
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Erakutsi Finder-en
+menu_action_show_file_windows=Ireki dagoen karpeta
+menu_action_show_file_linux=Ireki dagoen karpeta
+menu_action_show_file_default=Erakutsi fitxategia
+menu_action_open_file=Ireki fitxategia
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Kopiatu deskargaren lotura
+menu_action_go_to_download_page=Joan deskargaren orrira
+menu_action_remove_download=Kendu historiatik
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Bilatu
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} bilaketa
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Bilatu webean
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Webeko istorio interesgarrienen hautapena, irakurtzen duzunean oinarrituta. Orain Mozillaren zati den Pocket bidez datoz.
+section_disclaimer_topstories_linktext=Ikasi nola dabilen.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ulertuta
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefoxen hasiera-orriko edukia
+prefs_home_description=Aukeratu zein eduki nahi duzun Firefoxen hasiera-orriko pantailan.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option=Errenkada bat;{num} errenkada
+prefs_search_header=Web bilaketa
+prefs_topsites_description=Gehien bisitatzen dituzun guneak
+prefs_topstories_description2=Webeko eduki baliotsua, zuretzat pertsonalizatuta
+prefs_topstories_options_sponsored_label=Babesleen istorioak
+prefs_topstories_sponsored_learn_more=Argibide gehiago
+prefs_highlights_description=Gorde edo bisitatu dituzun guneen hautapena
+prefs_highlights_options_visited_label=Bisitatutako orriak
+prefs_highlights_options_download_label=Azken deskarga
+prefs_highlights_options_pocket_label=Pocket-en gordetako orriak
+prefs_snippets_description=Mozilla eta Firefoxi buruzko eguneraketak
+settings_pane_button_label=Pertsonalizatu fitxa berriaren orria
+settings_pane_topsites_header=Gune erabilienak
+settings_pane_highlights_header=Nabarmendutakoak
+settings_pane_highlights_options_bookmarks=Laster-markak
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Mezu-zatiak
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Editatu
+edit_topsites_edit_button=Editatu gune hau
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Maiz erabilitako gune berria
+topsites_form_edit_header=Editatu maiz erabilitako gunea
+topsites_form_title_label=Izenburua
+topsites_form_title_placeholder=Idatzi izenburua
+topsites_form_url_label=URLa
+topsites_form_image_url_label=Irudi pertsonalizatuaren URLa
+topsites_form_url_placeholder=Idatzi edo itsatsi URLa
+topsites_form_use_image_link=Erabili irudi pertsonalizatua…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Aurrebista
+topsites_form_add_button=Gehitu
+topsites_form_save_button=Gorde
+topsites_form_cancel_button=Utzi
+topsites_form_url_validation=Baliozko URLa behar da
+topsites_form_image_validation=Ezin da irudia kargatu. Saiatu beste URL batekin.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Gai ezagunak:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Ikusi istorio gehiago
+
+highlights_empty_state=Hasi nabigatzen eta azkenaldian bisitatutako edo laster-marka egindako aparteko artikulu, bideo eta orriak erakutsiko ditugu.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Egunean zaude jada. Etorri berriro geroago {provider} hornitzailearen istorio ezagun gehiagorako. Ezin duzu itxaron? Hautatu gai ezagun bat webeko istorio gehiago aurkitzeko.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Probatu Firefox beste nabigatzaile batetik ekarritako laster-marka, historia eta pasahitzekin.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Ez, eskerrik asko
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Inportatu orain
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Kontxo, zerbait gaizki joan da edukia kargatzerakoan.
+error_fallback_default_refresh_suggestion=Berritu orria berriro saiatzeko.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Kendu atala
+section_menu_action_collapse_section=Tolestu atala
+section_menu_action_expand_section=Zabaldu atala
+section_menu_action_manage_section=Kudeatu atala
+section_menu_action_manage_webext=Kudeatu hedapena
+section_menu_action_add_topsite=Gehitu maiz erabilitako gunea
+section_menu_action_move_up=Eraman gora
+section_menu_action_move_down=Eraman behera
+section_menu_action_privacy_notice=Pribatutasun-oharra
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Eraman Firefox aldean
+firstrun_content=Izan laster-markak, historia, pasahitzak eta beste ezarpenak eskura zure gailu guztietatik.
+firstrun_learn_more_link=Firefox kontuei buruzko argibide gehiago
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Idatzi zure helbide elektronikoa
+firstrun_form_sub_header=Firefox Sync-ekin jarraitzeko.
+
+firstrun_email_input_placeholder=Helbide elektronikoa
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Jarraitzearekin bat, {terms} eta {privacy} onartzen dituzu.
+firstrun_terms_of_service=Zerbitzu-baldintzak
+firstrun_privacy_notice=Pribatutasun-oharra
+
+firstrun_continue_to_login=Jarraitu
+firstrun_skip_login=Saltatu urrats hau
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/fa/strings.properties
@@ -0,0 +1,149 @@
+newtab_page_title=زبانه جدید
+
+header_top_sites=سایت‌های برتر
+header_highlights=برجسته‌ها
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=پیشنهاد شده توسط {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=بازکردن فهرست زمینه برای {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=مشاهده شده
+type_label_bookmarked=نشانک شده
+type_label_recommended=موضوعات داغ
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=نشانک
+menu_action_remove_bookmark=حذف نشانک
+menu_action_open_new_window=باز کردن در یک پنجره جدید
+menu_action_open_private_window=بار کردن در یک پنجره ناشناس جدید
+menu_action_dismiss=رد کردن
+menu_action_delete=حذف از تاریخچه
+menu_action_pin=سنجاق کردن
+menu_action_unpin=جدا کردن
+confirm_history_delete_p1=آیا از پاک کردن همه نمونه‌های این صفحه از تاریخ‌چه خود اطمینان دارید؟
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=این عمل قابل برگشت نیست.
+menu_action_save_to_pocket=ذخیره‌سازی در Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=جست‌وجو
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=جست‌وجو {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=جست‌وجوی وب
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=جالب‌ترین داستان‌ها در وب، بر اساس آنچه شما خواندید انتخاب شده است. از Pocket، که حالا بخشی از Mozilla است.
+section_disclaimer_topstories_linktext=ببینید چگونه کار می‌کند.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=باشه، گرفتم
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+settings_pane_button_label=صفحهٔ زبانه جدید را سفارشی کنید
+settings_pane_topsites_header=سایت‌های برتر
+settings_pane_highlights_header=برجسته‌ها
+settings_pane_highlights_options_bookmarks=نشانک‌ها
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=قطعه‌ها
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=ويرايش
+edit_topsites_edit_button=ویرایش این سایت
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=سایت برتر جدید
+topsites_form_edit_header=ویرایش سایت برتر
+topsites_form_title_placeholder=عنوان را وارد کنید
+topsites_form_url_placeholder=یک URL تایپ کنید یا بچسبانید
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_add_button=افزودن
+topsites_form_save_button=ذخیره
+topsites_form_cancel_button=انصراف
+topsites_form_url_validation=URL معتبر الزامی است
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=موضوع‌های محبوب:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=مشاهده داستان‌های بیشتر
+
+highlights_empty_state=مرور کردن را شروع کنید و شاهد تعداد زیادی مقاله، فیلم و صفحات خوبی باشید که اخیر مشاهده کرده اید یا نشانگ گذاری کرده اید.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=فعلا تموم شد. بعدا دوباره سر بزن تا مطالب جدید از {provider} ببینی. نمی‌تونی صبر کنی؟ یک موضوع محبوب رو انتخاب کن تا مطالب جالب مرتبط از سراسر دنیا رو پیدا کنی.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=فایرفاکس را با نشانک‌ها،‌ تاریخچه‌ها و کلمات عبور از سایر مرورگر ها تجربه کنید.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=نه ممنون
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=هم‌اکنون وارد شوند
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_move_up=جابه‌جایی به بالا
+section_menu_action_move_down=جابه‌جایی به پایین
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ff/strings.properties
@@ -0,0 +1,177 @@
+newtab_page_title=Tabbere hesere
+
+header_top_sites=Lowe dowrowe
+header_highlights=Jalbine
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Waggini ɗum ko {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Uddit dosol ngonka wonande {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Uddit taƴre dosol ngonka
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Yilliima
+type_label_bookmarked=Maantaa maanto deftere
+type_label_recommended=Ina tiindii
+type_label_pocket=Danndaama e Pocket
+type_label_downloaded=Awtaama
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Maanto ɗerewol
+menu_action_remove_bookmark=Momtu maanto ɗerewol
+menu_action_open_new_window=Uddit e Henorde Hesere
+menu_action_open_private_window=Uddit e Henorde Suturo Hesere
+menu_action_dismiss=Salo
+menu_action_delete=Momtu e daartol
+menu_action_pin=Ñippu
+menu_action_unpin=Ñippit
+confirm_history_delete_p1=Aɗa yananaa yiɗde momtude kala cilol ngoo hello e to aslol maa?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Ngal baɗal waawaa firteede.
+menu_action_save_to_pocket=Danndu e Pocket
+menu_action_delete_pocket=Momtu e Pocket
+menu_action_archive_pocket=Mooftu nder Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Hollit e Finder
+menu_action_show_file_windows=Uddit loowdi doosiyee
+menu_action_show_file_linux=Uddit loowdi doosiyee
+menu_action_show_file_default=Hollit fiilde
+menu_action_open_file=Uddit Fiilde
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Natto jokkorde awtaande ndee
+menu_action_go_to_download_page=Yah to hello awtaango ngoo
+menu_action_remove_download=Momtu ɗum e kewol hee
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Yiylo
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} Yiylo
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Yiylo geese
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Daarti ɓurɗi teeŋtude e geese ɗee, cuɓaaɗi e yowitaade e ko tarɗaa. Ummoraade e Pocket, jeyaaɗo jooni e Mozilla.
+section_disclaimer_topstories_linktext=Humpito hol no ɗum gollortoo.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Eey, mi faamii
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Loowdi Jaɓɓorgo Firefox
+prefs_home_description=Suɓo hol loowdi njiɗɗaa e yaynirde jaɓɓorgo Firefox maa.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} gorol;{num} gorol
+prefs_search_header=Njiilaw Geese
+prefs_topsites_description=Lowe ɗe ɓurɗaa waawde yillaade
+prefs_topstories_description2=Loowdi dowrowri geese, keertinanaandi ma
+prefs_topstories_options_sponsored_label=Daari joɓanaaɗi
+prefs_topstories_sponsored_learn_more=Ɓeydu humpito
+prefs_highlights_description=Suɓngo lowe ɗe ndannduɗaa walla ɗe njilliɗaa
+prefs_highlights_options_visited_label=Kelle jiyaaɗe
+prefs_highlights_options_download_label=Cakkitiiɗe awteede
+prefs_highlights_options_pocket_label=Kelle kisnaaɗe e Pocket
+prefs_snippets_description=Kesɗitineiwde e Mozilla kañum e Firefox
+settings_pane_button_label=Neɗɗin tabbere maa hello hesere ndee
+settings_pane_topsites_header=Lowre Rowrowe
+settings_pane_highlights_header=Jalbine
+settings_pane_highlights_options_bookmarks=Maantore
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Taƴitine
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Taƴto
+edit_topsites_edit_button=Taƴto ndee lowre
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Lowre Dowrowre Hesere
+topsites_form_edit_header=Taƴto Lowre Dowrowre
+topsites_form_title_label=Tiitoonde
+topsites_form_title_placeholder=Naatnu tiitoonde
+topsites_form_url_label=URL
+topsites_form_image_url_label=Neɗɗin ngal natal URL
+topsites_form_url_placeholder=Tappu walla ɗakku URL
+topsites_form_use_image_link=Huutoro natal neɗɗinangal…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Sooyno
+topsites_form_add_button=Ɓeydu
+topsites_form_save_button=Daɗndu
+topsites_form_cancel_button=Haaytu
+topsites_form_url_validation=URL Moƴƴo ina naamnaa
+topsites_form_image_validation=loowgol natal gallii. Enndir URL goɗɗo.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Loowdiiji lolluɗi:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Yiy Daarti Goɗɗi
+
+highlights_empty_state=Fuɗɗo wanngaade, min kolloymaa huunde e binndanɗe mawɗe ɗee, widewooji kañum e kelle goɗɗe ɗe njilliɗaa ko ɓooyaani walla maantoraaɗe ɗoo.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Rutto ɗoo goɗngol ngam daari goɗɗi {provider}. A waawaa fadde ? Suvo tiitoonde lollunde ngam yiytude e geese hee daari goɗɗi.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Ƴeewndo Firefox wonndude e maantore ɗee, aslol kam e finndeeji iwde e wanngorde woɗnde.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Alaa, moƴƴii
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Jiggo Jooni
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Uf, saɗeende kewii e loowgol ngoo loowdi.
+error_fallback_default_refresh_suggestion=Wultin hello ngoo ngam ennditde.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Momtu taƴre
+section_menu_action_collapse_section=Renndin taƴe
+section_menu_action_expand_section=Yaajtin taƴre
+section_menu_action_manage_section=Feewnu taƴre
+section_menu_action_add_topsite=Ɓeydu lowre rowrowre
+section_menu_action_move_up=Dirtin dow
+section_menu_action_move_down=Dirtin les
+section_menu_action_privacy_notice=Tintinal sirlu
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/fi/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Uusi välilehti
+
+header_top_sites=Ykkössivustot
+header_highlights=Nostot
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Suositukset lähteestä {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Avaa pikavalikko sivustolle {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Avaa osion ponnahdusvalikko
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Vierailtu
+type_label_bookmarked=Kirjanmerkki
+type_label_recommended=Pinnalla
+type_label_pocket=Tallennettu Pocket-palveluun
+type_label_downloaded=Ladatut
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Lisää kirjanmerkki
+menu_action_remove_bookmark=Poista kirjanmerkki
+menu_action_open_new_window=Avaa uuteen ikkunaan
+menu_action_open_private_window=Avaa uuteen yksityiseen ikkunaan
+menu_action_dismiss=Hylkää
+menu_action_delete=Poista historiasta
+menu_action_pin=Kiinnitä
+menu_action_unpin=Poista kiinnitys
+confirm_history_delete_p1=Haluatko varmasti poistaa tämän sivun kaikkialta historiastasi?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Tämä toiminto on peruuttamaton.
+menu_action_save_to_pocket=Tallenna Pocket-palveluun
+menu_action_delete_pocket=Poista Pocket-palvelusta
+menu_action_archive_pocket=Arkistoi Pocket-palveluun
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Näytä Finderissa
+menu_action_show_file_windows=Avaa kohteen kansio
+menu_action_show_file_linux=Avaa kohteen kansio
+menu_action_show_file_default=Näytä tiedosto
+menu_action_open_file=Avaa tiedosto
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Kopioi latauslinkki
+menu_action_go_to_download_page=Siirry ladatulle sivulle
+menu_action_remove_download=Poista historiasta
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Haku
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name}-haku
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Verkkohaku
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Verkon kiinnostavimmat jutut, lukemasi perusteella valittuna. Pocketilta, joka on nyt osa Mozillaa.
+section_disclaimer_topstories_linktext=Lue, miten tämä toimii.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Selvä
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefoxin aloitussivun sisältö
+prefs_home_description=Valitse Firefoxin aloitussivulle haluamasi sisältö.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} rivi;{num} riviä
+prefs_search_header=Verkkohaku
+prefs_topsites_description=Useimmin vierailemasi sivustot
+prefs_topstories_description2=Hyvää sisältöä kaikkialta verkosta, juuri sinulle
+prefs_topstories_options_sponsored_label=Sponsoroidut tarinat
+prefs_topstories_sponsored_learn_more=Lue lisää
+prefs_highlights_description=Valikoima sivustoja, joilla olet käynyt tai jotka olet tallentanut
+prefs_highlights_options_visited_label=Vieraillut sivustot
+prefs_highlights_options_download_label=Viimeisimmät lataukset
+prefs_highlights_options_pocket_label=Pocketiin tallennetut sivut
+prefs_snippets_description=Päivitykset Mozillalta ja Firefoxilta
+settings_pane_button_label=Muokkaa Uusi välilehti -sivua
+settings_pane_topsites_header=Ykkössivustot
+settings_pane_highlights_header=Nostot
+settings_pane_highlights_options_bookmarks=Kirjanmerkit
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Tiedonmuruset
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Muokkaa
+edit_topsites_edit_button=Muokkaa tätä sivustoa
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Uusi ykkössivusto
+topsites_form_edit_header=Muokkaa ykkössivustoa
+topsites_form_title_label=Otsikko
+topsites_form_title_placeholder=Kirjoita otsikko
+topsites_form_url_label=Osoite
+topsites_form_image_url_label=Oman kuvan osoite
+topsites_form_url_placeholder=Kirjoita tai liitä osoite
+topsites_form_use_image_link=Käytä omaa kuvaa…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Esikatsele
+topsites_form_add_button=Lisää
+topsites_form_save_button=Tallenna
+topsites_form_cancel_button=Peruuta
+topsites_form_url_validation=Kelvollinen osoite vaaditaan
+topsites_form_image_validation=Kuvan lataaminen epäonnistui. Kokeile toista osoitetta.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Suositut aiheet:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Katso lisää juttuja
+
+highlights_empty_state=Ala selata, niin tässä alkaa näkyä hyviä juttuja, videoita ja muita sivuja, joilla olet käynyt hiljattain tai jotka olet lisännyt kirjanmerkkeihin.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Ei enempää suosituksia juuri nyt. Katso myöhemmin uudestaan lisää ykkösjuttuja lähteestä {provider}. Etkö malta odottaa? Valitse suosittu aihe ja löydä lisää hyviä juttuja ympäri verkkoa.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Kokeile Firefoxia toisesta selaimesta tuotujen kirjanmerkkien, historian ja salasanojen kanssa.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Ei kiitos
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Tuo nyt
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Hups, jotain meni vikaan tätä sisältöä ladattaessa.
+error_fallback_default_refresh_suggestion=Yritä uudestaan päivittämällä sivu.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Poista osio
+section_menu_action_collapse_section=Pienennä osio
+section_menu_action_expand_section=Laajenna osio
+section_menu_action_manage_section=Muokkaa osiota
+section_menu_action_manage_webext=Hallitse laajennusta
+section_menu_action_add_topsite=Lisää ykkössivusto
+section_menu_action_move_up=Siirrä ylös
+section_menu_action_move_down=Siirrä alas
+section_menu_action_privacy_notice=Tietosuojakäytäntö
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Ota Firefox matkalle mukaan
+firstrun_content=Käytä kirjanmerkkejä, historiaa, salasanoja ja muita asetuksia kaikilla laitteillasi.
+firstrun_learn_more_link=Lue lisää Firefox-tilistä
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Kirjoita sähköpostisi
+firstrun_form_sub_header=jatkaaksesi Firefox Sync -palveluun.
+
+firstrun_email_input_placeholder=Sähköposti
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Jatkamalla hyväksyt {terms} ja {privacy}.
+firstrun_terms_of_service=käyttöehdot
+firstrun_privacy_notice=tietosuojakäytännön
+
+firstrun_continue_to_login=Jatka
+firstrun_skip_login=Ohita tämä vaihe
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/fr/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Nouvel onglet
+
+header_top_sites=Sites les plus visités
+header_highlights=Éléments-clés
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recommandations par {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Ouvrir le menu contextuel pour {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Ouvrir le menu contextuel de cette section
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visité
+type_label_bookmarked=Ajouté aux marque-pages
+type_label_recommended=Tendance
+type_label_pocket=Enregistré dans Pocket
+type_label_downloaded=Téléchargé
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Marquer cette page
+menu_action_remove_bookmark=Supprimer le marque-page
+menu_action_open_new_window=Ouvrir dans une nouvelle fenêtre
+menu_action_open_private_window=Ouvrir dans une nouvelle fenêtre privée
+menu_action_dismiss=Retirer
+menu_action_delete=Supprimer de l’historique
+menu_action_pin=Épingler
+menu_action_unpin=Détacher
+confirm_history_delete_p1=Voulez-vous vraiment supprimer de l’historique toutes les occurrences de cette page ?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Cette action est irréversible.
+menu_action_save_to_pocket=Enregistrer dans Pocket
+menu_action_delete_pocket=Supprimer de Pocket
+menu_action_archive_pocket=Archiver dans Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Afficher dans le Finder
+menu_action_show_file_windows=Ouvrir le dossier contenant le fichier
+menu_action_show_file_linux=Ouvrir le dossier contenant le fichier
+menu_action_show_file_default=Afficher le fichier
+menu_action_open_file=Ouvrir le fichier
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Copier l’adresse d’origine du téléchargement
+menu_action_go_to_download_page=Aller à la page de téléchargement
+menu_action_remove_download=Retirer de l’historique
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Rechercher
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Recherche {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Rechercher sur le Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Les articles les plus intéressants du Web, sélectionnés selon ce que vous lisez. Et ceci grâce à Pocket, qui fait désormais partie de Mozilla.
+section_disclaimer_topstories_linktext=Découvrez comment cela fonctionne.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=J’ai compris
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Contenu de la page d’accueil de Firefox
+prefs_home_description=Choisissez le contenu que vous souhaitez pour la page d’accueil de Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} ligne;{num} lignes
+prefs_search_header=Recherche web
+prefs_topsites_description=Les sites que vous visitez le plus
+prefs_topstories_description2=Du contenu intéressant en provenance du Web, personnalisé pour vous
+prefs_topstories_options_sponsored_label=Articles sponsorisés
+prefs_topstories_sponsored_learn_more=En savoir plus
+prefs_highlights_description=Une sélection de sites que vous avez sauvegardés ou visités
+prefs_highlights_options_visited_label=Pages visitées
+prefs_highlights_options_download_label=Dernier téléchargement
+prefs_highlights_options_pocket_label=Pages enregistrées dans Pocket
+prefs_snippets_description=Actualité de Mozilla et Firefox
+settings_pane_button_label=Personnaliser la page Nouvel onglet
+settings_pane_topsites_header=Sites les plus visités
+settings_pane_highlights_header=Éléments-clés
+settings_pane_highlights_options_bookmarks=Marque-pages
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Brèves
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Modifier
+edit_topsites_edit_button=Modifier ce site
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nouveau site populaire
+topsites_form_edit_header=Modifier le site populaire
+topsites_form_title_label=Titre
+topsites_form_title_placeholder=Saisir un titre
+topsites_form_url_label=Adresse web
+topsites_form_image_url_label=URL de l’image personnalisée
+topsites_form_url_placeholder=Saisir ou coller une adresse web
+topsites_form_use_image_link=Utiliser une image personnalisée…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Aperçu
+topsites_form_add_button=Ajouter
+topsites_form_save_button=Enregistrer
+topsites_form_cancel_button=Annuler
+topsites_form_url_validation=Adresse web valide requise
+topsites_form_image_validation=Échec du chargement de l’image. Essayez avec une autre URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Sujets populaires :
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Afficher plus d’articles
+
+highlights_empty_state=Commencez à naviguer puis nous afficherons des articles, des vidéos ou d’autres pages que vous avez récemment visités ou ajoutés aux marque-pages.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Il n’y en a pas d’autres. Revenez plus tard pour plus d’articles de {provider}. Vous ne voulez pas attendre ? Choisissez un sujet parmi les plus populaires pour découvrir d’autres articles intéressants sur le Web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Essayez Firefox en important les marque-pages, l’historique et les mots de passe depuis un autre navigateur.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Non merci
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importer
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Oups, une erreur s’est produite lors du chargement du contenu.
+error_fallback_default_refresh_suggestion=Actualisez la page pour réessayer.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Supprimer la section
+section_menu_action_collapse_section=Réduire la section
+section_menu_action_expand_section=Développer la section
+section_menu_action_manage_section=Gérer la section
+section_menu_action_manage_webext=Gérer l’extension
+section_menu_action_add_topsite=Ajouter un site populaire
+section_menu_action_move_up=Déplacer vers le haut
+section_menu_action_move_down=Déplacer vers le bas
+section_menu_action_privacy_notice=Politique de confidentialité
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Emportez Firefox avec vous
+firstrun_content=Accédez à vos marque-pages, votre historique, vos mots de passe et d’autres paramètres sur l’ensemble de vos appareils.
+firstrun_learn_more_link=En savoir plus sur les comptes Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Saisissez votre adresse électronique
+firstrun_form_sub_header=pour continuer avec Firefox Sync.
+
+firstrun_email_input_placeholder=Adresse électronique
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=En continuant, vous acceptez les {terms} et la {privacy}.
+firstrun_terms_of_service=Conditions d’utilisation
+firstrun_privacy_notice=Politique de confidentialité
+
+firstrun_continue_to_login=Continuer
+firstrun_skip_login=Ignorer cette étape
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/fy-NL/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Nij ljepblêd
+
+header_top_sites=Topwebsites
+header_highlights=Hichtepunten
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Oanrekommandearre troch {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Kontekstmenu foar {title} iepenje
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Kontekstmenu fan seksje iepenje
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Besocht
+type_label_bookmarked=Blêdwizer makke
+type_label_recommended=Trending
+type_label_pocket=Bewarre nei Pocket
+type_label_downloaded=Download
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Blêdwizer
+menu_action_remove_bookmark=Blêdwizer fuortsmite
+menu_action_open_new_window=Iepenje yn in nij finster
+menu_action_open_private_window=Iepenje yn in nij priveefinster
+menu_action_dismiss=Fuortsmite
+menu_action_delete=Fuortsmite út skiednis
+menu_action_pin=Fêstsette
+menu_action_unpin=Losmeitsje
+confirm_history_delete_p1=Binne jo wis dat jo elke ferwizing fan dizze side út jo skiednis fuortsmite wolle?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Dizze aksje kin net ûngedien makke wurde.
+menu_action_save_to_pocket=Bewarje nei Pocket
+menu_action_delete_pocket=Fuortsmite út Pocket
+menu_action_archive_pocket=Argivearje yn Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Toane yn Finder
+menu_action_show_file_windows=Byhearrende map iepenje
+menu_action_show_file_linux=Byhearrende map iepenje
+menu_action_show_file_default=Bestân toane
+menu_action_open_file=Bestân iepenje
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Downloadkeppeling kopiearje
+menu_action_go_to_download_page=Nei downloadside gean
+menu_action_remove_download=Fuortsmite út skiednis
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Sykje
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} trochsykje
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Sykje op it web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=De meast ynteressante ferhalen op it web, selektearre op basis fan wat jo lêzen hawwe. Fan Pocket, no ûnderdiel fan Mozilla.
+section_disclaimer_topstories_linktext=Lês hoe't it wurket.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Oké, begrepen
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Ynhâld fan Firefox-startside
+prefs_home_description=Kies hokker ynhâld jo op jo Firefox-startside werjaan wolle.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} rige;{num} rigen
+prefs_search_header=Sykje op it web
+prefs_topsites_description=De troch jo meast besochte websites
+prefs_topstories_description2=Bjusterbaarlike ynhâld fan it ynternet, oanpast foar jo
+prefs_topstories_options_sponsored_label=Sponsore ferhalen
+prefs_topstories_sponsored_learn_more=Mear ynfo
+prefs_highlights_description=In seleksje fan websites dy't jo bewarre of besocht hawwe
+prefs_highlights_options_visited_label=Besochte siden
+prefs_highlights_options_download_label=Meast resinte download
+prefs_highlights_options_pocket_label=Siden bewarre nei Pocket
+prefs_snippets_description=Fernijingen fan Mozilla en Firefox
+settings_pane_button_label=Jo side foar nije ljepblêden oanpasse
+settings_pane_topsites_header=Topwebsites
+settings_pane_highlights_header=Hichtepunten
+settings_pane_highlights_options_bookmarks=Blêdwizers
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Koarte ynformaasje
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Bewurkje
+edit_topsites_edit_button=Dizze side bewurkje
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nije topwebsite
+topsites_form_edit_header=Topwebsite tafoegje
+topsites_form_title_label=Titel
+topsites_form_title_placeholder=Titel ynfiere
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL fan oanpaste ôfbylding
+topsites_form_url_placeholder=Typ of plak in URL
+topsites_form_use_image_link=In oanpaste ôfbylding brûke…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Foarbyld
+topsites_form_add_button=Tafoegje
+topsites_form_save_button=Bewarje
+topsites_form_cancel_button=Annulearje
+topsites_form_url_validation=Jildige URL fereaske
+topsites_form_image_validation=Ofbylding koe net laden wurde. Probearje in oare URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Populêre ûnderwerpen:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Mear ferhalen besjen
+
+highlights_empty_state=Start mei sneupen en wy toane jo guon moaie artikelen, fideo's en oare siden dy't jo resint besocht hawwe of in blêdwizer fan makke hawwe.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Jo binne by. Kom letter werom foar mear ferhalen fan {provider}. Kin jo net wachtsje? Selektearje in populêr ûnderwerp om mear ferhalen fan it ynternet te finen.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Probearje Firefox en ymportearje de blêdwizers, skiednis en wachtwurden fan oare browsers.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Nee tankewol
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=No ymportearje
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Oeps, der is wat misgien by it laden fan dizze ynhâld.
+error_fallback_default_refresh_suggestion=Fernij de side om it opnij te probearjen.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Seksje fuortsmite
+section_menu_action_collapse_section=Seksje ynklappe
+section_menu_action_expand_section=Seksje útklappe
+section_menu_action_manage_section=Seksje beheare
+section_menu_action_manage_webext=Utwreiding beheare
+section_menu_action_add_topsite=Topwebsite tafoegje
+section_menu_action_move_up=Omheech ferpleatse
+section_menu_action_move_down=Omleech ferpleatse
+section_menu_action_privacy_notice=Privacyferklearring
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Nim Firefox mei jo mei
+firstrun_content=Krij jo blêdwizers, skiednis, wachtwurden en oare ynstellingen op al jo apparaten.
+firstrun_learn_more_link=Mear ynfo oer Firefox Accounts
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Fier jo e-mailadres yn
+firstrun_form_sub_header=om troch te gean nei Firefox Sync.
+
+firstrun_email_input_placeholder=E-mailadres
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Troch fierder te gean, gean jo akkoard mei de {terms} en {privacy}.
+firstrun_terms_of_service=Tsjinstbetingsten
+firstrun_privacy_notice=Privacyferklearring
+
+firstrun_continue_to_login=Trochgean
+firstrun_skip_login=Dizze stap oerslaan
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ga-IE/strings.properties
@@ -0,0 +1,133 @@
+newtab_page_title=Cluaisín Nua
+default_label_loading=Á Lódáil…
+
+header_top_sites=Barrshuímh
+header_stories=Barrscéalta
+header_visit_again=Cuairt Arís
+header_bookmarks=Leabharmharcanna Le Déanaí
+# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
+# meant to inform that section contains no information because
+# the user hasn't added any bookmarks.
+header_bookmarks_placeholder=Níl aon leabharmharcanna agat.
+# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
+# corresponding content (stories) provider
+header_stories_from=ó
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Feicthe
+type_label_bookmarked=Leabharmharcáilte
+type_label_synced=Sioncronaithe ó ghléas eile
+type_label_recommended=Treochtáil
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=Oscailte
+type_label_topic=Ábhar
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Cruthaigh leabharmharc
+menu_action_remove_bookmark=Scrios an Leabharmharc
+menu_action_copy_address=Cóipeáil an Seoladh
+menu_action_email_link=Seol an Nasc trí Ríomhphost…
+menu_action_open_new_window=Oscail i bhFuinneog Nua
+menu_action_open_private_window=Oscail i bhFuinneog Nua Phríobháideach
+menu_action_dismiss=Ruaig
+menu_action_delete=Scrios ón Stair
+menu_action_pin=Pionnáil
+menu_action_unpin=Díphionnáil
+confirm_history_delete_p1=An bhfuil tú cinnte gur mhaith leat an leathanach seo a scriosadh go hiomlán ó do stair?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Ní féidir an gníomh seo a chur ar ceal.
+menu_action_save_to_pocket=Sábháil in Pocket
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with=Déan cuardach ar {search_term} le:
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Cuardach
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Cuardach {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Cuardaigh an Gréasán
+search_settings=Socruithe Cuardaigh
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=Fáilte go dtí cluaisín nua
+welcome_body=Úsáidfidh Firefox an spás seo chun na leabharmharcanna, ailt, físeáin, agus leathanaigh is tábhachtaí a thaispeáint duit, ionas go mbeidh tú in ann filleadh orthu gan stró.
+welcome_label=Buaicphointí á lorg
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=< 1 n
+time_label_minute={number}n
+time_label_hour={number}u
+time_label_day={number}l
+
+# LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar.
+settings_pane_button_label=Saincheap an Leathanach do Chluaisín Nua
+settings_pane_header=Sainroghanna do Chluaisín Nua
+settings_pane_body=Roghnaigh na rudaí a fheicfidh tú nuair a osclóidh tú cluaisín nua.
+settings_pane_search_header=Cuardach
+settings_pane_search_body=Cuardaigh an Gréasán go díreach ón gcluaisín nua.
+settings_pane_topsites_header=Barrshuímh
+settings_pane_topsites_body=Na suímh Ghréasáin a dtugann tú cuairt orthu is minice.
+settings_pane_topsites_options_showmore=Taispeáin dhá shraith
+settings_pane_bookmarks_header=Leabharmharcanna Le Déanaí
+settings_pane_bookmarks_body=Do chuid leabharmharcanna nua in áit amháin.
+settings_pane_visit_again_header=Cuairt Arís
+settings_pane_visit_again_body=Taispeánann Firefox nascanna ó do stair bhrabhsála a mbeadh suim agat filleadh orthu amach anseo.
+settings_pane_pocketstories_header=Barrscéalta
+settings_pane_pocketstories_body=Le Pocket, ball de theaghlach Mozilla, beidh tú ábalta teacht ar ábhar den chéad scoth go héasca.
+settings_pane_done_button=Déanta
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Eagar
+edit_topsites_button_label=Saincheap na Barrshuímh
+edit_topsites_showmore_button=Taispeáin níos mó
+edit_topsites_showless_button=Taispeáin níos lú
+edit_topsites_done_button=Déanta
+edit_topsites_pin_button=Greamaigh an suíomh seo
+edit_topsites_unpin_button=Díghreamaigh an suíomh seo
+edit_topsites_edit_button=Cuir an suíomh seo in eagar
+edit_topsites_dismiss_button=Ruaig an suíomh seo
+edit_topsites_add_button=Cuir leis
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Barrshuíomh Nua
+topsites_form_edit_header=Cuir an Barrshuíomh in Eagar
+topsites_form_title_placeholder=Cuir teideal isteach
+topsites_form_url_placeholder=Clóscríobh nó greamaigh URL
+topsites_form_add_button=Cuir leis
+topsites_form_save_button=Sábháil
+topsites_form_cancel_button=Cealaigh
+topsites_form_url_validation=URL neamhbhailí
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Topaicí i mbéal an phobail:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Tuilleadh Scéalta
+# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
+# to Pocket as part of the feedback form.
+pocket_feedback_header=Ábhar den chéad scoth ón Ghréasán, le níos mó ná 25 milliún duine i mbun coimeádaíochta.
+# LOCALIZATION NOTE (pocket_feedback_body): This is shown below
+# (pocket_feedback_header) to provide more information about Pocket.
+pocket_feedback_body=Le Pocket, ball de theaghlach Mozilla, beidh tú ábalta teacht ar ábhar den chéad scoth go héasca.
+pocket_send_feedback=Tabhair Aiseolas Dúinn
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/gd/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Taba ùr
+
+header_top_sites=Brod nan làrach
+header_highlights=Sàr-roghainn
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=’Ga mholadh le {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Fosgail an clàr-taice co-theacsail aig {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Fosgail clàr-taice co-theacsail na h-earrainn
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Na thadhail thu air
+type_label_bookmarked=’Nan comharran-lìn
+type_label_recommended=A’ treandadh
+type_label_pocket=Air a shàbhaladh ann am Pocket
+type_label_downloaded=Air a luchdadh a-nuas
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Comharra-lìn
+menu_action_remove_bookmark=Thoir an comharra-lìn air falbh
+menu_action_open_new_window=Fosgail ann an uinneag ùr
+menu_action_open_private_window=Fosgail ann an uinneag phrìobhaideach ùr
+menu_action_dismiss=Leig seachad
+menu_action_delete=Sguab às an eachdraidh
+menu_action_pin=Prìnich
+menu_action_unpin=Dì-phrìnich
+confirm_history_delete_p1=A bheil thu cinnteach gu bheil thu airson gach ionstans na duilleige seo a sguabadh às an eachdraidh agad?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Cha ghabh seo a neo-dhèanamh.
+menu_action_save_to_pocket=Sàbhail sa phòcaid
+menu_action_delete_pocket=Air a sguabadh à Pocket
+menu_action_archive_pocket=Tasglannaich ann am Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Seall san lorgair
+menu_action_show_file_windows=Fosgail am pasgan far a bheil e
+menu_action_show_file_linux=Fosgail am pasgan far a bheil e
+menu_action_show_file_default=Seall am faidhle
+menu_action_open_file=Fosgail faidhle
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Dèan lethbhreac dhen cheangal luchdaidh
+menu_action_go_to_download_page=Tadhail aor duilleag nan luchdaidhean
+menu_action_remove_download=Thoir air falbh on eachdraidh
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Lorg
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Lorg le {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Lorg air an lìon
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Na sgeulachdan as inntinniche air an lìon, air a thaghadh a-rèir na bhios tu a’ leughadh. O Phocket, a tha ’na phàirt de Mhozilla a-nis.
+section_disclaimer_topstories_linktext=Seo mar a dh’obraicheas e.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ceart, tha mi agaibh
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Susbaint sgrìn mhòr Firefox
+prefs_home_description=Tagh an t-susbaint a bu mhath leat fhaicinn air sgrìn mhòr Firefox
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} ràgh;{num} ràgh;{num} ràghan;{num} ràgh
+prefs_search_header=Lorg air an lìon
+prefs_topsites_description=Na làraichean air an tadhail thu as trice
+prefs_topstories_description2=Sàr-shusbaint o fheadh an lìn, air a phearsantachadh dhut-sa
+prefs_topstories_options_sponsored_label=Sgeulachdan sponsairichte
+prefs_topstories_sponsored_learn_more=Barrachd fiosrachaidh
+prefs_highlights_description=Taghadh de làraichean a shàbhail thu no air an do thadhail thu
+prefs_highlights_options_visited_label=Duilleagan air an do thadhail thu
+prefs_highlights_options_download_label=Air a luchdadh a-nuas o chionn goirid
+prefs_highlights_options_pocket_label=Duilleagan air an sàbhaladh ann am Pocket
+prefs_snippets_description=Ùrachaidhean o Mozilla is Firefox
+settings_pane_button_label=Gnàthaich duilleag nan tabaichean ùra agad
+settings_pane_topsites_header=Brod nan làrach
+settings_pane_highlights_header=Sàr-roghainn
+settings_pane_highlights_options_bookmarks=Comharran-lìn
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Snippets
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Deasaich
+edit_topsites_edit_button=Deasaich an làrach seo
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Brod làraich ùr
+topsites_form_edit_header=Deasaich am brod làraich
+topsites_form_title_label=Tiotal
+topsites_form_title_placeholder=Cuir ainm a-steach
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL deilbh gnàthaichte
+topsites_form_url_placeholder=Sgrìobh URL no cuir fear ann
+topsites_form_use_image_link=Cleachd dealbh gnàthaichte...
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Ro-shealladh
+topsites_form_add_button=Cuir ris
+topsites_form_save_button=Sàbhail
+topsites_form_cancel_button=Sguir dheth
+topsites_form_url_validation=Tha feum air URL dligheach
+topsites_form_image_validation=Dh’fhàillig luchdadh an deilbh. Feuch URL eile.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Cuspairean fèillmhor:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Seall barrachd sgeul
+
+highlights_empty_state=Tòisich air brabhsadh is seallaidh sinn dhut an-seo cuid dhe na h-artaigilean, videothan is duilleagan eile air an do thadhail thu no a chuir thu ris na comharran-lìn o chionn ghoirid.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Sin na naidheachdan uile o {provider} an-dràsta ach bidh barrachd ann a dh’aithghearr. No thoir sùil air cuspair air a bheil fèill mhòr is leugh na tha a’ dol mun cuairt air an lìon an-dràsta.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Feuch Firefox leis na comharran-lìn, an eachdraidh ’s na faclan-faire o bhrabhsair eile.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Chan eil, tapadh leibh
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Ion-phortaich an-dràsta
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ìoc, chaidh rudeigin cearr fhad ’s a bha sinn a’ luchdadh na susbaint seo.
+error_fallback_default_refresh_suggestion=Ath-nuadhaich an duilleag airson fheuchainn ris a-rithist.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Thoir an earrann air falbh
+section_menu_action_collapse_section=Co-theannaich an earrann
+section_menu_action_expand_section=Leudaich an earrann
+section_menu_action_manage_section=Stiùirich an earrann
+section_menu_action_manage_webext=Stiùirich an leudachan
+section_menu_action_add_topsite=Cuir ris brod làraich
+section_menu_action_move_up=Gluais suas
+section_menu_action_move_down=Gluais sìos
+section_menu_action_privacy_notice=Sanas prìobhaideachd
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Thoir Firefox leat
+firstrun_content=Faigh na comharran-lìn, an eachdraidh, na faclan-faire ’s roghainnean eile air na h-uidheaman air fad agad.
+firstrun_learn_more_link=Barrachd fiosrachaidh air cunntasan Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Cuir a-steach am post-d agad
+firstrun_form_sub_header=a leantainn air adhart gu sioncronachadh Firefox.
+
+firstrun_email_input_placeholder=Post-d
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Ma leanas tu air adhart, bidh tu ag aontachadh ri {terms} agus {privacy}.
+firstrun_terms_of_service=teirmichean na seirbheise
+firstrun_privacy_notice=aithris na prìobhaideachd
+
+firstrun_continue_to_login=Lean air adhart
+firstrun_skip_login=Leum seachad air seo
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/gl/strings.properties
@@ -0,0 +1,192 @@
+newtab_page_title=Nova lapela
+
+header_top_sites=Sitios favoritos
+header_highlights=Destacados
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recomendado por {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Abrir o menú contextual para {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Abrir o menú contextual da sección
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visitados
+type_label_bookmarked=Nos marcadores
+type_label_recommended=Tendencias
+type_label_pocket=Gardado no Pocket
+type_label_downloaded=Descargado
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Engadir aos marcadores
+menu_action_remove_bookmark=Retirar marcador
+menu_action_open_new_window=Abrir nunha nova xanela
+menu_action_open_private_window=Abrir nunha nova xanela privada
+menu_action_dismiss=Rexeitar
+menu_action_delete=Eliminar do historial
+menu_action_pin=Fixar
+menu_action_unpin=Quitar
+confirm_history_delete_p1=Confirma que quere eliminar do historial todas as instancias desta páxina?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Non é posíbel desfacer esta acción.
+menu_action_save_to_pocket=Gardar en Pocket
+menu_action_delete_pocket=Eliminar do Pocket
+menu_action_archive_pocket=Arquivar no Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Amosar no Finder
+menu_action_show_file_windows=Abrir o cartafol que o contén
+menu_action_show_file_linux=Abrir o cartafol que o contén
+menu_action_show_file_default=Amosar o ficheiro
+menu_action_open_file=Abrir o ficheiro
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Copiar ligazón de descarga
+menu_action_go_to_download_page=Ir á páxina de descargas
+menu_action_remove_download=Retirar do historial
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Buscar
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Busca de {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Buscar na Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=As historias máis interesantes da web, seleccionadas en función do que vostede lee. Grazas a Pocket, que agora é parte de Mozilla.
+section_disclaimer_topstories_linktext=Coñeza como funciona.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Entendín
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Contido da páxina de inicio de Firefox
+prefs_home_description=Escolla o contido que quere na pantalla de inicio de Firefox.
+prefs_restore_defaults_button=Restaurar a configuración predeterminada
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} fila;{num} filas
+prefs_search_header=Busca na web
+prefs_topsites_description=Os sitios que máis visita
+prefs_topstories_description2=Os mellores contidos dispoñíbeis na web, personalizados para vostede
+prefs_topstories_options_sponsored_label=Historias patrocinadas
+prefs_topstories_sponsored_learn_more=Máis información
+prefs_highlights_description=Unha selección de sitios que gardou ou visitou
+prefs_highlights_options_visited_label=Páxinas visitadas
+prefs_highlights_options_download_label=A descarga máis recente
+prefs_highlights_options_pocket_label=Páxinas gardadas en Pocket
+prefs_snippets_description=Actualizacións de Mozilla e Firefox
+settings_pane_button_label=Personalice a páxina de nova lapela
+settings_pane_header=Preferencias de nova lapela
+settings_pane_body2=Escolla que quere ver nesta páxina.
+settings_pane_search_header=Busca
+settings_pane_search_body=Busca na web dende a nova lapela.
+settings_pane_topsites_header=Sitios favoritos
+settings_pane_topsites_body=Acceda aos sitios web que máis visita.
+settings_pane_topsites_options_showmore=Amosar dúas filas
+settings_pane_highlights_header=Destacados
+settings_pane_highlights_body2=Atope algunhas páxinas interesantes que vostede xa visitou ou marcou recentemente.
+settings_pane_highlights_options_bookmarks=Marcadores
+settings_pane_highlights_options_visited=Sitios visitados
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Fragmentos
+settings_pane_snippets_body=Lea noticias curtas de Mozilla sobre o Firefox, a cultura de Internet, e ocasionalmente, algún meme.
+settings_pane_done_button=Feito
+settings_pane_topstories_options_sponsored=Amosar historias patrocinadas
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Editar
+edit_topsites_edit_button=Editar este sitio
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Novo sitio favorito
+topsites_form_edit_header=Editar sitio favorito
+topsites_form_title_label=Título
+topsites_form_title_placeholder=Escribir un título
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL da imaxe personalizada
+topsites_form_url_placeholder=Escribir ou pegar un URL
+topsites_form_use_image_link=Usar unha imaxe personalizada…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Previsualizar
+topsites_form_add_button=Engadir
+topsites_form_save_button=Gardar
+topsites_form_cancel_button=Cancelar
+topsites_form_url_validation=Requírese un URL válido
+topsites_form_image_validation=Produciuse un fallo ao cargar a imaxe. Probe un URL diferente.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Temas populares:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Ver máis historias
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=Grazas a Pocket, que agora forma parte de Mozilla, poderá descubrir contido de gran calidade que doutra forma se perdería.
+
+highlights_empty_state=Comece a navegar e aquí amosarémoslle algúns dos mellores artigos, vídeos e outras páxinas que visitara recentemente ou que engadira aos marcadores.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Xa está ao día. Regrese máis tarde para ver máis historias de {provider}. Non pode agardar? Seleccione un tema popular e atopará máis historias interesantes da web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Probe Firefox cos marcadores, historial e contrasinais doutro navegador.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Non, grazas
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importar agora
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Vaites, produciuse un erro ao cargar este contido.
+error_fallback_default_refresh_suggestion=Actualice a páxina para tentalo de novo.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Retirar sección
+section_menu_action_collapse_section=Contraer sección
+section_menu_action_expand_section=Expandir sección
+section_menu_action_manage_section=Xestionar sección
+section_menu_action_add_topsite=Engadir sitio favorito
+section_menu_action_move_up=Subir
+section_menu_action_move_down=Baixar
+section_menu_action_privacy_notice=Política de privacidade
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/gn/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Tendayke Pyahu
+
+header_top_sites=Tenda Ojehechavéva
+header_highlights=Mba'eporãitéva
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} he'i ndéve reike hag̃ua
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Embojuruja poravorã {title} peg̃uarã
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Eike poravorã vore jereguávape
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Jeikepyre
+type_label_bookmarked=Oñeñongatuva'ekue techaukaháramo
+type_label_recommended=Ojehechajepíva
+type_label_pocket=Pocket-pe ñongatupyre
+type_label_downloaded=Mboguejypyre
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Techaukaha
+menu_action_remove_bookmark=Techaukaha Mboguete
+menu_action_open_new_window=Jeike Ovetã Pyahúpe
+menu_action_open_private_window=Jeike Ovetã Ñemi Pyahúpe
+menu_action_dismiss=Emboyke
+menu_action_delete=Tembiasakue Rysýigui Ñeguenohẽ
+menu_action_pin=Mboja
+menu_action_unpin=Mboja'ỹ
+confirm_history_delete_p1=Añetehápepa renohẽse oimeraẽva mba'e ko toguepegua tembiasakue rysýigui?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Ko ojejapóva ndaikatuvéima oñemboguevi.
+menu_action_save_to_pocket=Eñongatu Pocket-pe
+menu_action_delete_pocket=Embogue Pocket-pe
+menu_action_archive_pocket=Eñongatu Pocket-pe
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Ehechauka Finder-pe
+menu_action_show_file_windows=Embojuruja ñongatuha guerekopýva
+menu_action_show_file_linux=Embojuruja ñongatuha guerekopýva
+menu_action_show_file_default=Ehechauka marandurenda
+menu_action_open_file=Embojuruja marandurenda
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Emonguatia juajuha kundaharape
+menu_action_go_to_download_page=Eho ñemboguejyha kuatiaroguépe
+menu_action_remove_download=Emboguepa tembiasakuégui
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Eheka
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Eheka {search_engine_name} ndive
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Ñandutivevépe Jeheka
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Mba'erechapyrã ñandutivevepegua ojeiporavóva ndéve g̃uarã ojejesareko rupi remoñe'ẽva jepi rehe. Pocket guive ha'éva ko'ág̃a Mozilla mba'e.
+section_disclaimer_topstories_linktext=Eikuaave mba'éichapa oiko.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Oĩma, hesakãma chéve
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Kuatiarogue retepy Firefox ñepyrũháme
+prefs_home_description=Eiporavo mba’e retepýpa eipota Firefox mba’erechaha ñepyrũháme.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} rysýi; {num} rysýi
+prefs_search_header=Ñandutípe jeheka
+prefs_topsites_description=Umi tenda ojeikeveha
+prefs_topstories_description2=Iporãvéva ñanduti retepy, oñemomba’éva ndéve g̃uarã
+prefs_topstories_options_sponsored_label=Tembiasakue jehepyme'ẽguáva
+prefs_topstories_sponsored_learn_more=Kuaave
+prefs_highlights_description=Tenda jeporavopy eñongatu térã eike hague
+prefs_highlights_options_visited_label=Tenda jeikepyre
+prefs_highlights_options_download_label=Oñemboguejy ramovéva
+prefs_highlights_options_pocket_label=Kuatiarogue ñongatupyre Pocket-pe
+prefs_snippets_description=Mozilla ha Firefox ñembohekopyahu
+settings_pane_button_label=Eñemomba'e ne Tendayke Pyahu roguére
+settings_pane_topsites_header=Tenda Ojeikevéva
+settings_pane_highlights_header=Mba'erechapyrã
+settings_pane_highlights_options_bookmarks=Techaukaha
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Mba'epehẽ
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Mbosako'i
+edit_topsites_edit_button=Embosako'i ko tenda
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Tenda Pyahu Ojeikevéva
+topsites_form_edit_header=Tenda Ojeikevéva Mbosako'i
+topsites_form_title_label=Teratee
+topsites_form_title_placeholder=Ehai herarã
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL ra’anga ñemomba’etepyre
+topsites_form_url_placeholder=Ehai térã emboja peteĩ URL
+topsites_form_use_image_link=Ta’anga ñemomba’etepyre…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Jehecha ypy
+topsites_form_add_button=Embojoapy
+topsites_form_save_button=Ñongatu
+topsites_form_cancel_button=Heja
+topsites_form_url_validation=Oñeikotevẽ URL oiko porãva
+topsites_form_image_validation=Ta’anga nehenyhẽkuái. Eipuru peteĩ URL iñambuéva.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Ñe'ẽmbyrã Ojehayhuvéva:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Ahechaseve Mombe'upy
+
+highlights_empty_state=Eñepyrũ eikundaha ha rohechaukáta ndéve mba'ehai, mba'erecharã oĩva ha ambue ñandutirenda reikeva'ekue ýrõ rembotechaukava'ekue.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Ko'ág̃a reikuaapáma ipyahúva. Eikejey ag̃ave ápe eikuaávo mombe'upy pyahu {provider} oikuave'ẽva ndéve. Ndaikatuvéima reha'ãrõ? Eiporavo peteĩ ñe'ẽmbyrã ha emoñe'ẽve oĩvéva ñande yvy ape ári.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Eipuru Firefox reheve techaukaha, tembiasakue ha ñe'ẽñemi ambue kundaharapegua.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Ag̃amiénte
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Egueroike Ko'ág̃a
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ema'ẽ, mba’épa osẽvai henyhẽnguévo ko tetepy.
+error_fallback_default_refresh_suggestion=Kuatiarogue mbopiro’y eñepyrũjey hag̃ua
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Emboguete vore
+section_menu_action_collapse_section=Embopytupa vore
+section_menu_action_expand_section=Emyasãi vore
+section_menu_action_manage_section=Eñagareko vorére
+section_menu_action_manage_webext=Emongu'e jepysokue
+section_menu_action_add_topsite=Embojuaju Tenda ojeikeveha
+section_menu_action_move_up=Jupi
+section_menu_action_move_down=Guejy
+section_menu_action_privacy_notice=Marandu’i ñemiguáva
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Egueraha Firefox nendive
+firstrun_content=Eike nde techaukaha, tembiasakue, ñe’ẽñemi ha ambueve ñemoĩporã opaite nde mba’e’okápe.
+firstrun_learn_more_link=Eikuaave Firefox Accounts rehegua
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Emoinge ne ñandutiveve
+firstrun_form_sub_header=eike hag̃ua Firefox Sync-pe.
+
+firstrun_email_input_placeholder=Ñandutiveve
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Ejapóva, emoneĩ ko'ã {terms} ha {privacy}.
+firstrun_terms_of_service=Mba'epytyvõrã ñemboguata
+firstrun_privacy_notice=Ñemigua purureko
+
+firstrun_continue_to_login=Eku'ejey
+firstrun_skip_login=Ehejánte kóva
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/gu-IN/strings.properties
@@ -0,0 +1,200 @@
+newtab_page_title=નવી ટૅબ
+
+header_top_sites=ટોચની સાઇટ્સ
+header_highlights=હાઇલાઇટ્સ
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} દ્વારા ભલામણ
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr={title} માટે સંદર્ભ મેનૂ ખોલો
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=વિભાગ સંદર્ભ મેનૂ ખોલો
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=જોવામા આવેલ:
+type_label_bookmarked=બુકમાર્ક્સ
+type_label_recommended=વલણ
+type_label_pocket=પોકેટ પર સાચવ્યું
+type_label_downloaded=ડાઉનલોડ કરેલું
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=બુકમાર્ક
+menu_action_remove_bookmark=બુકમાર્ક કાઢો
+menu_action_open_new_window=નવી વિન્ડોમાં ખોલો
+menu_action_open_private_window=ખાનગી વિન્ડોમાં ખોલો
+menu_action_dismiss=રદ કરો
+menu_action_delete=ઇતિહાસમાંથી દૂર કરો
+menu_action_pin=પિન
+menu_action_unpin=અનપિન
+confirm_history_delete_p1=શું તમે ખરેખર તમારા ઇતિહાસમાંથી આ પૃષ્ઠનાં દરેક ઘટકને કાઢી નાખવા માંગો છો?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=આ ક્રિયા પૂર્વવત્ કરી શકાતી નથી.
+menu_action_save_to_pocket=પોકેટમાં સાચવો
+menu_action_delete_pocket=પોકેટમાંથી કાઢી નાંખો
+menu_action_archive_pocket=પોકેટમાં આર્કાઇવ
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=ફાઇન્ડર માં બતાવો
+menu_action_show_file_windows=સમાવેલ ફોલ્ડર ખોલો
+menu_action_show_file_linux=સમાવેલ ફોલ્ડર ખોલો
+menu_action_show_file_default=ફાઇલ બતાવો
+menu_action_open_file=ફાઇલ ખોલો
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=ડાઉનલોડ કડીની નકલ કરો
+menu_action_go_to_download_page=ડાઉનલોડ પૃષ્ઠ પર જાઓ
+menu_action_remove_download=ઇતિહાસમાંથી દૂર કરો
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=શોધો
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} શોધ કરો
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=વેબ પર શોધો
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=વેબ પરની સૌથી રસપ્રદ વાર્તાઓ, તમે જે વાંચો છો તેના આધારે પસંદ કરેલ છે. Pocket થી, હવે Mozilla નો ભાગ.
+section_disclaimer_topstories_linktext=તે કેવી રીતે કાર્ય કરે છે તે જાણો.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=ઠીક છે, સમજાઇ ગયું
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox મુખ્ય સામગ્રી
+prefs_home_description=તમારી Firefox મુખ્ય સ્ક્રીન પર કઈ સામગ્રી તમે ઇચ્છો તે પસંદ કરો.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} પંક્તિ;{num} પંક્તિઓ
+prefs_search_header=વેબ શોધ
+prefs_topsites_description=તમે સૌથી વધુ મુલાકાત લો છો તે સાઇટ્સ
+prefs_topstories_description2=તમારા માટે વ્યક્તિગત કરેલ વેબ પરથી, વિખ્યાત સામગ્રી
+prefs_topstories_options_sponsored_label=પ્રાયોજિત વાર્તાઓ
+prefs_topstories_sponsored_learn_more=વધુ શીખો
+prefs_highlights_description=સાઇટ્સની પસંદગી કે જે તમે સાચવી અથવા મુલાકાત લીધી છે
+prefs_highlights_options_visited_label=મુલાકાત લીધેલા પૃષ્ઠો
+prefs_highlights_options_download_label=સૌથી તાજેતરની ડાઉનલોડ
+prefs_highlights_options_pocket_label=પોકેટ પર સાચવેલ પૃષ્ઠો
+prefs_snippets_description=Mozilla અને Firefox તરફથી અપડેટ્સ
+settings_pane_button_label=તમારા નવા ટૅબ પૃષ્ઠને કસ્ટમાઇઝ કરો
+settings_pane_topsites_header=ટોચની સાઇટ્સ
+settings_pane_highlights_header=વીતી ગયેલું
+settings_pane_highlights_options_bookmarks=બુકમાર્ક્સ
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=જાણકારી આપનારા ઉતારા ક કાપલીઓ
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=ફેરફાર કરો
+edit_topsites_edit_button=આ સાઇટને સંપાદિત કરો
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=નવી ટોચની સાઇટ
+topsites_form_edit_header=ટોચની સાઇટ સંપાદિત કરો
+topsites_form_title_label=શીર્ષક
+topsites_form_title_placeholder=શીર્ષક દાખલ કરો
+topsites_form_url_label=URL
+topsites_form_image_url_label=વૈવિધ્યપૂર્ણ છબી URL
+topsites_form_url_placeholder=URL ટાઇપ કરો અથવા પેસ્ટ કરો
+topsites_form_use_image_link=વૈવિધ્યપૂર્ણ છબીનો ઉપયોગ કરો…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=પૂર્વદર્શન
+topsites_form_add_button=ઉમેરો
+topsites_form_save_button=સાચવો
+topsites_form_cancel_button=રદ કરો
+topsites_form_url_validation=માન્ય URL આવશ્યક છે
+topsites_form_image_validation=છબી લોડ થવામાં નિષ્ફળ. એક અલગ URL અજમાવી જુઓ.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=લોકપ્રિય વિષયો:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=વધુ વાર્તાઓ જુઓ
+
+highlights_empty_state=બ્રાઉઝ કરવું પ્રારંભ કરો અને અમે અહીં કેટલાક સરસ લેખો, વિડિઓઝ અને અન્ય પૃષ્ઠો દર્શાવીશું જે તમે તાજેતરમાં મુલાકાત લીધાં છે અથવા બુકમાર્ક કર્યા છે.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=અન્ય બ્રાઉઝરથી બુકમાર્ક્સ, ઇતિહાસ અને પાસવર્ડ્સ સાથે ફાયરફોક્સ અજમાવો.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=ના અભાર
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=હવે આયાત કરો
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=ઊફ્ફ, આ સામગ્રીને લોડ કરવામાં કંઈક ખોટું થયું.
+error_fallback_default_refresh_suggestion=ફરી પ્રયાસ કરવા માટે પૃષ્ઠને તાજું કરો.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=વિભાગ દૂર કરો
+section_menu_action_collapse_section=વિભાગ સંકુચિત કરો
+section_menu_action_expand_section=વિભાગ વિસ્તૃત કરો
+section_menu_action_manage_section=વિભાગ સંચાલિત કરો
+section_menu_action_manage_webext=એક્સ્ટેંશનનો વહીવટ કરો
+section_menu_action_add_topsite=ટોચની સાઇટ ઉમેરો
+section_menu_action_move_up=ઉપર કરો
+section_menu_action_move_down=નીચે કરો
+section_menu_action_privacy_notice=ખાનગી સૂચના
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=તમારી સાથે Firefox લો
+firstrun_content=તમારા બધા ઉપકરણો પર તમારા બુકમાર્ક્સ, ઇતિહાસ, પાસવર્ડ્સ અને અન્ય સેટિંગ્સ મેળવો.
+firstrun_learn_more_link=Fireofox ખાતા વિશે વધુ જાણો
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=તમારા ઇમેઇલ દાખલ કરો
+firstrun_form_sub_header=Firefox સમન્વયન ચાલુ રાખવા માટે.
+
+firstrun_email_input_placeholder=ઇમેઇલ
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=આગળ વધીને, તમે {terms} અને {privacy} સાથે સંમત થાઓ છો.
+firstrun_terms_of_service=સેવાની શરતો
+firstrun_privacy_notice=ખાનગી સૂચના
+
+firstrun_continue_to_login=ચાલુ રાખો
+firstrun_skip_login=આ પગલું છોડી દો
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/he/strings.properties
@@ -0,0 +1,232 @@
+newtab_page_title=לשונית חדשה
+default_label_loading=בטעינה…
+
+header_top_sites=אתרים מובילים
+header_stories=סיפורים מובילים
+header_highlights=מומלצים
+header_visit_again=ביקור חוזר
+header_bookmarks=סימניות אחרונות
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=מומלץ על ידי {provider}
+# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
+# meant to inform that section contains no information because
+# the user hasn't added any bookmarks.
+header_bookmarks_placeholder=אין לך סימניות עדיין.
+# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
+# corresponding content (stories) provider
+header_stories_from=מאת
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=פתיחת תפריט ההקשר עבור {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=פתיחת תפריט ההקשר של המדור
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=ביקורים קודמים
+type_label_bookmarked=שמור כסימניה
+type_label_synced=סונכרן מהתקן אחר
+type_label_recommended=פופולרי
+type_label_pocket=נשמר ל־Pocket
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=פתיחה
+type_label_topic=נושא
+type_label_now=עכשיו
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=הוספת סימניה
+menu_action_remove_bookmark=הסרת סימניה
+menu_action_copy_address=העתקת כתובת
+menu_action_email_link=שליחת קישור בדוא״ל…
+menu_action_open_new_window=פתיחה בחלון חדש
+menu_action_open_private_window=פתיחה בלשונית פרטית חדשה
+menu_action_dismiss=הסרה
+menu_action_delete=מחיקה מההיסטוריה
+menu_action_pin=הצמדה
+menu_action_unpin=ביטול הצמדה
+confirm_history_delete_p1=למחוק כל עותק של העמוד הזה מההיסטוריה שלך?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=לא ניתן לבטל פעולה זו.
+menu_action_save_to_pocket=שמירה ל־Pocket
+menu_action_delete_pocket=מחיקה מ־Pocket
+menu_action_archive_pocket=העברה לארכיון ב־Pocket
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with=חיפוש אחר {search_term} עם:
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=חיפוש
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=חיפוש ב־{search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=חיפוש ברשת
+search_settings=שינוי הגדרות חיפוש
+
+# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the
+# (?) icon that would show a section's description with optional feedback link.
+section_info_option=מידע
+section_info_send_feedback=שליחת משוב
+section_info_privacy_notice=הצהרת פרטיות
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=הסיפורים המעניינים ביותר באינטרנט, על בסיס מה שמעניין אותך. בעזרת Pocket, כיום חלק מ־Mozilla.
+section_disclaimer_topstories_linktext=מידע על איך זה עובד.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=בסדר, הבנתי
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=ברוכים הבאים לדף הלשונית החדשה
+welcome_body=Firefox ישתמש באזור זה כדי להציג את הסימניות הרלוונטיות ביותר, מאמרים, סרטוני וידאו ודפים שביקרת בהם לאחרונה, כך שניתן יהיה לגשת אליהם שוב בקלות.
+welcome_label=תחומי העניין שלך מזוהים
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=פחות מדקה
+time_label_minute={number} דקות
+time_label_hour={number} שעות
+time_label_day={number} ימים
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox Home Content
+prefs_home_description=בחירת תוכן שיוצג במסך הבית של Firefox.
+prefs_restore_defaults_button=שחזור ברירות מחדל
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option=שורה אחת;{num} שורות
+prefs_search_header=חיפוש ברשת
+prefs_topsites_description=האתרים בהם ביקרת הכי הרבה
+prefs_topstories_description=תוכן באיכות גבוהה שעלול להתפספס
+# LOCALIZATION NOTE (prefs_topstories_show_sponsored_label): {provider} is
+# replaced by the name of the content provider for this section, e.g., "Pocket"
+prefs_topstories_show_sponsored_label=סיפורים ממומנים של {provider}
+prefs_topstories_sponsored_learn_more=מידע נוסף
+prefs_highlights_description=מבחר של אתרים ששמרת או ביקרת בהם
+prefs_snippets_description=עדכונים מ־Mozilla ו־Firefox
+settings_pane_button_label=התאמה אישית של דף הלשונית החדשה שלך
+settings_pane_header=העדפות לשונית חדשה
+settings_pane_body2=בחירה של מה שיופיע בעמוד הזה.
+settings_pane_search_header=חיפוש
+settings_pane_search_body=חיפוש באינטרנט ישירות מהלשונית החדשה שלך.
+settings_pane_topsites_header=אתרים מובילים
+settings_pane_topsites_body=גישה לאתרים בהם ביקרת הכי הרבה.
+settings_pane_topsites_options_showmore=הצגת שתי שורות
+settings_pane_bookmarks_header=סימניות אחרונות
+settings_pane_bookmarks_body=הסימניות החדשות שיצרת במיקום נוח ואחיד.
+settings_pane_visit_again_header=ביקור חוזר
+settings_pane_visit_again_body=Firefox תציג לך חלקים מהיסטוריית הגלישה שלך שאולי יעניין אותך להיזכר בהם או לחזור אליהם.
+settings_pane_highlights_header=מומלצים
+settings_pane_highlights_body2=מציאת הדרך חזרה לדברים שמעניינים אותך בהתאם לפריטים בהם ביקרת לאחרונה או הוספת לסימניות.
+settings_pane_highlights_options_bookmarks=סימניות
+settings_pane_highlights_options_visited=אתרים בהם ביקרת
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=פתקיות
+settings_pane_snippets_body=ניתן לקרוא עדכונים קטנים ומתוקים מ־Mozilla לגבי Firefox, תרבות האינטרנט ומם אקראי מדי פעם בפעם.
+settings_pane_done_button=סיום
+settings_pane_topstories_options_sponsored=הצגת סיפורים ממומנים
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=עריכה
+edit_topsites_button_label=התאמת אגף האתרים המובילים שלך
+edit_topsites_showmore_button=להציג יותר
+edit_topsites_showless_button=להציג פחות
+edit_topsites_done_button=סיום
+edit_topsites_pin_button=נעיצת אתר זה
+edit_topsites_unpin_button=ביטול הצמדת אתר זה
+edit_topsites_edit_button=עריכת אתר זה
+edit_topsites_dismiss_button=הסרת אתר זה
+edit_topsites_add_button=הוספה
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=אתר מוביל חדש
+topsites_form_edit_header=עריכת אתר מוביל
+topsites_form_title_label=כותרת
+topsites_form_title_placeholder=נא להזין כותרת
+topsites_form_url_label=כתובת
+topsites_form_image_url_label=כתובת תמונה מותאמת אישית
+topsites_form_url_placeholder=נא להקליד או להזין כתובת
+topsites_form_use_image_link=שימוש בתמונה מותאמת אישית…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=תצוגה מקדימה
+topsites_form_add_button=הוספה
+topsites_form_save_button=שמירה
+topsites_form_cancel_button=ביטול
+topsites_form_url_validation=נדרשת כתובת תקינה
+topsites_form_image_validation=טעינת התמונה נכשלה. נא לנסות כתובת שונה.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=נושאים פופולריים:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=צפייה בחדשות נוספות
+# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
+# to Pocket as part of the feedback form.
+pocket_feedback_header=המיטב מרחבי האינטרנט, נאסף על ידי 25 מיליון אנשים.
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane and
+# below (pocket_feedback_header) to provide more information about Pocket.
+pocket_description=ניתן להחשף לתוכן באיכות גבוהה שיתכן שלא היית רואה, בעזרת Pocket, שכיום מהווה חלק מ־Mozilla.
+
+highlights_empty_state=ניתן להתחיל בגלישה ואנו נציג בפניך מספר כתבות, סרטונים ועמודים שונים מעולים בהם ביקרת לאחרונה או שהוספת לסימניות.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=התעדכנת בכל הסיפורים. כדאי לנסות שוב מאוחר יותר כדי לקבל עוד סיפורים מובילים מאת {provider}. לא רוצה לחכות? ניתן לבחור נושא נפוץ כדי למצוא עוד סיפורים נפלאים מרחבי הרשת.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=ניתן להתנסות ב־Firefox עם הסימניות, ההיסטוריה והססמאות מדפדפן אחר.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=לא תודה
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=ייבוא כעת
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=אופס, משהו השתבש בעת טעינת התוכן הזה.
+error_fallback_default_refresh_suggestion=נא לרענן את הדף כדי לנסות שוב.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=הסרת מדור
+section_menu_action_collapse_section=צמצום מדור
+section_menu_action_expand_section=הרחבת מדור
+section_menu_action_manage_section=ניהול מדור
+section_menu_action_add_topsite=הוספת אתר מוביל
+section_menu_action_move_up=העברה למעלה
+section_menu_action_move_down=העברה למטה
+section_menu_action_privacy_notice=הצהרת פרטיות
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/hi-IN/strings.properties
@@ -0,0 +1,195 @@
+newtab_page_title=नया टैब
+
+header_top_sites=सर्वोच्च साइटें
+header_highlights=झलकियाँ
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} द्वारा अनुशंसित
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr={title} के लिए कॉन्टेक्स्ट मेनू खोलें
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=अनुभाग प्रसंग मेनू खोलें
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=देखी गई
+type_label_bookmarked=पुस्तचिह्न लगाया हुआ
+type_label_recommended=लोकप्रिय
+type_label_pocket=Pocket में सहेजा
+type_label_downloaded=डाउनलोड की गई
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=पुस्तचिह्न
+menu_action_remove_bookmark=पुस्तचिह्न हटाएँ
+menu_action_open_new_window=एक नई विंडो में खोलें
+menu_action_open_private_window=एक नई निजी विंडो में खोलें
+menu_action_dismiss=निरस्त करें
+menu_action_delete=इतिहास से मिटाएँ
+menu_action_pin=पिन करें
+menu_action_unpin=पिन हटाएँ
+confirm_history_delete_p1=क्या वाकई आप इस पृष्ठ का हर उदाहरण के अपने इतिहास से हटाना चाहते हैं?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=इस क्रिया को पहले जैसा नहीं किया जा सकता है.
+menu_action_save_to_pocket=Pocket में सहेजें
+menu_action_delete_pocket=पॉकेट से हटाएं
+menu_action_archive_pocket=पॉकेट में पुरालेख
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_windows=संग्राहक फोल्डर खोलें
+menu_action_show_file_linux=संग्राहक फोल्डर खोलें
+menu_action_show_file_default=फ़ाइल दिखाएं
+menu_action_open_file=फ़ाइल खोलें
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=डाउनलोड लिंक कॉपी करें
+menu_action_go_to_download_page=डाउनलोड पृष्ठ पर जाएं
+menu_action_remove_download=इतिहास से हटाएँ
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=खोज
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} खोज
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=वेब पर खोजें
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=वेब पर सबसे दिलचस्प कहानियाँ, आपके पठन के आधार पर चयनित. Pocket के द्वारा, जो अब है Mozilla का हिस्सा.
+section_disclaimer_topstories_linktext=जाने यह कैसे काम करता है.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=ठीक है, समझ गए
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox होम सामग्री
+prefs_home_description=चुनें जो सामग्री आप अपने Firefox होम स्क्रीन पर चाहते हैं ।
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} row;{num} rows
+prefs_search_header=वेब खोज
+prefs_topsites_description=साइटों आप सबसे अधिक यात्रा
+prefs_topstories_options_sponsored_label=प्रायोजित कहानियां
+prefs_topstories_sponsored_learn_more=अधिक जानें
+prefs_highlights_description=आपके द्वारा सहेजी गई या विज़िट की गई साइटों का चयन
+prefs_highlights_options_visited_label=देखे गए पृष्ठ
+prefs_snippets_description=Mozilla और Firefox से अद्यतन
+settings_pane_button_label=अपने नए टैब पृष्ठ को अनुकूलित करें
+settings_pane_topsites_header=सर्वोच्च साइटें
+settings_pane_highlights_header=झलकियाँ
+settings_pane_highlights_options_bookmarks=पुस्तचिह्न
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=अंश
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=संपादित करें
+edit_topsites_edit_button=इस साइट को संपादित करें
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=नई शीर्ष साइट
+topsites_form_edit_header=शीर्ष साइट संपादित करें
+topsites_form_title_label=शीर्षक
+topsites_form_title_placeholder=एक शीर्षक दर्ज करें
+topsites_form_url_label=URL
+topsites_form_image_url_label=कस्टम छवि URL
+topsites_form_url_placeholder=एक URL टाइप करें अथवा पेस्ट करें
+topsites_form_use_image_link=कस्टम छवि का उपयोग करें…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=पूर्वावलोकन
+topsites_form_add_button=जोड़ें
+topsites_form_save_button=सहेजें
+topsites_form_cancel_button=रद्द करें
+topsites_form_url_validation=मान्य URL आवश्यक
+topsites_form_image_validation=छवि लोड करने में विफल । किसी भिंन URL का प्रयास करें ।
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=लोकप्रिय विषय:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=और कहानियाँ देखें
+
+highlights_empty_state=ब्राउज़िंग प्रारंभ करें, और हम कुछ प्रमुख आलेख, विडियो, तथा अन्य पृष्ठों को प्रदर्शित करेंगे जिन्हें आपने हाल ही में देखा या पुस्तचिन्हित किया है.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=आप अंत तक आ गए हैं. {provider} से और शीर्ष घटनाओं के लिए कुछ समय में पुनः आइए. इंतज़ार नहीं कर सकते? वेब से और प्रमुख घटनाएं ढूंढने के लिए एक लोकप्रिय विषय चुनें.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Firefox को किसी अन्य ब्राउज़र के पुस्तचिह्नों, इतिहास और पासवर्डों के साथ आज़माएं.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=नहीं शुक्रिया
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=अब आयात करें
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=उफ़, कुछ गलत इस सामग्री लोड हो गया ।
+error_fallback_default_refresh_suggestion=पुन: प्रयास करने के लिए पृष्ठ ताज़ा करें ।
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=अनुभाग निकालें
+section_menu_action_collapse_section=अनुभाग संक्षिप्त करें
+section_menu_action_expand_section=अनुभाग विस्तृत करें
+section_menu_action_manage_section=अनुभाग प्रबंधित करें
+section_menu_action_add_topsite=शीर्ष साइट जोड़ें
+section_menu_action_move_up=ऊपर जाएँ
+section_menu_action_move_down=नीचे जाएँ
+section_menu_action_privacy_notice=गोपनीयता नीति
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_content=अपने सभी उपकरणों पर अपना पुस्तचिह्न, इतिहास, कूटशब्द और अन्य सेटिंग प्राप्त करें.
+firstrun_learn_more_link=Firefox खातों के बारे में अधिक जानें
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=अपना ईमेल प्रविष्ट करें
+firstrun_form_sub_header=Firefox सिंक के लिए जारी रखें.
+
+firstrun_email_input_placeholder=ईमेल
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=आगे बढ़ने से, आप {terms} और {privacy} से सहमत हैं|
+firstrun_terms_of_service=सेवा की शर्तें
+firstrun_privacy_notice=गोपनीयता नीति
+
+firstrun_continue_to_login=जारी रखें
+firstrun_skip_login=इस चरण को छोड़ दें
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/hr/strings.properties
@@ -0,0 +1,167 @@
+newtab_page_title=Nova kartica
+default_label_loading=Učitavanje…
+
+header_top_sites=Najbolje stranice
+header_stories=Najbolje priče
+header_highlights=Istaknuto
+header_visit_again=Posjetite ponovno
+header_bookmarks=Nedavne zabilješke
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Preporučeno od {provider}
+# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
+# meant to inform that section contains no information because
+# the user hasn't added any bookmarks.
+header_bookmarks_placeholder=Još nemate niti jednu zabilješku.
+# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
+# corresponding content (stories) provider
+header_stories_from=od
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Posjećeno
+type_label_bookmarked=Zabilježeno
+type_label_synced=Sinkronizirano s drugog uređaja
+type_label_recommended=Popularno
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=Otvori
+type_label_topic=Tema
+type_label_now=Sada
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Zabilježi stranicu
+menu_action_remove_bookmark=Ukloni zabilješku
+menu_action_copy_address=Kopiraj adresu
+menu_action_email_link=Pošalji poveznicu e-poštom…
+menu_action_open_new_window=Otvori u novom prozoru
+menu_action_open_private_window=Otvori u novom privatnom prozoru
+menu_action_dismiss=Odbaci
+menu_action_delete=Obriši iz povijesti
+menu_action_pin=Zakači
+menu_action_unpin=Otkači
+confirm_history_delete_p1=Jeste li sigurni da želite obrisati sve primjere ove stranice iz vaše povijesti?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Ova radnja je nepovratna.
+menu_action_save_to_pocket=Spremi u Pocket
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with=Traži {search_term} s:
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Traži
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} pretraživanje
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Pretraži web
+search_settings=Promijeni postavke pretraživanja
+
+# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the
+# (?) icon that would show a section's description with optional feedback link.
+section_info_option=Info
+section_info_send_feedback=Pošaljite povratnu informaciju
+section_info_privacy_notice=Politika privatnosti
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=Dobro došli u novu karticu
+welcome_body=Firefox će koristiti ovaj prostor kako bi vam pokazao najbitnije zabilješke, članke, video uratke i stranice koje ste nedavno posjetili, tako da se možete lako vratiti na njih.
+welcome_label=Identificiranje istaknutog
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=<1m
+time_label_minute={number}m
+time_label_hour={number}h
+time_label_day={number}d
+
+# LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar.
+settings_pane_button_label=Prilagodite svoju početnu stranicu nove kartice
+settings_pane_header=Postavke nove kartice
+settings_pane_body2=Odaberite što vidite na ovoj stranici.
+settings_pane_search_header=Traži
+settings_pane_search_body=Pretražite Web iz nove kartice.
+settings_pane_topsites_header=Najbolje stranice
+settings_pane_topsites_body=Pristupite stranicama koje najčešće posjećujete.
+settings_pane_topsites_options_showmore=Prikaži dva reda
+settings_pane_bookmarks_header=Nedavne zabilješke
+settings_pane_bookmarks_body=Vaše novo stvorene zabilješke na jednom praktičnom mjestu.
+settings_pane_visit_again_header=Posjetite ponovno
+settings_pane_visit_again_body=Firefox će vam prikazati dijelove vaše povijesti pretraživanja koje možda želite zapamtiti ili posjetiti ponovno.
+settings_pane_highlights_header=Istaknuto
+settings_pane_highlights_body2=Pronađite put natrag do zanimljivih stvari koje ste nedavno posjetili ili zabilježili.
+settings_pane_highlights_options_bookmarks=Zabilješke
+settings_pane_highlights_options_visited=Posjećene stranice
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Isječci
+settings_pane_snippets_body=Pročitajte kratke i slatke obavijesti od Mozille o Firefoxu, internet kulturi i povremenim nasumičnim temama.
+settings_pane_done_button=Gotovo
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Uredi
+edit_topsites_button_label=Prilagodite odjel s najboljim stranicama
+edit_topsites_showmore_button=Prikaži više
+edit_topsites_showless_button=Prikaži manje
+edit_topsites_done_button=Gotovo
+edit_topsites_pin_button=Zakači stranicu
+edit_topsites_unpin_button=Otkači ovu stranicu
+edit_topsites_edit_button=Uredi ovu stranicu
+edit_topsites_dismiss_button=Odbaci stranicu
+edit_topsites_add_button=Dodaj
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nova najbolja stranica
+topsites_form_edit_header=Uredi najbolju stranicu
+topsites_form_title_placeholder=Unesi naslov
+topsites_form_url_placeholder=Utipkajte ili zalijepite URL
+topsites_form_add_button=Dodaj
+topsites_form_save_button=Spremi
+topsites_form_cancel_button=Otkaži
+topsites_form_url_validation=Potrebno je unijeti ispravan URL
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Popularne teme:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Prikaži više priča
+# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
+# to Pocket as part of the feedback form.
+pocket_feedback_header=Najbolje od interneta, birano od preko 25 miliona ljudi.
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane and
+# below (pocket_feedback_header) to provide more information about Pocket.
+pocket_description=Otkrijte visoko kvalitetan sadržaj koji ste možda propustili, uz pomoć Pocketa koji je sada dio Mozille.
+
+highlights_empty_state=Započnite pretraživati i pokazat ćemo vam neke od izvrsnih članaka, videa i drugih web stranica prema vašim nedavno posjećenim stranicama ili zabilješkama.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Provjerite kasnije za više najpopularnijih priča od {provider}. Ne možete čekati? Odaberite popularne teme kako biste pronašli više kvalitetnih priča s cijelog weba.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Probajte Firefox s zabilješkama, povijesti i lozinkama iz drugog pretraživača.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Ne hvala
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Uvezi sada
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/hsb/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Nowy rajtark
+
+header_top_sites=Najhusćišo wopytane sydła
+header_highlights=Wjerški
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Wot {provider} doporučeny
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Kontekstowy meni za {title} wočinić
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Kontekstowy meni wotrězka wočinić
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Wopytany
+type_label_bookmarked=Jako zapołožka składowany
+type_label_recommended=Popularny
+type_label_pocket=Do Pocket składowany
+type_label_downloaded=Sćehnjeny
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Zapołožki składować
+menu_action_remove_bookmark=Zapołožku wotstronić
+menu_action_open_new_window=W nowym woknje wočinić
+menu_action_open_private_window=W nowym priwatnym woknje wočinić
+menu_action_dismiss=Zaćisnyć
+menu_action_delete=Z historije zhašeć
+menu_action_pin=Připjeć
+menu_action_unpin=Wotpjeć
+confirm_history_delete_p1=Chceće woprawdźe kóždu instancu tuteje strony ze swojeje historije zhašeć?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Tuta akcija njeda so cofnyć.
+menu_action_save_to_pocket=Pola Pocket składować
+menu_action_delete_pocket=Z Pocket zhašeć
+menu_action_archive_pocket=W Pocket archiwować
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=W Finder pokazać
+menu_action_show_file_windows=Wobsahowacy rjadowak wočinić
+menu_action_show_file_linux=Wobsahowacy rjadowak wočinić
+menu_action_show_file_default=Dataju pokazać
+menu_action_open_file=Dataju wočinić
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Sćehnjenski wotkaz kopěrować
+menu_action_go_to_download_page=K sćehnjenskej stronje přeńć
+menu_action_remove_download=Z historije wotstronić
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Pytać
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Z {search_engine_name} pytać
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Web přepytać
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Najzajimawše stawizny we webje, wubrane na zakładźe toho, štož sće čitał. Z Pocket, nětko dźěl Mozilla.
+section_disclaimer_topstories_linktext=Zhońće, kak to funguje.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=W porjadku, sym zrozumił
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Wobsah startoweje strony Firefox
+prefs_home_description=Wubjerće, kotry wobsah chceće na swojej startowej wobrazowce Firefox měć.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} linka;{num} lince;{num} linki;{num} linkow
+prefs_search_header=Webpytanje
+prefs_topsites_description=Sydła, kotrež najhusćišo wopytujeće
+prefs_topstories_description2=Wulkotny wobsah z cyłeho weba, wubrany specielnje za was
+prefs_topstories_options_sponsored_label=Sponsorowane stawizny
+prefs_topstories_sponsored_learn_more=Dalše informacije
+prefs_highlights_description=Wuběr websydłow, kotrež sće składował abo wopytał
+prefs_highlights_options_visited_label=Wopytane strony
+prefs_highlights_options_download_label=Najnowše sćehnjenje
+prefs_highlights_options_pocket_label=Strony składowane do Pocket
+prefs_snippets_description=Aktualizacije wot Mozilla a Firefox
+settings_pane_button_label=Stronu wašeho noweho rajtarka přiměrić
+settings_pane_topsites_header=Najhusćišo wopytane sydła
+settings_pane_highlights_header=Wjerški
+settings_pane_highlights_options_bookmarks=Zapołožki
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Šlipki
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Wobdźěłać
+edit_topsites_edit_button=Tute sydło wobdźěłać
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nowe najhusćišo wopytane sydło
+topsites_form_edit_header=Najhusćišo wopytane sydło wobdźěłać
+topsites_form_title_label=Titul
+topsites_form_title_placeholder=Titul zapodać
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL swójskeho wobraza
+topsites_form_url_placeholder=URL zapodać abo zasadźić
+topsites_form_use_image_link=Swójski wobraz wužiwać…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Přehlad
+topsites_form_add_button=Přidać
+topsites_form_save_button=Składować
+topsites_form_cancel_button=Přetorhnyć
+topsites_form_url_validation=Płaćiwy URL trěbny
+topsites_form_image_validation=Wobraz njeda so začitać. Spytajće druhi URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Woblubowane temy:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Dalše zdźělenki sej wobhladać
+
+highlights_empty_state=Započńće přehladować, a pokazamy někotre wulkotne nastawki, wideja a druhe strony, kotrež sće njedawno wopytał abo tu jako zapołožki składował.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=To je nachwilu wšitko. Wróćće so pozdźišo dalšich wulkotnych stawiznow dla wot {provider}. Njemóžeće čakać? Wubjerće woblubowanu temu, zo byšće dalše wulkotne stawizny z weba namakał.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Wupruwujće Firefox ze zapołožkami, historiju a hesłami z druheho wobhladowaka.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Ně, dźakuju so
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Nětko importować
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Hopla, při čitanju tutoho wobsaha je so něšto nimokuliło.
+error_fallback_default_refresh_suggestion=Aktualizujće stronu, zo byšće hišće raz spytał.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Wotrězk wotstronić
+section_menu_action_collapse_section=Wotrězk schować
+section_menu_action_expand_section=Wotrězk pokazać
+section_menu_action_manage_section=Wotrězk rjadować
+section_menu_action_manage_webext=Rozšěrjenje rjadować
+section_menu_action_add_topsite=Woblubowane sydło přidać
+section_menu_action_move_up=Horje
+section_menu_action_move_down=Dele
+section_menu_action_privacy_notice=Zdźělenka priwatnosće
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Wzmiće Firefox sobu
+firstrun_content=Wzmiće swoje zapołožki, historiju, hesła a druhe nastajenja na wšěch wašich gratach sobu.
+firstrun_learn_more_link=Zhońće wjace wo Firefox Accounts
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Zapodajće swoju e-mejlowu adresu,
+firstrun_form_sub_header=zo byšće z Firefox Sync pokročował.
+
+firstrun_email_input_placeholder=E-mejl
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Hdyž pokročujeće, zwoliće do {terms} a {privacy}.
+firstrun_terms_of_service=Wužiwanske wuměnjenja
+firstrun_privacy_notice=Zdźělenka priwatnosće
+
+firstrun_continue_to_login=Pokročować
+firstrun_skip_login=Tutón krok přeskočić
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/hu/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Új lap
+
+header_top_sites=Népszerű oldalak
+header_highlights=Kiemelések
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=A(z) {provider} ajánlásával
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Környezeti menü megnyitása ehhez: {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=A szakasz környezeti menüjének megnyitása
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Látogatott
+type_label_bookmarked=Könyvjelzőzött
+type_label_recommended=Népszerű
+type_label_pocket=Mentve a Pocketbe
+type_label_downloaded=Letöltve
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Könyvjelzőzés
+menu_action_remove_bookmark=Könyvjelző eltávolítása
+menu_action_open_new_window=Megnyitás új ablakban
+menu_action_open_private_window=Megnyitás új privát ablakban
+menu_action_dismiss=Elutasítás
+menu_action_delete=Törlés az előzményekből
+menu_action_pin=Rögzítés
+menu_action_unpin=Rögzítés feloldása
+confirm_history_delete_p1=Biztosan törli ezen oldal minden példányát az előzményekből?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Ez a művelet nem vonható vissza.
+menu_action_save_to_pocket=Mentés a Pocketbe
+menu_action_delete_pocket=Törlés a Pocketből
+menu_action_archive_pocket=Archiválás a Pocketben
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Megjelenítés a Finderben
+menu_action_show_file_windows=Tartalmazó mappa megnyitása
+menu_action_show_file_linux=Tartalmazó mappa megnyitása
+menu_action_show_file_default=Fájl megjelenítése
+menu_action_open_file=Fájl megnyitása
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Letöltési hivatkozás másolása
+menu_action_go_to_download_page=Ugrás a letöltési oldalra
+menu_action_remove_download=Törlés az előzményekből
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Keresés
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} keresés
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Keresés a weben
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=A web legérdekesebb történetei, az alapján kiválasztva, hogy mit olvas. A Pockettől, amely már a Mozilla része.
+section_disclaimer_topstories_linktext=Tudja meg hogyan működik.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Rendben, értem
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox kezdőlap tartalma
+prefs_home_description=Válassza ki milyen tartalmat szeretne a Firefox kezdőlapon.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} sor;{num} sor
+prefs_search_header=Webes keresés
+prefs_topsites_description=A leggyakrabban látogatott oldalak
+prefs_topstories_description2=Nagyszerű tartalom szerte a webről, személyre szabva
+prefs_topstories_options_sponsored_label=Szponzorált történetek
+prefs_topstories_sponsored_learn_more=További tudnivalók
+prefs_highlights_description=Válogatás azon oldalakból, amelyeket elmentett vagy felkeresett
+prefs_highlights_options_visited_label=Látogatott oldalak
+prefs_highlights_options_download_label=Legutóbbi letöltés
+prefs_highlights_options_pocket_label=Pocketbe mentett lapok
+prefs_snippets_description=Hírek a Mozilláról és a Firefoxról
+settings_pane_button_label=Az Új lap oldal személyre szabása
+settings_pane_topsites_header=Népszerű oldalak
+settings_pane_highlights_header=Kiemelések
+settings_pane_highlights_options_bookmarks=Könyvjelzők
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Töredékek
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Szerkesztés
+edit_topsites_edit_button=Webhely szerkesztése
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Új népszerű oldal
+topsites_form_edit_header=Népszerű oldal szerkesztése
+topsites_form_title_label=Cím
+topsites_form_title_placeholder=Cím megadása
+topsites_form_url_label=URL
+topsites_form_image_url_label=Egyéni kép URL
+topsites_form_url_placeholder=Írjon vagy illesszen be egy URL-t
+topsites_form_use_image_link=Egyéni kép használata…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Előnézet
+topsites_form_add_button=Hozzáadás
+topsites_form_save_button=Mentés
+topsites_form_cancel_button=Mégse
+topsites_form_url_validation=Érvényes URL szükséges
+topsites_form_image_validation=A kép betöltése nem sikerült. Próbáljon meg egy másik URL-t.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Népszerű témák:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=További történetek
+
+highlights_empty_state=Kezdjen el böngészni, és itt fognak megjelenni azok a nagyszerű cikkek, videók és más lapok, amelyeket nemrég meglátogatott vagy könyvjelzőzött.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Már felzárkózott. Nézzen vissza később a legújabb {provider} hírekért. Nem tud várni? Válasszon egy népszerű témát, hogy még több sztorit találjon a weben.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Próbálja ki a Firefoxot másik böngészőből származó könyvjelzőkkel, előzményekkel és jelszavakkal.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Köszönöm, nem
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importálás most
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Hoppá, valami hiba történt a tartalom betöltésekor.
+error_fallback_default_refresh_suggestion=Az újrapróbálkozáshoz frissítse az oldalt.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Szakasz eltávolítása
+section_menu_action_collapse_section=Szakasz összecsukása
+section_menu_action_expand_section=Szakasz lenyitása
+section_menu_action_manage_section=Szakasz kezelése
+section_menu_action_manage_webext=Kiterjesztés kezelése
+section_menu_action_add_topsite=Hozzáadás a népszerű oldalakhoz
+section_menu_action_move_up=Mozgatás felfelé
+section_menu_action_move_down=Mozgatás lefelé
+section_menu_action_privacy_notice=Adatvédelmi nyilatkozat
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Vigye magával a Firefoxot
+firstrun_content=Kapja meg a könyvjelzőit, előzményeit, jelszavait és egyéb beállításait az összes eszközén.
+firstrun_learn_more_link=Ismerje meg a Firefox fiókokat
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Adja meg az e-mail címét
+firstrun_form_sub_header=és lépjen tovább a Firefox Synchez.
+
+firstrun_email_input_placeholder=E-mail
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=A folytatással elfogadja a {terms} és az {privacy}.
+firstrun_terms_of_service=Felhasználási feltételeket
+firstrun_privacy_notice=Adatvédelmi nyilatkozatot
+
+firstrun_continue_to_login=Folytatás
+firstrun_skip_login=Lépés kihagyása
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/hy-AM/strings.properties
@@ -0,0 +1,65 @@
+newtab_page_title=Նոր ներդիր
+default_label_loading=Բեռնվում է...
+
+header_top_sites=Լավագույն կայքեր
+header_highlights=Գունանշում
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Այցելած
+type_label_bookmarked=Էջանշված
+type_label_synced=Համաժամեցված այլ սարքից
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=Բացել
+type_label_topic=Թեմա
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Էջանիշ
+menu_action_remove_bookmark=Հեռացնել էջանիշը
+menu_action_copy_address=Պատճենել հասցեն
+menu_action_email_link=Ուղարկել հղումը...
+menu_action_open_new_window=Բացել Նոր Պատուհանով
+menu_action_open_private_window=Բացել Նոր Գաղտնի դիտարկմամբ
+menu_action_dismiss=Բաց թողնել
+menu_action_delete=Ջնջել Պատմությունից
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with=Որոնել {search_term}-ը հետևյալով՝
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name}-ի որոնում
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Որոնել առցանց
+search_settings=Փոխել որոնման կարգավորումները
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=Բարի գալուստ նոր ներդիր
+welcome_body=Firefox-ը կօգտագործի այս բացատը՝ ցուցադրելու ձեզ համար առավել կարևոր էջանիշերը, հոդվածները և ձեր այցելած վերջին էջերը, որպեսզի հեշտությամբ վերադառնաք դրանց:
+welcome_label=Նույնացնում է ձեր գունանշումը
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=<1 ր
+time_label_minute={number} ր
+time_label_hour={number} ժ
+time_label_day={number} օր
+
+# LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar.
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ia/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Nove scheda
+
+header_top_sites=Sitos popular
+header_highlights=In evidentia
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recommendate per {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Aperir le menu contextual pro {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Aperir le menu contextual de section
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visitate
+type_label_bookmarked=Marcapaginas addite
+type_label_recommended=Tendentias
+type_label_pocket=Salvate in Pocket
+type_label_downloaded=Discargate
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Adder marcapaginas
+menu_action_remove_bookmark=Remover le marcapaginas
+menu_action_open_new_window=Aperir in un nove fenestra
+menu_action_open_private_window=Aperir in un nove fenestra private
+menu_action_dismiss=Dimitter
+menu_action_delete=Deler del chronologia
+menu_action_pin=Clavar
+menu_action_unpin=Disclavar
+confirm_history_delete_p1=Desira tu vermente deler cata instantia de iste pagina de tu chronologia?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Iste action es irreversibile.
+menu_action_save_to_pocket=Salvar in Pocket
+menu_action_delete_pocket=Delite ex Pocket
+menu_action_archive_pocket=Archivar in Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Monstrar in Finder
+menu_action_show_file_windows=Aperir le plica que lo contine
+menu_action_show_file_linux=Aperir le plica que lo contine
+menu_action_show_file_default=Monstrar le file
+menu_action_open_file=Aperir le file
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Copiar le ligamine de discargamento
+menu_action_go_to_download_page=Ir al pagina de discargamento
+menu_action_remove_download=Remover ex le chronologia
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Cercar
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Recerca {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Cercar in le Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Le historias plus interessante del web, eligite in base a lo que tu lege. Per Pocket, ora parte de Mozilla.
+section_disclaimer_topstories_linktext=Apprende como illo functiona.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ok, io comprende
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Pagina initial de Firefox
+prefs_home_description=Elige qual contento tu desira i tu pagina initial de Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} riga;{num} rigas
+prefs_search_header=Recerca de web
+prefs_topsites_description=Le sitos que tu visita plus
+prefs_topstories_description2=Grande contento ex tote le web, personalisate pro te
+prefs_topstories_options_sponsored_label=Historias sponsorisate
+prefs_topstories_sponsored_learn_more=Saper plus
+prefs_highlights_description=Un election de files que tu ha salvate o visitate
+prefs_highlights_options_visited_label=Paginas visitate
+prefs_highlights_options_download_label=Discargamentos plus recente
+prefs_highlights_options_pocket_label=Paginas salvate in Pocket
+prefs_snippets_description=Actualisationes per Mozilla e Firefox
+settings_pane_button_label=Personalisar tu pagina de nove scheda
+settings_pane_topsites_header=Sitos popular
+settings_pane_highlights_header=In evidentia
+settings_pane_highlights_options_bookmarks=Marcapaginas
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Breve novas
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Editar
+edit_topsites_edit_button=Editar iste sito
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nove sito popular
+topsites_form_edit_header=Editar le sito popular
+topsites_form_title_label=Titulo
+topsites_form_title_placeholder=Scriber un titulo
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL de imagine personal
+topsites_form_url_placeholder=Scriber o collar un URL
+topsites_form_use_image_link=Uso de imagine personal...
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Vista preliminar
+topsites_form_add_button=Adder
+topsites_form_save_button=Salvar
+topsites_form_cancel_button=Cancellar
+topsites_form_url_validation=Il es necessari un URL valide
+topsites_form_image_validation=Error durante le carga del imagina. Prova un URL differente.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Subjectos popular:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Vider plus historias
+
+highlights_empty_state=Comencia navigar e nos te monstrara alcun del grande articulos, videos e altere paginas que tu ha recentemente visitate o addite marcapaginas hic.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Tu ja es in die con toto. Reveni plus tarde pro plus historias popular de {provider}. Non vole attender? Selectiona un subjecto popular pro trovar plus altere historias interessante del web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Essaya Firefox con le marcapaginas, le chronologia e le contrasignos de un altere navigator.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=No, gratias
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importar ora
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Op, error durante le carga de iste contento.
+error_fallback_default_refresh_suggestion=Refresca le pagina pro retentar.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Remover le section
+section_menu_action_collapse_section=Collaber le section
+section_menu_action_expand_section=Expander le section
+section_menu_action_manage_section=Gerer le section
+section_menu_action_manage_webext=Gerer extension
+section_menu_action_add_topsite=Adder a sito popular
+section_menu_action_move_up=Mover in alto
+section_menu_action_move_down=Mover in basso
+section_menu_action_privacy_notice=Notification de confidentialitate
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Porta Firefox con te
+firstrun_content=Tene tu marcapaginas, chronologia, contrasignos e altere configurationes sur tote tu apparatos.
+firstrun_learn_more_link=Apprende plus re Firefox Accounts
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Insere tu email
+firstrun_form_sub_header=pro continuar con Firefox Sync.
+
+firstrun_email_input_placeholder=Email
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Si tu procede, tu consenti a {terms} e {privacy}.
+firstrun_terms_of_service=Terminos de servicio
+firstrun_privacy_notice=Notification de confidentialitate
+
+firstrun_continue_to_login=Continuar
+firstrun_skip_login=Saltar iste grado
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/id/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Tab Baru
+
+header_top_sites=Situs Teratas
+header_highlights=Sorotan
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Disarankan oleh {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Buka menu konteks untuk {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Buka bagian menu konteks
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Dikunjungi
+type_label_bookmarked=Dimarkahi
+type_label_recommended=Trending
+type_label_pocket=Disimpan di Pocket
+type_label_downloaded=Terunduh
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Markah
+menu_action_remove_bookmark=Hapus Markah
+menu_action_open_new_window=Buka di Jendela Baru
+menu_action_open_private_window=Buka di Jendela Penjelajahan Pribadi Baru
+menu_action_dismiss=Tutup
+menu_action_delete=Hapus dari Riwayat
+menu_action_pin=Semat
+menu_action_unpin=Lepas
+confirm_history_delete_p1=Yakin ingin menghapus setiap bagian dari laman ini dari riwayat Anda?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Tindakan ini tidak bisa diurungkan.
+menu_action_save_to_pocket=Simpan ke Pocket
+menu_action_delete_pocket=Hapus dari Pocket
+menu_action_archive_pocket=Arsip di Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Tampilkan di Finder
+menu_action_show_file_windows=Buka Foldernya
+menu_action_show_file_linux=Buka Foldernya
+menu_action_show_file_default=Tampilkan Berkas
+menu_action_open_file=Buka Berkas
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Salin Tautan Unduhan
+menu_action_go_to_download_page=Buka Laman Unduhan
+menu_action_remove_download=Hapus dari Riwayat
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Cari
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Pencarian {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Cari di Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Cerita paling menarik di web, dipilih berdasarkan apa yang Anda baca. Dari Pocket, yang kini merupakan bagian dari Mozilla.
+section_disclaimer_topstories_linktext=Pelajari cara kerjanya.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Oke, paham
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Konten Beranda Firefox
+prefs_home_description=Pilih konten yang anda ingin untuk ditampilkan dalam Beranda Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} baris;{num} baris
+prefs_search_header=Pencarian Web
+prefs_topsites_description=Situs yang sering Anda kunjungi
+prefs_topstories_description2=Konten bermutu dari seluruh web, khusus untuk Anda
+prefs_topstories_options_sponsored_label=Konten Sponsor
+prefs_topstories_sponsored_learn_more=Pelajari lebih lanjut
+prefs_highlights_description=Sejumlah situs yang Anda simpan atau kunjungi
+prefs_highlights_options_visited_label=Laman yang Dikunjungi
+prefs_highlights_options_download_label=Unduhan Terbaru
+prefs_highlights_options_pocket_label=Laman Disimpan di Pocket
+prefs_snippets_description=Pembaruan dari Mozilla dan Firefox
+settings_pane_button_label=Ubahsuai laman Tab Baru Anda
+settings_pane_topsites_header=Situs Teratas
+settings_pane_highlights_header=Sorotan
+settings_pane_highlights_options_bookmarks=Markah
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Catatan Kecil
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Sunting
+edit_topsites_edit_button=Sunting situs ini
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Situs Pilihan Baru
+topsites_form_edit_header=Ubah Situs Pilihan
+topsites_form_title_label=Judul
+topsites_form_title_placeholder=Masukkan judul
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL Gambar Khusus
+topsites_form_url_placeholder=Ketik atau tempel URL
+topsites_form_use_image_link=Gunakan gambar khusus…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Pratinjau
+topsites_form_add_button=Tambah
+topsites_form_save_button=Simpan
+topsites_form_cancel_button=Batalkan
+topsites_form_url_validation=URL valid diperlukan
+topsites_form_image_validation=Gambar gagal dimuat. Cobalah URL lain.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Topik Populer:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Lihat Cerita Lainnya
+
+highlights_empty_state=Mulai menjelajah, dan kami akan menampilkan beberapa artikel bagus, video, dan halaman lain yang baru saja Anda kunjungi atau termarkah di sini.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Maaf Anda tercegat. Periksa lagi nanti untuk lebih banyak cerita terbaik dari {provider}. Tidak mau menunggu? Pilih topik populer untuk menemukan lebih banyak cerita hebat dari seluruh web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Coba Firefox dengan markah, riwayat, dan sandi dari peramban lain.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Tidak, Terima kasih
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Impor Sekarang
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ups, ada masalah saat memuat konten ini.
+error_fallback_default_refresh_suggestion=Segarkan laman untuk mencoba lagi.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Hapus Bagian
+section_menu_action_collapse_section=Ciutkan Bagian
+section_menu_action_expand_section=Bentangkan Bagian
+section_menu_action_manage_section=Kelola Bagian
+section_menu_action_manage_webext=Kelola Ekstensi
+section_menu_action_add_topsite=Tambah Situs Pilihan
+section_menu_action_move_up=Naikkan
+section_menu_action_move_down=Turunkan
+section_menu_action_privacy_notice=Kebijakan Privasi
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Bawa Firefox bersama Anda
+firstrun_content=Dapatkan markah, riwayat, sandi, dan setelan lainnya di semua peranti Anda.
+firstrun_learn_more_link=Pelajari selengkapnya tentang Firefox Accounts
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Masukkan surel Anda
+firstrun_form_sub_header=Lanjutkan ke Firefox Sync.
+
+firstrun_email_input_placeholder=Surel
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Dengan melanjutkan, Anda menyetujui {terms} dan {privacy}.
+firstrun_terms_of_service=Ketentuan Layanan
+firstrun_privacy_notice=Pernyataan Privasi
+
+firstrun_continue_to_login=Lanjutkan
+firstrun_skip_login=Lewati langkah ini
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/it/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Nuova scheda
+
+header_top_sites=Siti principali
+header_highlights=In evidenza
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Consigliati da {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Apri menu contestuale per {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Apri il menu contestuale per la sezione
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visitato
+type_label_bookmarked=Nei segnalibri
+type_label_recommended=Di tendenza
+type_label_pocket=Salvato in Pocket
+type_label_downloaded=Scaricata
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Aggiungi ai segnalibri
+menu_action_remove_bookmark=Elimina segnalibro
+menu_action_open_new_window=Apri in una nuova finestra
+menu_action_open_private_window=Apri in una nuova finestra anonima
+menu_action_dismiss=Rimuovi
+menu_action_delete=Elimina dalla cronologia
+menu_action_pin=Aggiungi alla bacheca
+menu_action_unpin=Rimuovi dalla bacheca
+confirm_history_delete_p1=Eliminare tutte le occorrenze di questa pagina dalla cronologia?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Questa operazione non può essere annullata.
+menu_action_save_to_pocket=Salva in Pocket
+menu_action_delete_pocket=Elimina da Pocket
+menu_action_archive_pocket=Archivia in Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Mostra nel Finder
+menu_action_show_file_windows=Apri cartella di destinazione
+menu_action_show_file_linux=Apri cartella di destinazione
+menu_action_show_file_default=Mostra file
+menu_action_open_file=Apri file
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Copia indirizzo di origine
+menu_action_go_to_download_page=Vai alla pagina di download
+menu_action_remove_download=Elimina dalla cronologia
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Cerca
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Ricerca {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Cerca sul Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Le storie più interessanti del Web, selezionate in base alle tue letture. Direttamente da Pocket, ora parte del gruppo Mozilla.
+section_disclaimer_topstories_linktext=Scopri come funziona.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ho capito.
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Pagina iniziale di Firefox
+prefs_home_description=Scegli i contenuti da visualizzare nella pagina iniziale di Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} riga;{num} righe
+prefs_search_header=Ricerca sul Web
+prefs_topsites_description=I siti più visitati
+prefs_topstories_description2=Contenuti interessanti da tutto il Web, personalizzati per te.
+prefs_topstories_options_sponsored_label=Articoli sponsorizzati
+prefs_topstories_sponsored_learn_more=Ulteriori informazioni
+prefs_highlights_description=Una selezione di siti che hai salvato o visitato in precedenza
+prefs_highlights_options_visited_label=Pagine visitate
+prefs_highlights_options_download_label=Download più recenti
+prefs_highlights_options_pocket_label=Pagine salvate in Pocket
+prefs_snippets_description=Aggiornamenti da Mozilla e Firefox
+settings_pane_button_label=Personalizza la pagina Nuova scheda
+settings_pane_topsites_header=Siti principali
+settings_pane_highlights_header=In evidenza
+settings_pane_highlights_options_bookmarks=Segnalibri
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Snippet
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Modifica
+edit_topsites_edit_button=Modifica questo sito
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nuovi sito principale
+topsites_form_edit_header=Modifica sito principale
+topsites_form_title_label=Titolo
+topsites_form_title_placeholder=Inserire un titolo
+topsites_form_url_label=URL
+topsites_form_image_url_label=Indirizzo immagine personalizzata
+topsites_form_url_placeholder=Digitare o incollare un URL
+topsites_form_use_image_link=Utilizza un’immagine personalizzata…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Anteprima
+topsites_form_add_button=Aggiungi
+topsites_form_save_button=Salva
+topsites_form_cancel_button=Annulla
+topsites_form_url_validation=È necessario fornire un URL valido
+topsites_form_image_validation=Errore durante il caricamento dell’immagine. Prova con un altro indirizzo.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Argomenti popolari:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Visualizza altre storie
+
+highlights_empty_state=Inizia a navigare e, in questa sezione, verranno visualizzati articoli, video e altre pagine visitate di recente o aggiunte ai segnalibri.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Non c'è altro. Controlla più tardi per altre storie da {provider}. Non vuoi aspettare? Seleziona un argomento tra quelli più popolari per scoprire altre notizie interessanti dal Web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Prova Firefox con i segnalibri, la cronologia e le password di un altro browser.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=No grazie
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importa adesso
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Oops, qualcosa è andato storto durante il tentativo di caricare questo contenuto.
+error_fallback_default_refresh_suggestion=Aggiornare la pagina per riprovare.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Rimuovi sezione
+section_menu_action_collapse_section=Comprimi sezione
+section_menu_action_expand_section=Espandi sezione
+section_menu_action_manage_section=Gestisci sezione
+section_menu_action_manage_webext=Gestisci estensione
+section_menu_action_add_topsite=Aggiungi sito principale
+section_menu_action_move_up=Sposta in alto
+section_menu_action_move_down=Sposta in basso
+section_menu_action_privacy_notice=Informativa sulla privacy
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Porta Firefox con te
+firstrun_content=Ritrova segnalibri, cronologia, password e altre impostazioni su tutti i tuoi dispositivi.
+firstrun_learn_more_link=Scopri di più sull’account Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Inserisci email
+firstrun_form_sub_header=per utilizzare Firefox Sync.
+
+firstrun_email_input_placeholder=Email
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Proseguendo, accetto le {terms} e l’{privacy}.
+firstrun_terms_of_service=condizioni di utilizzo del servizio
+firstrun_privacy_notice=informativa sulla privacy
+
+firstrun_continue_to_login=Continua
+firstrun_skip_login=Ignora questo passaggio
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ja/strings.properties
@@ -0,0 +1,192 @@
+newtab_page_title=新しいタブ
+
+header_top_sites=トップサイト
+header_highlights=ハイライト
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} のおすすめ
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr={title} のコンテキストメニューを開く
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=セクションのコンテキストメニューを開く
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=訪問済み
+type_label_bookmarked=ブックマーク済み
+type_label_recommended=話題の記事
+type_label_pocket=Pocket に保存しました
+type_label_downloaded=ダウンロード済み
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=ブックマーク
+menu_action_remove_bookmark=ブックマークを削除
+menu_action_open_new_window=新しいウィンドウで開く
+menu_action_open_private_window=新しいプライベートウィンドウで開く
+menu_action_dismiss=閉じる
+menu_action_delete=履歴から削除
+menu_action_pin=ピン留め
+menu_action_unpin=ピン留めを外す
+confirm_history_delete_p1=本当にこのページに関して保存されているあらゆる情報を履歴から削除しますか?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=この操作は取り消せません。
+menu_action_save_to_pocket=Pocket へ保存
+menu_action_delete_pocket=Pocket から削除
+menu_action_archive_pocket=Pocket にアーカイブ
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Finder に表示
+menu_action_show_file_windows=保存フォルダーを開く
+menu_action_show_file_linux=保存フォルダーを開く
+menu_action_show_file_default=ファイルを表示
+menu_action_open_file=ファイルを開く
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=ダウンロード元の URL をコピー
+menu_action_go_to_download_page=ダウンロード元のページを開く
+menu_action_remove_download=履歴から削除
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=検索
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} 検索
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=ウェブを検索
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=あなたが読んだページに基づいて選ばれた、ウェブ上で最も興味深い記事。Mozilla の一員となった Pocket がお届けします。
+section_disclaimer_topstories_linktext=詳しくはこちら。
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=了解しました
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox ホームコンテンツ
+prefs_home_description=Firefox のホーム画面に表示するコンテンツを選びましょう。
+prefs_restore_defaults_button=初期設定に戻す
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} 行;{num} 行
+prefs_search_header=ウェブ検索
+prefs_topsites_description=よく訪れるサイト
+prefs_topstories_description2=ウェブ上の様々な場所から集められた、あなたにピッタリの優れたコンテンツ
+prefs_topstories_options_sponsored_label=広告記事
+prefs_topstories_sponsored_learn_more=詳しくはこちら
+prefs_highlights_description=保存したり訪れたりしたサイトうち主なもの
+prefs_highlights_options_visited_label=訪れたページ
+prefs_highlights_options_download_label=最近のダウンロード
+prefs_highlights_options_pocket_label=Pocket に保存されたページ
+prefs_snippets_description=Mozilla と Firefox に関する最新情報
+settings_pane_button_label=新しいタブページをカスタマイズ
+settings_pane_header=新しいタブの設定
+settings_pane_body2=このページに表示する内容を選択してください。
+settings_pane_search_header=検索
+settings_pane_search_body=新しいタブからウェブを検索します。
+settings_pane_topsites_header=トップサイト
+settings_pane_topsites_body=よく訪れるサイトへアクセス。
+settings_pane_topsites_options_showmore=2 行で表示
+settings_pane_highlights_header=ハイライト
+settings_pane_highlights_body2=最近訪れたりブックマークしたりした興味のあるページへ戻る方法を見つけましょう。
+settings_pane_highlights_options_bookmarks=ブックマーク
+settings_pane_highlights_options_visited=訪れたサイト
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=スニペット
+settings_pane_snippets_body=Firefox、インターネット文化、時々無作為にお届けする小ネタなど、簡潔で役立つ Mozilla からの最新情報を読んでください。
+settings_pane_done_button=完了
+settings_pane_topstories_options_sponsored=広告記事を表示
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=編集
+edit_topsites_edit_button=このサイトを編集
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=新着トップサイト
+topsites_form_edit_header=トップサイトを編集
+topsites_form_title_label=タイトル
+topsites_form_title_placeholder=タイトルを入力
+topsites_form_url_label=URL
+topsites_form_image_url_label=カスタム画像 URL
+topsites_form_url_placeholder=URL を入力するか貼り付け
+topsites_form_use_image_link=カスタム画像を使用...
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=プレビュー
+topsites_form_add_button=追加
+topsites_form_save_button=保存
+topsites_form_cancel_button=キャンセル
+topsites_form_url_validation=正しい URL を入力してください
+topsites_form_image_validation=画像を読み込めませんでした。別の URL を試してください。
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=人気のトピック:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=他の記事を見る
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=Mozilla の一員となった Pocket の力を借りて、見逃してしまうかもしれない質の高い情報を見つけましょう。
+
+highlights_empty_state=ブラウジング中にあなたが最近訪れたりブックマークしたりした、優れた記事、動画、その他ページの一部をここに表示します。
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=すべて既読です。また後で戻って {provider} からのおすすめ記事をチェックしてください。もし待ちきれないなら、人気のトピックを選択すれば、他にもウェブ上の優れた記事を見つけられます。
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=他のブラウザーからブックマークや履歴、パスワードを取り込んで Firefox を使ってみましょう。
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=今はしない
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=今すぐインポート
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=このコンテンツの読み込み中に何か問題が発生しました。
+error_fallback_default_refresh_suggestion=ページを再読み込みして再確認してください。
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=セクションを削除
+section_menu_action_collapse_section=セクションを折りたたむ
+section_menu_action_expand_section=セクションを広げる
+section_menu_action_manage_section=セクションを管理
+section_menu_action_add_topsite=トップサイトを追加
+section_menu_action_move_up=上へ移動
+section_menu_action_move_down=下へ移動
+section_menu_action_privacy_notice=プライバシー通知
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ka/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=ახალი ჩანართი
+
+header_top_sites=რჩეული საიტები
+header_highlights=მნიშვნელოვანი საიტები
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider}-ის შემოთავაზებული
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=კონტექსტური მენიუს გახსნა {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=გვერდის ნაწილების პარამეტრები
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=მონახულებული
+type_label_bookmarked=ჩანიშნული
+type_label_recommended=პოპულარული
+type_label_pocket=შენახულია Pocket-ში
+type_label_downloaded=ჩამოტვირთული
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=ჩანიშვნა
+menu_action_remove_bookmark=სანიშნებიდან ამოშლა
+menu_action_open_new_window=ახალ ფანჯარაში გახსნა
+menu_action_open_private_window=ახალ პირად ფანჯარაში გახსნა
+menu_action_dismiss=დამალვა
+menu_action_delete=ისტორიიდან ამოშლა
+menu_action_pin=მიმაგრება
+menu_action_unpin=მოხსნა
+confirm_history_delete_p1=ნამდვილად გსურთ, ამ გვერდის ყველა ჩანაწერის ისტორიიდან ამოშლა?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=ეს ქმედება შეუქცევადია.
+menu_action_save_to_pocket=Pocket-ში შენახვა
+menu_action_delete_pocket=წაშლა Pocket-იდან
+menu_action_archive_pocket=დაარქივება Pocket-ში
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=ჩვენება Finder-ში
+menu_action_show_file_windows=შემცველი საქაღალდის გახსნა
+menu_action_show_file_linux=შემცველი საქაღალდის გახსნა
+menu_action_show_file_default=ფაილის ჩვენება
+menu_action_open_file=ფაილის გახსნა
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=ჩამოტვირთვის ბმულის დაკოპირება
+menu_action_go_to_download_page=გადასვლა ჩამოტვირთვის გვერდზე
+menu_action_remove_download=ისტორიიდან ამოშლა
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=ძიება
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} საძიებოთი ძიება
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=ინტერნეტში ძიება
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=საუკეთესო და საინტერესო სიახლეები ინტერნეტიდან, შერჩეული თქვენ მიერ მონახულებული გვერდების საფუძველზე. Pocket-იდან, რომელიც უკვე Mozilla-ს ნაწილია.
+section_disclaimer_topstories_linktext=ნახეთ, როგორ მუშაობს.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=კარგი, გასაგებია
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox საწყისი გვერდი
+prefs_home_description=აირჩიეთ, თუ რისი გამოჩენა გსურთ Firefox-ის საწყის გვერდზე.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} რიგად;{num} რიგად
+prefs_search_header=საძიებო ველი
+prefs_topsites_description=ხშირად მონახულებული საიტები
+prefs_topstories_description2=მნიშვნელოვანი ამბები ინტერნეტ-სამყაროდან, შერჩეული თქვენი ინტერესების მიხედვით
+prefs_topstories_options_sponsored_label=დაფინანსებული სტატიები
+prefs_topstories_sponsored_learn_more=იხილეთ ვრცლად
+prefs_highlights_description=თქვენ მიერ შენახული ან ბოლოს მონახულებული საიტები
+prefs_highlights_options_visited_label=მონახულებული გვერდები
+prefs_highlights_options_download_label=ბოლო ჩამოტვირთვები
+prefs_highlights_options_pocket_label=Pocket-ში შენახული გვერდები
+prefs_snippets_description=სიახლეები Mozilla-სა და Firefox-ისგან
+settings_pane_button_label=მოირგეთ ახალი ჩანართის გვერდი
+settings_pane_topsites_header=რჩეული საიტები
+settings_pane_highlights_header=მნიშვნელოვანი საიტები
+settings_pane_highlights_options_bookmarks=სანიშნები
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=ცნობები
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=ჩასწორება
+edit_topsites_edit_button=საიტის ჩასწორება
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=ახალი საიტი რჩეულებში
+topsites_form_edit_header=რჩეული საიტის ჩასწორება
+topsites_form_title_label=დასახელება
+topsites_form_title_placeholder=სათაურის შეყვანა
+topsites_form_url_label=URL ბმული
+topsites_form_image_url_label=სასურველი სურათის URL ბმული
+topsites_form_url_placeholder=აკრიფეთ ან ჩასვით URL ბმული
+topsites_form_use_image_link=სასურველი სურათის გამოყენება…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=შეთვალიერება
+topsites_form_add_button=დამატება
+topsites_form_save_button=შენახვა
+topsites_form_cancel_button=გაუქმება
+topsites_form_url_validation=საჭიროა მართებული URL
+topsites_form_image_validation=სურათი ვერ ჩაიტვირთა. სცადეთ სხვა URL ბმული.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=პოპულარული თემები:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=მეტი სიახლის ნახვა
+
+highlights_empty_state=დაიწყეთ გვერდების დათვალიერება და აქ გამოჩნდება თქვენი რჩეული სტატიები, ვიდეოები და ბოლოს მონახულებული ან ჩანიშნული საიტები.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=უკვე ყველაფერი წაკითხული გაქვთ. {provider}-იდან ახალი რჩეული სტატიების მისაღებად, მოგვიანებით შემოიარეთ. თუ ვერ ითმენთ, აირჩიეთ რომელიმე მოთხოვნადი თემა, ახალი საინტერესო სტატიების მოსაძიებლად.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=გადმოიტანეთ სხვა ბრაუზერებიდან თქვენი სანიშნები, ისტორია და პაროლები Firefox-ში.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=არა, გმადლობთ
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=ახლავე გადმოტანა
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=სამწუხაროდ, შიგთავსის ჩატვირთვისას რაღაც ხარვეზი წარმოიქმნა.
+error_fallback_default_refresh_suggestion=განაახლეთ გვერდი და სცადეთ ხელახლა.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=ამ ნაწილის მოცილება
+section_menu_action_collapse_section=ამ ნაწილის აკეცვა
+section_menu_action_expand_section=ამ ნაწილის გაშლა
+section_menu_action_manage_section=გვერდის ნაწილების მართვა
+section_menu_action_manage_webext=გაფართოების მართვა
+section_menu_action_add_topsite=რჩეული საიტის დამატება
+section_menu_action_move_up=აწევა
+section_menu_action_move_down=ჩამოწევა
+section_menu_action_privacy_notice=პირადი მონაცემების დაცვის განაცხადი
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=თან წაიყოლეთ Firefox
+firstrun_content=მიიღეთ წვდომა თქვენს სანიშნებთან, ისტორიასთან, პაროლებსა და სხვა პარამეტრებთან, ყველა თქვენს მოწყობილობაზე.
+firstrun_learn_more_link=იხილეთ ვრცლად, Firefox ანგარიშების შესახებ
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=შეიყვანეთ თქვენი ელფოსტა
+firstrun_form_sub_header=Firefox Sync-ზე გადასასვლელად.
+
+firstrun_email_input_placeholder=ელფოსტა
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=გაგრძელების შემთხვევაში, თქვენ ეთანხმებით {terms} და {privacy}.
+firstrun_terms_of_service=გამოყენების პირობებსა
+firstrun_privacy_notice=პირადი მონაცემების დაცვის განაცხადს
+
+firstrun_continue_to_login=გაგრძელება
+firstrun_skip_login=გამოტოვება
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/kab/strings.properties
@@ -0,0 +1,200 @@
+newtab_page_title=Iccer amaynut
+
+header_top_sites=Ismal ifazen
+header_highlights=Asebrureq
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Iwelleh-it-id {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Ldi umuɣ asatal i {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Ldi umuɣ n usatal n tgezmi
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Yettwarza
+type_label_bookmarked=Yettwacreḍ
+type_label_recommended=Tiddin
+type_label_pocket=Yettwakles ɣer Pocket
+type_label_downloaded=Yuli-d
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Creḍ asebter-agi
+menu_action_remove_bookmark=Kkes tacreṭ-agi
+menu_action_open_new_window=Ldei deg usfaylu amaynut
+menu_action_open_private_window=Ldi deg usfaylu uslig amaynut
+menu_action_dismiss=Kkes
+menu_action_delete=Kkes seg umazray
+menu_action_pin=Senteḍ
+menu_action_unpin=Serreḥ
+confirm_history_delete_p1=Tebɣiḍ ad tekksed yal tummant n usebter-agi seg umazray-ik?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Tigawt-agi ur tettuɣal ara ar deffir.
+menu_action_save_to_pocket=Sekles ɣer Pocket
+menu_action_delete_pocket=Kkes si Pocket
+menu_action_archive_pocket=Ḥrez di Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Sken deg Finder
+menu_action_show_file_windows=Ldi akaram deg yella ufaylu
+menu_action_show_file_linux=Ldi akaram deg yella ufaylu
+menu_action_show_file_default=Sken afaylu
+menu_action_open_file=Ldi afaylu
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Nɣel tansa n useɣwen n usali
+menu_action_go_to_download_page=Ddu ɣer usebter n usider
+menu_action_remove_download=Kkes seg umazray
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Nadi
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Anadi {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Nadi di Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Tiqṣiḍin ifazen ak deg Web, ttwafernent ilmend n wayen teqqareḍ. Seg Pocket i yuγal akka d aḥric n Mozilla.
+section_disclaimer_topstories_linktext=Issin amek i teddu.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ih, awi-t-id
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Agbur agejdan Firefox
+prefs_home_description=Fren agbur i tebɣiḍ deg ugdil agejdan Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} izirig;{num} izirigen
+prefs_search_header=Anadi Web
+prefs_topsites_description=Ismal i tettwaliḍ aṭas
+prefs_topstories_description2=Agbur meqqren seg umaḍal, yettwag i kečč
+prefs_topstories_options_sponsored_label=Tiqṣidin yettwarefden
+prefs_topstories_sponsored_learn_more=Issin ugar
+prefs_highlights_description=Tafrant n yismal i teskelseḍ neɣ i twalaḍ
+prefs_highlights_options_visited_label=isebtar yettwarzan
+prefs_highlights_options_download_label=Isidar imaynuten
+prefs_highlights_options_pocket_label=Isebtar yettwaḥerzen ar Pocket
+prefs_snippets_description=Ileqman seg Mozilla d Firefox
+settings_pane_button_label=Sagen asebter n yiccer-ik amaynut
+settings_pane_topsites_header=Ismal ifazen
+settings_pane_highlights_header=Asebrureq
+settings_pane_highlights_options_bookmarks=Ticraḍ n isebtar
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Tiwzillin
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Ẓreg
+edit_topsites_edit_button=Ẓreg asmel-agi
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Asmel ifazen amaynut
+topsites_form_edit_header=Ẓreg asmel ifazen
+topsites_form_title_label=Azwel
+topsites_form_title_placeholder=Sekcem azwel
+topsites_form_url_label=URL
+topsites_form_image_url_label=Tugna tudmawant URL
+topsites_form_url_placeholder=Aru neɣ sekcem tansa URL
+topsites_form_use_image_link=Seqdec tugna tudmawant…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Taskant
+topsites_form_add_button=Rnu
+topsites_form_save_button=Sekles
+topsites_form_cancel_button=Sefsex
+topsites_form_url_validation=Tansa URL tameɣtut tettwasra
+topsites_form_image_validation=Tugna ur d-uli ara. Ɛreḍ tansa-nniḍen URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Isental ittwasnen aṭas:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Wali ugar n teqsiḍin
+
+highlights_empty_state=Bdu tuniginn sakin nekkni ad k-n-sken imagraden, tividyutin, akked isebtar nniḍen i γef terziḍ yakan neγ i tceṛḍeḍ dagi.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Ulac wiyaḍ. Uɣal-d ticki s wugar n imagraden seg {provider}. Ur tebɣiḍ ara ad terǧuḍ? Fren asentel seg wid yettwasnen akken ad twaliḍ imagraden yelhan di Web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Σreḍ Firefox s ticṛaḍ n isebtar, amazray akked awalen uffiren sγur ilinigen nniḍen.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Ala, tanemmirt
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Kter tura
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ihuh, yella wayen yeḍran deg usali n ugbur-a.
+error_fallback_default_refresh_suggestion=Sali-d aseter akken ad talseḍ aɛraḍ.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Kkes tigezmi
+section_menu_action_collapse_section=Fneẓ tigezmi
+section_menu_action_expand_section=Snefli tigezmi
+section_menu_action_manage_section=Sefrek tigezmi
+section_menu_action_manage_webext=Sefrek asiɣzef
+section_menu_action_add_topsite=Rnu asmel ifazen
+section_menu_action_move_up=Ali
+section_menu_action_move_down=Ader
+section_menu_action_privacy_notice=Tasertit n tbaḍnit
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Awi Firefox yid-k
+firstrun_content=Awi ticraḍ-ik n yisebtar, amazray-ik, awalen-ik uffiren d yiɣewwaṛen-nniḍen ɣef ibenkan-ik meṛṛa.
+firstrun_learn_more_link=Issin ugar ɣef Firefox Accounts
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Sekcem imayl inek
+firstrun_form_sub_header=akken ad tkemleḍ akked Firefox Sync
+
+firstrun_email_input_placeholder=Imayl
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_terms_of_service=Tiwtilin n useqdec
+firstrun_privacy_notice=Tasertit n tbaḍnit
+
+firstrun_continue_to_login=Kemmel
+firstrun_skip_login=Zgel amecwaṛ-agi
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/kk/strings.properties
@@ -0,0 +1,192 @@
+newtab_page_title=Жаңа бет
+
+header_top_sites=Үздік сайттар
+header_highlights=Ерекше жаңалықтар
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Ұсынушы {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr={title} үшін контекст мәзірін ашу
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Санаттың контекст мәзірін ашу
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Қаралған
+type_label_bookmarked=Бетбелгілерде
+type_label_recommended=Әйгілі
+type_label_pocket=Pocket-ке сақталған
+type_label_downloaded=Жүктеп алынған
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Бетбелгілерге қосу
+menu_action_remove_bookmark=Бетбелгіні өшіру
+menu_action_open_new_window=Жаңа терезеде ашу
+menu_action_open_private_window=Жаңа жекелік терезесінде ашу
+menu_action_dismiss=Тайдыру
+menu_action_delete=Тарихтан өшіру
+menu_action_pin=Бекіту
+menu_action_unpin=Бекітуді алып тастау
+confirm_history_delete_p1=Бұл парақтың барлық кездесулерін шолу тарихыңыздан өшіруді қалайсыз ба?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Бұл әрекетті болдырмау мүмкін болмайды.
+menu_action_save_to_pocket=Pocket ішіне сақтау
+menu_action_delete_pocket=Pocket-тен өшіру
+menu_action_archive_pocket=Pocket-те архивтеу
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Finder ішінен көрсету
+menu_action_show_file_windows=Орналасқан бумасын ашу
+menu_action_show_file_linux=Орналасқан бумасын ашу
+menu_action_show_file_default=Файлды көрсету
+menu_action_open_file=Файлды ашу
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Жүктеу сілтемесін көшіріп алу
+menu_action_go_to_download_page=Жүктеп алу парағына өту
+menu_action_remove_download=Тарихтан өшіру
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Іздеу
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} іздеуі
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Интернетте іздеу
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Сіз оқитын нәрселерге негізделген интернеттегі ең қызықты хикаялар. Mozilla құрамындағы Pocket ұсынады.
+section_disclaimer_topstories_linktext=Бұл қалай жұмыс жасайтынын білу.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Жақсы, түсіндім
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox үй парағы құрамасы
+prefs_home_description=Firefox үй парағында қандай құраманы көргіңіз келетінді таңдаңыз.
+prefs_restore_defaults_button=Бастапқы мәндерін қайтару
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} жол;{num} жол
+prefs_search_header=Интернеттен іздеу
+prefs_topsites_description=Сіз жиі шолатын сайттар
+prefs_topstories_description2=Бүкіл Интернеттен алынған тамаша контент, талғамыңызға сай таңдалған
+prefs_topstories_options_sponsored_label=Демеушілер мақалалары
+prefs_topstories_sponsored_learn_more=Көбірек білу
+prefs_highlights_description=Сіз сақтаған немесе шолған таңдамалы сайттар
+prefs_highlights_options_visited_label=Қаралған беттер
+prefs_highlights_options_download_label=Ең соңғы жүктеме
+prefs_highlights_options_pocket_label=Pocket-ке сақталған беттер
+prefs_snippets_description=Mozilla және Firefox жаңалықтары
+settings_pane_button_label=Жаңа бетті баптаңыз
+settings_pane_header=Жаңа бет баптаулары
+settings_pane_body2=Бұл бетте не көргіңіз келетінді таңдаңыз.
+settings_pane_search_header=Іздеу
+settings_pane_search_body=Жаңа беттен интернеттен іздеңіз.
+settings_pane_topsites_header=Үздік сайттар
+settings_pane_topsites_body=Көбірек қаралатын сайттарға қатынау.
+settings_pane_topsites_options_showmore=Екі жолды көрсету
+settings_pane_highlights_header=Ерекше жаңалықтар
+settings_pane_highlights_body2=Сіз жақында қараған немесе бетбелгілерге қосқан қызықты нәрселерге қайтатын жолды табыңыз.
+settings_pane_highlights_options_bookmarks=Бетбелгілер
+settings_pane_highlights_options_visited=Ашылған сайттар
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Үзінділер
+settings_pane_snippets_body=Mozilla ұсынған Firefox және интернет мәдениеті туралы қысқа жаңалықтарды, және кездейсоқ мемдерді оқыңыз.
+settings_pane_done_button=Дайын
+settings_pane_topstories_options_sponsored=Демеушілер мақалаларын көрсету
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Түзету
+edit_topsites_edit_button=Бұл сайтты түзету
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Жаңа топ сайты
+topsites_form_edit_header=Топ сайтын түзету
+topsites_form_title_label=Атауы
+topsites_form_title_placeholder=Атауын енгізіңіз
+topsites_form_url_label=URL
+topsites_form_image_url_label=Өз суреттің URL адресі
+topsites_form_url_placeholder=Сілтемені теріңіз немесе кірістіріңіз
+topsites_form_use_image_link=Таңдауыңызша суретті қолдану…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Алдын-ала қарау
+topsites_form_add_button=Қосу
+topsites_form_save_button=Сақтау
+topsites_form_cancel_button=Бас тарту
+topsites_form_url_validation=Жарамды сілтеме керек
+topsites_form_image_validation=Суретті жүктеу қатемен аяқталды. Басқа URL адресін қолданып көріңіз.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Әйгілі тақырыптар:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Көбірек хикаяларды қарау
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=Ол болмаса, сіз жіберіп алатын мүмкіндігі бар жоғары сапалы құраманы Pocket көмегімен табыңыз, ол енді Mozilla-ның бөлігі болып табылады.
+
+highlights_empty_state=Шолуды бастаңыз, сіз жақында шолған немесе бетбелгілерге қосқан тамаша мақалалар, видеолар немесе басқа парақтардың кейбіреулері осында көрсетіледі.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Дайын. {provider} ұсынған көбірек мақалаларды алу үшін кейінірек тексеріңіз. Күте алмайсыз ба? Интернеттен көбірек тамаша мақалаларды алу үшін әйгілі теманы таңдаңыз.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Firefox қолданбасын басқа браузер бетбелгілері, тарихы және парольдерімен қолданып көріңіз.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Жоқ, рахмет
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Қазір импорттау
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Қап, бұл құраманы жүктеу кезінде бірнәрсе қате кетті.
+error_fallback_default_refresh_suggestion=Қайталап көру үшін, бетті жаңартыңыз.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Санатты өшіру
+section_menu_action_collapse_section=Санатты бүктеу
+section_menu_action_expand_section=Санатты жазық қылу
+section_menu_action_manage_section=Санатты басқару
+section_menu_action_add_topsite=Үздік сайт қосу
+section_menu_action_move_up=Жоғары жылжыту
+section_menu_action_move_down=Төмен жылжыту
+section_menu_action_privacy_notice=Жекелік ескертуі
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/km/strings.properties
@@ -0,0 +1,166 @@
+newtab_page_title=ផ្ទាំង​ថ្មី
+default_label_loading=កំពុង​ផ្ទុក...
+
+header_top_sites=វិបសាយ​លើ​គេ
+header_stories=រឿងរ៉ាវកំពូល
+header_highlights=រឿងសំខាន់ៗ
+header_visit_again=ទស្សនាម្តងទៀត
+header_bookmarks=ចំណាំថ្មីៗ
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=បានណែនាំដោយ {provider}
+# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
+# meant to inform that section contains no information because
+# the user hasn't added any bookmarks.
+header_bookmarks_placeholder=អ្នកមិនមានចំណាំណាមួយនៅឡើយទេ ។
+# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
+# corresponding content (stories) provider
+header_stories_from=មកពី
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=បាន​ចូល​មើល
+type_label_bookmarked=បាន​ចំណាំ
+type_label_synced=បាន​ធ្វើ​សមកាលកម្ម​ពី​ឧបករណ៍​ផ្សេង​ទៀត
+type_label_recommended=និន្នាការ
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=បើក
+type_label_topic=ប្រធានបទ
+type_label_now=ឥឡូវនេះ
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=ចំណាំ
+menu_action_remove_bookmark=លុប​ចំណាំ​ចេញ
+menu_action_copy_address=ចម្លង​អាសយដ្ឋាន
+menu_action_email_link=តំណ​អ៊ីមែល...
+menu_action_open_new_window=បើក​នៅ​ក្នុង​បង្អួច​ថ្មី
+menu_action_open_private_window=បើក​នៅ​ក្នុង​បង្អួច​ឯកជន​ថ្មី
+menu_action_dismiss=បោះបង់ចោល
+menu_action_delete=លុប​ពី​ប្រវត្តិ
+menu_action_pin=ខ្ទាស់
+menu_action_unpin=ដកខ្ទាស់
+confirm_history_delete_p1=តើអ្នកប្រាកដថាអ្នកចង់លុបគ្រប់វត្ថុនៃទំព័រនេះពីប្រវត្តិរបស់អ្នកឬ?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=សកម្មភាពនេះមិនអាចមិនធ្វើឡើង​វិញបានទេ។
+menu_action_save_to_pocket=រក្សាទុកទៅ Pocket
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with=ស្វែងរក {search_term} ជាមួយ៖
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=ស្វែងរក
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} ស្វែងរក
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=ស្វែងរក​បណ្ដាញ
+search_settings=ផ្លាស់ប្ដូរ​ការ​កំណត់​ស្វែងរក
+
+# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the
+# (?) icon that would show a section's description with optional feedback link.
+section_info_option=ព័ត៌មាន
+section_info_send_feedback=ផ្ញើមតិត្រឡប់
+section_info_privacy_notice=សេចក្តីជូនដំណឹងអំពីភាពឯកជន
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=យល់​ហើយ
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=ស្វាគមន៍​មក​កាន់​ផ្ទាំង​ថ្មី
+welcome_body=Firefox នឹង​ប្រើប្រាស់​កន្លែង​ទំនេរ​នេះ ដើម្បី​បង្ហាញ​ចំណាំ អត្ថបទ វីដេអូ និង​ទំព័រ​ដែល​ទាក់ទង​អ្នក​បំផុត ដែល​អ្នក​បាន​ចូល​មើល​ថ្មីៗ​នេះ ដូច្នេះ​អ្នក​អាច​ត្រឡប់​ទៅ​​កាន់​​វា​​វិញ​បាន​យ៉ាងងាយស្រួល។
+welcome_label=កំពុង​បញ្ជាក់​ការ​រំលេច​របស់​អ្នក
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=<1 នាទី
+time_label_minute={number} នាទី
+time_label_hour={number} ម៉ោង
+time_label_day={number} ថ្ងៃ
+
+# LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar.
+settings_pane_header=ចំណង់ចំណូលចិត្ត ផ្ទាំងថ្មី
+settings_pane_body2=ជ្រើសរើសអ្វីដែលអ្នកឃើញនៅលើទំព័រនេះ។
+settings_pane_search_header=ស្វែងរក
+settings_pane_search_body=ស្វែងរកបណ្តាញពីផ្ទាំងថ្មីរបស់អ្នក។
+settings_pane_topsites_header=សាយកំពូល
+settings_pane_topsites_body=ចូលវេបសាយដែលអ្នកទស្សនាច្រើនបំផុត។
+settings_pane_topsites_options_showmore=បង្ហាញជួរដេកពីរ
+settings_pane_bookmarks_header=ចំណាំថ្មីៗ
+settings_pane_bookmarks_body=ចំណាំថ្មីៗ ដែលបានបង្កើតរបស់អ្នកនៅក្នុងទីតាំងដែលងាយស្រួល។
+settings_pane_visit_again_header=ទស្សនាម្ដងទៀត
+settings_pane_highlights_header=រឿងសំខាន់ៗ
+settings_pane_highlights_options_bookmarks=ចំណាំ
+settings_pane_highlights_options_visited=សាយដែលបានទស្សនា
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=អត្ថបទសង្ខេប
+settings_pane_done_button=ធ្វើរួច
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=កែសម្រួល
+edit_topsites_showmore_button=បង្ហាញច្រើនទៀត
+edit_topsites_showless_button=បង្ហាញតិចជាង​នេះ
+edit_topsites_done_button=ធ្វើរួច
+edit_topsites_pin_button=ខ្ទាស់សាយនេះ
+edit_topsites_unpin_button=ដកខ្ទាស់សាយនេះ
+edit_topsites_edit_button=កែសម្រួលសាយនេះ
+edit_topsites_dismiss_button=ច្រានចោលសាយនេះ
+edit_topsites_add_button=បន្ថែម
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=សាយកំពូលថ្មី
+topsites_form_edit_header=កែសម្រួលសាយកំពូល
+topsites_form_title_placeholder=បញ្ចូលចំណងជើង
+topsites_form_url_placeholder=វាយបញ្ចូល ឬបិទភ្ជាប់ URL
+topsites_form_add_button=បន្ថែម
+topsites_form_save_button=រក្សាទុក
+topsites_form_cancel_button=បោះបង់
+topsites_form_url_validation=ត្រូវការ URL ដែលត្រឹមត្រូវ
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=ប្រធានបទកំពុងពេញនិយម៖
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=មើលរឿងរ៉ាវច្រើនទៀត
+# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
+# to Pocket as part of the feedback form.
+pocket_feedback_header=បណ្តាញល្អបំផុត ដែលបានវាយតម្លៃដោយមនុស្សជាង 25 លាននាក់។
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane and
+# below (pocket_feedback_header) to provide more information about Pocket.
+
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=សាកល្បងប្រើ Firefox ជាមួយចំណាំ ប្រវត្តិ និងពាក្យសម្ងាត់ពីកម្មវិធីរុករកផ្សេងទៀត។
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=ទេ អរគុណ
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=នាំចូលឥឡូវនេះ
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/kn/strings.properties
@@ -0,0 +1,155 @@
+newtab_page_title=ಹೊಸ ಹಾಳೆ
+default_label_loading=ಲೋಡ್ ಆಗುತ್ತಿದೆ…
+
+header_top_sites=ಪ್ರಮುಖ ತಾಣಗಳು
+header_stories=ಪ್ರಮುಖ ಸುದ್ದಿಗಳು
+header_highlights=ಮುಖ್ಯಾಂಶಗಳು
+header_visit_again=ಮತ್ತೆ ಭೇಟಿಕೊಡು
+header_bookmarks=ಇತ್ತೀಚಿಗೆ ಮಾಡಲಾದ ಬುಕ್‌ಮಾರ್ಕುಗಳು
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} ರಿಂದ ಶಿಫಾರಸುಮಾಡುಲಾಗಿದೆ
+# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
+# meant to inform that section contains no information because
+# the user hasn't added any bookmarks.
+header_bookmarks_placeholder=ನಿಮ್ಮ ಹತ್ತಿರ ಇನ್ನೂ ಯಾವುದೇ ಪುಟಗುರುತುಗಳಿಲ್ಲ.
+# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
+# corresponding content (stories) provider
+header_stories_from=ಯಿಂದ
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=ಭೇಟಿ ನೀಡಲಾದ‍
+type_label_bookmarked=ಪುಟಗುರುತು ಮಾಡಲಾದ
+type_label_synced=ಮತ್ತೊಂದು ಸಾಧನದಿಂದ ಸಿಂಕ್ ಮಾಡಲಾಗಿದೆ
+type_label_recommended=ಪ್ರಚಲಿತ
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=ತೆರೆ
+type_label_topic=ವಿಷಯ
+type_label_now=ಈಗ
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=ಪುಟ ಗುರುತು
+menu_action_remove_bookmark=ಪುಟ ಗುರುತು ತೆಗೆ
+menu_action_copy_address=ವಿಳಾಸವನ್ನು ನಕಲಿಸು
+menu_action_email_link=ಇಮೈಲ್ ಕೊಂಡಿ…
+menu_action_open_new_window=ಹೊಸ ಕಿಟಕಿಯಲ್ಲಿ ತೆರೆ
+menu_action_open_private_window=ಹೊಸ ಖಾಸಗಿ ಕಿಟಕಿಯಲ್ಲಿ ತೆರೆ
+menu_action_dismiss=ವಜಾಗೊಳಿಸು‍
+menu_action_delete=ಇತಿಹಾಸದಿಂದ ಅಳಿಸು‍
+menu_action_pin=ಪಿನ್
+menu_action_unpin=ಅನ್‌ಪಿನ್
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=ಈ ಕಾರ್ಯವನ್ನು ರದ್ದುಗೊಳಿಸಲು ಸಾಧ್ಯವಿರುವುದಿಲ್ಲ.
+menu_action_save_to_pocket=ಪಾಕೆಟ್‌ನಲ್ಲಿ ಉಳಿಸಿ‍
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with={search_term} ಅನ್ನು ಇದರಿಂದ ಹುಡುಕಿ:
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=ಹುಡುಕು
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} ನಿಂದ ಹುಡುಕಿ
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=ಅಂತರ್ಜಾಲವನ್ನು ಹುಡುಕಿ
+search_settings=ಹುಡುಕು ಸಿದ್ಧತೆಗಳನ್ನು ಬದಲಾಯಿಸು
+
+# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the
+# (?) icon that would show a section's description with optional feedback link.
+section_info_option=ಮಾಹಿತಿ
+section_info_send_feedback=ಅಭಿಪ್ರಾಯವನ್ನು ಕಳುಹಿಸಿ
+section_info_privacy_notice=ಗೌಪ್ಯತಾ ಸೂಚನೆ
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=ಹೊಸ ಹಾಳೆಗೆ ಸುಸ್ವಾಗತ
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=<1ನಿ
+time_label_minute={number}ನಿ
+time_label_hour={number}ಗ
+time_label_day={number}ದಿ
+
+# LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar.
+settings_pane_button_label=ಹೊಸ ಹಾಳೆಯ ಪುಟವನ್ನು ಅಗತ್ಯಾನುಗುಣಗೊಳಿಸಿ
+settings_pane_header=ಹೊಸ ಹಾಳೆಯ ಆದ್ಯತೆಗಳು
+settings_pane_body2=ನೀವು ಈ ಪುಟದಲ್ಲಿ ಏನು ನೋಡಿತ್ತೀರೆಂದು ಆಯ್ಕೆಮಾಡಿ.
+settings_pane_search_header=ಹುಡುಕು
+settings_pane_search_body=ಹೊಸ ಹಾಳೆಯಿಂದ ಅಂತರ್ಜಾಲವನ್ನು ಹುಡುಕಿ.
+settings_pane_topsites_header=ಪ್ರಮುಖ ತಾಣಗಳು
+settings_pane_topsites_body=ನೀವು ಅತಿ ಹೆಚ್ಚು ನೋಡುವ ಜಾಲತಾಣಗಳಿಗೆ ಪ್ರವೇಶದ್ವಾರ.
+settings_pane_topsites_options_showmore=ಎರಡು ಸಾಲುಗಳನ್ನು ಪ್ರದರ್ಶಿಸು
+settings_pane_bookmarks_header=ಇತ್ತೀಚಿನ ಪುಟಗುರುತುಗಳು
+settings_pane_visit_again_header=ಮತ್ತೆ ಭೇಟಿಕೊಡು
+settings_pane_highlights_header=ಮುಖ್ಯಾಂಶಗಳು
+settings_pane_highlights_options_bookmarks=ಪುಟಗುರುತುಗಳು
+settings_pane_highlights_options_visited=ಭೇಟಿ ನೀಡಿದ ತಾಣಗಳು
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=ಉಲ್ಲೇಖಗಳು
+settings_pane_done_button=ಆಯಿತು
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=‍ತಿದ್ದು
+edit_topsites_showmore_button=‍ಹೆಚ್ಚು ತೋರಿಸು
+edit_topsites_showless_button=ಕೆಲವೊಂದು ತೋರಿಸಿ
+edit_topsites_done_button=ಆಯಿತು
+edit_topsites_pin_button=ಈ ತಾಣವನ್ನು ಪಿನ್ ಮಾಡು
+edit_topsites_unpin_button=ಈ ತಾಣವನ್ನು ಹೊರತೆಗೆ
+edit_topsites_edit_button=ಈ ತಾಣವನ್ನು ಸಂಪಾದಿಸು
+edit_topsites_dismiss_button=ಈ ತಾಣವನ್ನು ತೆಗೆದುಹಾಕು
+edit_topsites_add_button=ಸೇರಿಸು
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=ಹೊಸ ಅಗ್ರ ತಾಣಗಳು
+topsites_form_edit_header=ಅಗ್ರ ತಾಣಗಳನ್ನು ಸಂಪಾದಿಸಿ
+topsites_form_title_placeholder=ಶೀರ್ಷಿಕೆಯನ್ನು ನಮೂದಿಸಿ
+topsites_form_url_placeholder=ಒಂದು URL ಅನ್ನು ಟೈಪಿಸಿ ಅಥವಾ ನಕಲಿಸಿ
+topsites_form_add_button=ಸೇರಿಸು
+topsites_form_save_button=ಉಳಿಸು
+topsites_form_cancel_button=ರದ್ದು ಮಾಡು
+topsites_form_url_validation=ಸರಿಯಾದ URL ಬೇಕಾಗಿದೆ
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=ಜನಪ್ರಿಯವಾದ ವಿಷಯಗಳು:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=ಹೆಚ್ಚು ಕತೆಗಳನ್ನು ನೋಡಿರಿ
+# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
+# to Pocket as part of the feedback form.
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane and
+# below (pocket_feedback_header) to provide more information about Pocket.
+
+highlights_empty_state=ವೀಕ್ಷಣೆ ಮಾಡಲು ಶುರುಮಾಡಿ, ಮತ್ತು ನಾವು ಇತ್ತೀಚೆಗೆ ಭೇಟಿ ನೀಡಿದ ಅಥವಾ ಬುಕ್‌ಮಾರ್ಕ್ ಮಾಡಲಾದ ಕೆಲವು ಶ್ರೇಷ್ಠ ಲೇಖನಗಳು, ವೀಡಿಯೊಗಳು ಮತ್ತು ಇತರ ಪುಟಗಳನ್ನು ನಾವು ತೋರಿಸುತ್ತೇವೆ.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=ಪರವಾಗಿಲ್ಲ
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=ಈಗ ಆಮದು ಮಾಡು
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ko/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=새 탭
+
+header_top_sites=상위 사이트
+header_highlights=하이라이트
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} 추천
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr={title}에 대한 컨텍스트 메뉴 열기
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=섹션 컨텍스트 메뉴 열기
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=방문한 사이트
+type_label_bookmarked=즐겨찾기
+type_label_recommended=트랜드
+type_label_pocket=Pocket에 저장됨
+type_label_downloaded=다운로드됨
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=즐겨찾기
+menu_action_remove_bookmark=즐겨찾기 삭제
+menu_action_open_new_window=새 창에서 열기
+menu_action_open_private_window=새 사생활 보호 창에서 열기
+menu_action_dismiss=닫기
+menu_action_delete=방문 기록에서 삭제
+menu_action_pin=고정
+menu_action_unpin=고정 해제
+confirm_history_delete_p1=정말 이 페이지의 모든 인스턴스를 기록에서 지우겠습니까?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=이 작업은 되돌릴 수 없습니다.
+menu_action_save_to_pocket=Pocket에 저장
+menu_action_delete_pocket=Pocket에서 삭제
+menu_action_archive_pocket=Pocket에 보관
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Finder에서 보기
+menu_action_show_file_windows=저장 폴더 열기
+menu_action_show_file_linux=저장 폴더 열기
+menu_action_show_file_default=파일 보기
+menu_action_open_file=파일 열기
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=다운로드 주소 복사
+menu_action_go_to_download_page=다운로드 페이지로 이동
+menu_action_remove_download=방문 기록에서 삭제
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=검색
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} 검색
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=웹 검색
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Pocket을 통해서 사용자가 읽은 글을 기반으로 가장 재미있는 글을 찾아주는 글들을 읽어보세요. 이제 Mozilla와 함께 합니다.
+section_disclaimer_topstories_linktext=어떻게 작동 하는지 알아봅시다.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=알겠습니다.
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox 홈 콘텐츠
+prefs_home_description=Firefox 홈 화면에 나올 콘텐츠를 선택하세요.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} 행
+prefs_search_header=웹 검색
+prefs_topsites_description=가장 많이 방문한 사이트
+prefs_topstories_description2=여러분에게 맞춰진 웹에서 제공되는 훌륭한 컨텐츠
+prefs_topstories_options_sponsored_label=후원된 스토리
+prefs_topstories_sponsored_learn_more=자세히 보기
+prefs_highlights_description=저장하거나 방문한 사이트 모음
+prefs_highlights_options_visited_label=방문한 페이지
+prefs_highlights_options_download_label=가장 최근 다운로드
+prefs_highlights_options_pocket_label=Pocket에 저장된 페이지
+prefs_snippets_description=Mozilla와 Firefox 소식
+settings_pane_button_label=새 탭 페이지 꾸미기
+settings_pane_topsites_header=상위 사이트
+settings_pane_highlights_header=하이라이트
+settings_pane_highlights_options_bookmarks=즐겨찾기
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=짧은 요약
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=수정
+edit_topsites_edit_button=이 사이트 수정
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=새로운 인기 사이트
+topsites_form_edit_header=인기 사이트 편집
+topsites_form_title_label=제목
+topsites_form_title_placeholder=제목 입력
+topsites_form_url_label=URL
+topsites_form_image_url_label=개인화 이미지 URL
+topsites_form_url_placeholder=URL 입력 또는 붙여 넣기
+topsites_form_use_image_link=개인화 이미지 사용…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=미리보기
+topsites_form_add_button=추가
+topsites_form_save_button=저장
+topsites_form_cancel_button=취소
+topsites_form_url_validation=유효한 URL이 필요합니다
+topsites_form_image_validation=이미지를 읽어오지 못했습니다. 다른 URL을 시도해 주세요.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=인기 주제:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=더 많은 이야기 보기
+
+highlights_empty_state=브라우징을 시작하면 최근 방문하거나 북마크한 좋은 글이나 영상, 페이지를 여기에 보여줍니다.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=다 왔습니다. {provider}에서 제공하는 주요 기사를 다시 확인해 보세요. 기다릴 수가 없나요? 주제를 선택하면 웹에서 볼 수 있는 가장 재미있는 글을 볼 수 있습니다.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=다른 브라우저에 있는 북마크, 기록, 비밀번호를 사용해 Firefox를 이용해 보세요.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=괜찮습니다
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=지금 가져오기
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=이 콘텐츠를 불러오는데 오류가 발생하였습니다.
+error_fallback_default_refresh_suggestion=페이지를 새로고침해서 다시 시도해 주세요.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=섹션 삭제
+section_menu_action_collapse_section=섹션 닫기
+section_menu_action_expand_section=섹션 열기
+section_menu_action_manage_section=섹션 관리
+section_menu_action_manage_webext=부가 기능 관리
+section_menu_action_add_topsite=인기 사이트 추가
+section_menu_action_move_up=위로 이동
+section_menu_action_move_down=아래로 이동
+section_menu_action_privacy_notice=개인 정보 보호 정책
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Firefox와 함께 하세요
+firstrun_content=즐겨찾기와 방문기록, 비밀번호, 다른 설정을 모든 기기에서 사용해 보세요.
+firstrun_learn_more_link=Firefox 계정 자세히 알아보기
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=이메일을 입력
+firstrun_form_sub_header=해서 Firefox Sync 사용
+
+firstrun_email_input_placeholder=이메일
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=진행하면 {terms}과 {privacy}에 동의하게 됩니다.
+firstrun_terms_of_service=이용 약관
+firstrun_privacy_notice=개인 정보 보호 정책
+
+firstrun_continue_to_login=계속
+firstrun_skip_login=단계 건너뛰기
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/lij/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Neuvo Feuggio
+
+header_top_sites=I megio sciti
+header_highlights=In evidensa
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Consegiou da {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Arvi into menû contesto pe {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Arvi into menû contesto pe-a seçion
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Vixitou
+type_label_bookmarked=Azonto a-i segnalibbri
+type_label_recommended=De tentensa
+type_label_pocket=Sarvou in Pocket
+type_label_downloaded=Descaregou
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Azonzi a-i segnalibbri
+menu_action_remove_bookmark=Scancella segnalibbro
+menu_action_open_new_window=Arvi in neuvo barcon
+menu_action_open_private_window=Arvi in neuvo barcon privou
+menu_action_dismiss=Scancella
+menu_action_delete=Scancella da-a stöia
+menu_action_pin=Azonzi a-a bacheca
+menu_action_unpin=Leva da bacheca
+confirm_history_delete_p1=Te seguo de scancelâ tutte e ripetiçioin de sta pagina da stöia?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Sta açion a no se peu anulâ.
+menu_action_save_to_pocket=Sarva in Pocket
+menu_action_delete_pocket=Scancella da Pocket
+menu_action_archive_pocket=Archivia in Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Fanni vedde in Finder
+menu_action_show_file_windows=Arvi cartella
+menu_action_show_file_linux=Arvi cartella
+menu_action_show_file_default=Fanni vedde file
+menu_action_open_file=Arvi file
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Còpia indirisso òrigine
+menu_action_go_to_download_page=Vanni a-a pagina de descaregamento
+menu_action_remove_download=Scancella da-a stöia
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Çerca
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Riçerca {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Çerca inta Ræ
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=E stöie ciù interesanti do Web, seleçionæ in baze a quello che ti lezi. Pigiæ da Pocket, che oua o l'é parte de Mozilla.
+section_disclaimer_topstories_linktext=Descòvri comme fonçionn-a.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Va ben, ò capio
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Pagina iniçiâ de Firefox
+prefs_home_description=Çerni i contegnui che ti veu vedde inta pagina iniçiâ de Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} riga;{num} righe
+prefs_search_header=Çerca into Web
+prefs_topsites_description=I sciti che ti vixiti de ciù
+prefs_topstories_description2=I megio contegnui pigiæ in gio pe-a ræ, personalizæ pe ti
+prefs_topstories_options_sponsored_label=Stöie sponsorizæ
+prefs_topstories_sponsored_learn_more=Atre informaçioin
+prefs_highlights_description='Na seleçion di sciti che t'ê sarvou ò vixitou
+prefs_highlights_options_visited_label=Pagine vixitæ
+prefs_highlights_options_download_label=Urtimi descaregamenti
+prefs_highlights_options_pocket_label=Pagine sarvæ in Pocket
+prefs_snippets_description=Agiornamenti da Mozilla e Firefox
+settings_pane_button_label=Personalizza a teu pagina Neuvo feuggio
+settings_pane_topsites_header=I megio sciti
+settings_pane_highlights_header=In evidensa
+settings_pane_highlights_options_bookmarks=Segnalibbri
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Snippet
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Cangia
+edit_topsites_edit_button=Cangia sto scito
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Neuvo scito prinçipâ
+topsites_form_edit_header=Cangia scito prinçipâ
+topsites_form_title_label=Titolo
+topsites_form_title_placeholder=Scrivi 'n titolo
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL da inmagine personalizâ
+topsites_form_url_placeholder=Scrivi ò incòlla URL
+topsites_form_use_image_link=Adeuvia inagine personalizâ…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Anteprimma
+topsites_form_add_button=Azonzi
+topsites_form_save_button=Sarva
+topsites_form_cancel_button=Anulla
+topsites_form_url_validation=Serve 'na URL bonn-a
+topsites_form_image_validation=Erô into caregamento de l'inmagine. Preuva 'n atra URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Argomenti popolari:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Amia atre stöie
+
+highlights_empty_state=Iniçia a navegâ e, in sta seçion, saian mostræ articoli, video e atre pagine vixitæ de fresco ò azonti a-i segnalibbri.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=No gh'é atro. Contròlla ciù tardi se gh'é atre stöie da {provider}. No t'eu aspetâ? Seleçionn-a 'n argomento tra quelli ciù popolari pe descovrî atre notiçie interesanti da-o Web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Preuva Firefox con i segnalibbri, a stöia e-e paròlle segrete de 'n atro navegatô.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=No graçie
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Inpòrta oua
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ahime mi, gh'é quarche problema into caregamento de sto contegnuo.
+error_fallback_default_refresh_suggestion=Agiorna pagina pe provâ torna.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Scancella seçion
+section_menu_action_collapse_section=Conprimmi seçion
+section_menu_action_expand_section=Espandi seçion
+section_menu_action_manage_section=Gestisci seçion
+section_menu_action_manage_webext=Gestisci estenscioin
+section_menu_action_add_topsite=Azonzi scito prinçipâ
+section_menu_action_move_up=Mescia in sciù
+section_menu_action_move_down=Mescia in zu
+section_menu_action_privacy_notice=Informativa in sciâ privacy
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Pòrta Firefox con ti
+firstrun_content=Repiggia i teu segnalibbri, stöia, poule segrete e atre inpostaçioin in sce tutti i teu dispoxitivi.
+firstrun_learn_more_link=Saccine de ciù in sce l'account Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Scrivi a teu email
+firstrun_form_sub_header=pe continoâ con Firefox Sync.
+
+firstrun_email_input_placeholder=Email
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Se ti væ avanti t'ê d'acòrdio co-i {terms} e l'{privacy}.
+firstrun_terms_of_service=Termini do serviçio
+firstrun_privacy_notice=Informativa in sciâ privacy
+
+firstrun_continue_to_login=Continoa
+firstrun_skip_login=Sata sto passo
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/lo/strings.properties
@@ -0,0 +1,165 @@
+newtab_page_title=ແທັບໃຫມ່
+
+header_top_sites=ເວັບໄຊຕ໌ຍອດນິຍົມ
+header_highlights=ລາຍການເດັ່ນ
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=ແນະນຳໂດຍ {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=ເຂົ້າໄປເບິ່ງມາແລ້ວ
+type_label_bookmarked=ບຸກມາກໄວ້ແລ້ວ
+type_label_recommended=ກຳລັງນິຍົມ
+type_label_pocket=ບັນທຶກລົງໃນ Pocket ແລ້ວ
+type_label_downloaded=ດາວໂຫຼດແລ້ວ
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=ບຸກມາກ
+menu_action_remove_bookmark=ລຶບບຸກມາກອອກ
+menu_action_open_new_window=ເປີດລີ້ງໃນຫນ້າຕ່າງໃຫມ່
+menu_action_open_private_window=ເປີດໃນຫນ້າຕ່າງສ່ວນຕົວໃຫມ່
+menu_action_dismiss=ຍົກເລີກ
+menu_action_delete=ລຶບອອກຈາກປະຫວັດການນຳໃຊ້
+menu_action_pin=ປັກໝຸດ
+menu_action_unpin=ຖອນປັກໝຸດ
+confirm_history_delete_p1=ທ່ານແນ່ໃຈຫຼືບໍ່ວ່າຕ້ອງການລຶບທຸກ instance ຂອງຫນ້ານີ້ອອກຈາກປະຫວັດການໃຊ້ງານຂອງທ່ານ?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+menu_action_save_to_pocket=ບັນທືກໄປທີ່ Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=ສະແດງໃນ Finder
+menu_action_show_file_windows=ເປີດໂຟນເດີທີ່ບັນຈຸ
+menu_action_show_file_linux=ເປີດໂຟນເດີທີ່ບັນຈຸ
+menu_action_show_file_default=ສະແດງໄຟລ໌
+menu_action_open_file=ເປີດໄຟລ໌
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=ສຳເນົາລີ້ງດາວໂຫລດ
+menu_action_go_to_download_page=ໄປທີ່ຫນ້າດາວໂຫລດ
+menu_action_remove_download=ລຶບອອກຈາກປະຫວັດ
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=ຊອກ​ຫາ
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=ຊອກຫາ {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=ຊອກຫາເວັບ
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories_linktext=ສຶກສາວິທີການເຮັດວຽກຂອງມັນ.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=ຕົກລົງ, ເຂົ້າໃຈແລ້ວ
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=ເນື້ອໃນຫນ້າທຳອິດຂອງ Firefox
+prefs_restore_defaults_button=ກູ້ຄືນຄ່າພື້ນຖານ
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_search_header=ຊອກຫາເວັບ
+prefs_topstories_sponsored_learn_more=ສຶກສາເພີ່ມເຕີມ
+prefs_highlights_options_visited_label=ຫນ້າທີ່ເຂົ້າໄປເບິ່ງແລ້ວ
+prefs_highlights_options_pocket_label=ຫນ້າທີ່ບັນທຶກໄວ້ໃນ Pocket
+settings_pane_button_label=ປັບແຕ່ງຫນ້າແທັບໃຫມ່ຂອງທ່ານ
+settings_pane_header=ການຕັ້ງຄ່າແທັບໃຫມ່
+settings_pane_body2=ເລືອກສິ່ງທີ່ທ່ານຕ້ອງການເຫັນໃນຫນ້ານີ້.
+settings_pane_search_header=ຊອກຫາ
+settings_pane_search_body=ຊອກຫາເວັບຈາກແທັບໃຫມ່ຂອງທ່ານ.
+settings_pane_topsites_header=ເວັບໄຊທ໌ຍອດນິຍົມ
+settings_pane_topsites_body=ເຂົ້າເວັບໄຊທ໌ທີ່ທ່ານໄດ້ເຂົ້າໄປຫລາຍທີ່ສຸດ.
+settings_pane_topsites_options_showmore=ສະແດງເປັນສອງແຖວ
+settings_pane_highlights_header=ຈຸດເດັ່ນ
+settings_pane_highlights_options_bookmarks=ບຸກມາກ
+settings_pane_highlights_options_visited=ໄຊທ໌ທີ່ເຂົ້າໄປເບິ່ງແລ້ວ
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=ສ່ວນຍ່ອຍ
+settings_pane_done_button=ສຳເລັດ
+settings_pane_topstories_options_sponsored=ສະແດງບົດເລື່ອງທີ່ໄດ້ຮັບການສະຫນັບສະຫນູນ
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=ແກ້ໄຂ
+edit_topsites_edit_button=ແກ້ໄຂເວັບໄຊທ໌ນີ້
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=ເວັບໄຊທ໌ຍອດນິຍົມໃຫມ່
+topsites_form_edit_header=ແກ້ໄຂເວັບໄຊທ໌ຍອດນິຍົມ
+topsites_form_title_label=ຊື່ເລື່ອງ
+topsites_form_title_placeholder=ປ້ອນຊື່ເລື່ອງ
+topsites_form_url_label=URL
+topsites_form_url_placeholder=ພິມຫລືວາງ URL
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=ສະແດງຕົວຢ່າງ
+topsites_form_add_button=ເພີ່ມ
+topsites_form_save_button=ບັນທຶກ
+topsites_form_cancel_button=ຍົກເລີກ
+topsites_form_url_validation=ຕ້ອງການ URL ທີ່ຖືກຕ້ອງ
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=ຫົວຂໍ້ຍອດນິຍົມ:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=ເບິ່ງບົດເລື່ອງເພີ່ມເຕີມ
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=ຄົ້ນພົບເນື້ອຫາຄຸນນະພາບສູງທີ່ທ່ານອາດຈະພາດໄປ, ດ້ວຍຄວາມຊ່ວຍເຫຼືອຈາກ Pocket, ເຊີ່ງຂະນະນີ້ເປັນສ່ວນໜື່ງຂອງ Mozilla.
+
+highlights_empty_state=ເລີ່ມການທ່ອງເວັບ ແລະ ພວກເຮົາຈະສະແດງເນື້ອຫາ, ວິດີໂອ ແລະ ຫນ້າອື່ນໆບາງສ່ວນທີ່ທ່ານຫາກໍເຂົ້າໄປເບິງມາ ຫລື ຫາກໍໄດ້ບຸກມາກໄວ້ທີ່ນີ້.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=ບໍ່, ຂອບໃຈ
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=ນຳເຂົ້າຕອນນີ້
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_add_topsite=ເພີ່ມເວັບໄຊທ໌ຍອດນິຍົມ
+section_menu_action_move_up=ຍ້າຍຂື້ນ
+section_menu_action_move_down=ຍ້າຍລົງ
+section_menu_action_privacy_notice=ນະໂຍບາຍຄວາມເປັນສ່ວນຕົວ
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/lt/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Nauja kortelė
+
+header_top_sites=Lankomiausios svetainės
+header_highlights=Akcentai
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Rekomendavo „{provider}“
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Atverti kontekstinį {title} meniu
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Atverti skilties kontekstinį meniu
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Lankytasi
+type_label_bookmarked=Iš adresyno
+type_label_recommended=Populiaru
+type_label_pocket=Įrašyta į „Pocket“
+type_label_downloaded=Atsiųsta
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Įrašyti į adresyną
+menu_action_remove_bookmark=Pašalinti iš adresyno
+menu_action_open_new_window=Atverti naujame lange
+menu_action_open_private_window=Atverti naujame privačiajame lange
+menu_action_dismiss=Paslėpti
+menu_action_delete=Pašalinti iš istorijos
+menu_action_pin=Įsegti
+menu_action_unpin=Išsegti
+confirm_history_delete_p1=Ar tikrai norite pašalinti visus šio tinklalapio įrašus iš savo naršymo žurnalo?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Atlikus šį veiksmą, jo atšaukti neįmanoma.
+menu_action_save_to_pocket=Įrašyti į „Pocket“
+menu_action_delete_pocket=Trinti iš „Pocket“
+menu_action_archive_pocket=Archyvuoti per „Pocket“
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Rodyti per „Finder“
+menu_action_show_file_windows=Atverti aplanką
+menu_action_show_file_linux=Atverti aplanką
+menu_action_show_file_default=Rodyti failą
+menu_action_open_file=Atverti failą
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Kopijuoti šaltinio adresą
+menu_action_go_to_download_page=Eiti į atsisiuntimo tinklalapį
+menu_action_remove_download=Pašalinti iš žurnalo
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Ieškoti
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} paieška
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Ieškokite saityne
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Įdomiausi saityno straipsniai, parinkti pagal jūsų skaitymo įpročius. Iš „Pocket“, kuri dabar priklauso „Mozillai“.
+section_disclaimer_topstories_linktext=Sužinokite, kaip tai veikia.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Gerai, supratau
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=„Firefox“ pradžios turinys
+prefs_home_description=Pasirinkite, kokį turinį norite matyti „Firefox“ pradžios ekrane
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} eilutė;{num} eilutės;{num} eilučių
+prefs_search_header=Paieška internete
+prefs_topsites_description=Dažniausiai lankomos svetainės
+prefs_topstories_description2=Puikus turinys iš viso saityno, parinktas specialiai jums
+prefs_topstories_options_sponsored_label=Rėmėjų straipsniai
+prefs_topstories_sponsored_learn_more=Sužinoti daugiau
+prefs_highlights_description=Aplankytų bei išsaugotų svetainių rinkinys
+prefs_highlights_options_visited_label=Aplankyti tinklalapiai
+prefs_highlights_options_download_label=Paskiausias atsisiuntimas
+prefs_highlights_options_pocket_label=Į „Pocket“ įrašyti tinklalapiai
+prefs_snippets_description=Naujienos iš „Mozillos“ ir „Firefox“
+settings_pane_button_label=Tinkinkite savo naujos kortelės puslapį
+settings_pane_topsites_header=Lankomiausios svetainės
+settings_pane_highlights_header=Akcentai
+settings_pane_highlights_options_bookmarks=Adresynas
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Iškarpos
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Keisti
+edit_topsites_edit_button=Redaguoti šią svetainę
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nauja mėgstama svetainė
+topsites_form_edit_header=Redaguoti mėgstamą svetainę
+topsites_form_title_label=Pavadinimas
+topsites_form_title_placeholder=Įveskite pavadinimą
+topsites_form_url_label=URL
+topsites_form_image_url_label=Kitoks paveikslo URL
+topsites_form_url_placeholder=Įveskite arba įklijuokite URL
+topsites_form_use_image_link=Naudoti kitą paveikslą…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Peržiūrėti
+topsites_form_add_button=Pridėti
+topsites_form_save_button=Įrašyti
+topsites_form_cancel_button=Atsisakyti
+topsites_form_url_validation=Reikalingas tinkamas URL
+topsites_form_image_validation=Nepavyko įkelti paveikslo. Pabandykite kitokį URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Populiarios temos:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Rodyti daugiau straipsnių
+
+highlights_empty_state=Pradėkite naršyti, o mes čia pateiksime puikių straipsnių, vaizdo įrašų bei kitų tinklalapių, kuriuose neseniai lankėtės ar įtraukėte į adresyną.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Viską perskaitėte. Užsukite vėliau, norėdami rasti daugiau gerų straipsnių iš „{provider}“. Nekantraujate? Pasirinkite populiarią temą, norėdami rasti daugiau puikių straipsnių saityne.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Išbandykite „Firefox“ su adresynu, žurnalu bei slaptažodžiais iš kitos naršyklės.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Ačiū, ne
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importuoti dabar
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ups, įkeliant šį turinį įvyko klaida.
+error_fallback_default_refresh_suggestion=Pabandykite iš naujo įkelti tinklalapį.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Pašalinti skiltį
+section_menu_action_collapse_section=Suskleisti skiltį
+section_menu_action_expand_section=Išplėsti skiltį
+section_menu_action_manage_section=Tvarkyti skiltį
+section_menu_action_manage_webext=Tvarkyti priedą
+section_menu_action_add_topsite=Pridėti lankomą svetainę
+section_menu_action_move_up=Pakelti
+section_menu_action_move_down=Nuleisti
+section_menu_action_privacy_notice=Privatumo nuostatai
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Pasiimkite „Firefox“ su savimi
+firstrun_content=Turėkite savo adresyną, žurnalą, slaptažodžius ir kitas nuostatas visuose savo įrenginiuose.
+firstrun_learn_more_link=Sužinokite daugiau apie „Firefox“ paskyras
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Įveskite savo el. paštą
+firstrun_form_sub_header=norėdami tęsti su „Firefox Sync“.
+
+firstrun_email_input_placeholder=El. paštas
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Tęsdami sutinkate su {terms} ir {privacy}.
+firstrun_terms_of_service=paslaugos teikimo nuostatais
+firstrun_privacy_notice=privatumo nuostatais
+
+firstrun_continue_to_login=Tęsti
+firstrun_skip_login=Praleisti šį žingsnį
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ltg/strings.properties
@@ -0,0 +1,183 @@
+newtab_page_title=Jauna cilne
+default_label_loading=Īlōdej…
+
+header_top_sites=Popularōkōs lopys
+header_stories=Popularōkī roksti
+header_highlights=Izraudzeitī
+header_visit_again=Apsavērt nu jauna
+header_bookmarks=Naseņ saglobōtōs
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} īsaceitōs
+# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
+# meant to inform that section contains no information because
+# the user hasn't added any bookmarks.
+header_bookmarks_placeholder=Tu vāļ naesi nikū saglobōjs.
+# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
+# corresponding content (stories) provider
+header_stories_from=nu
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Attaiseit konteksta izvielni {title}
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Apsavārtys lopys
+type_label_bookmarked=Saglobōts grōmotzemēs
+type_label_synced=Sinhroniziets nu cytas īreices
+type_label_recommended=Populars
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=Attaiseit
+type_label_topic=Tēma
+type_label_now=Ņiuļa
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Grōmotzeime
+menu_action_remove_bookmark=Izjimt grōmotzeimi
+menu_action_copy_address=Kopēt adresi
+menu_action_email_link=Nūsyuteit saiti…
+menu_action_open_new_window=Attaiseit saiti jaunā lūgā
+menu_action_open_private_window=Attaiseit saiti jaunā privātajā lūgā
+menu_action_dismiss=Paslēpt
+menu_action_delete=Nūteireit nu viestures
+menu_action_pin=Daspraust
+menu_action_unpin=Atbreivōt
+confirm_history_delete_p1=Voi gribi dzēst vysus itōs lopys īrokstus nu viestures?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Itei ir naatgrīzeniska darbeiba.
+menu_action_save_to_pocket=Saglobōt Pocket
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with=Mekleit {search_term} ar:
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Mekleit
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} mekliešona
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Mekleit teiklā
+search_settings=Maineit mekliešonys īstatiejumus
+
+# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the
+# (?) icon that would show a section's description with optional feedback link.
+section_info_option=Informaceja
+section_info_send_feedback=Syutēt atsauksmi
+section_info_privacy_notice=Privatuma pīzeime
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Pošas interesantōkōs ziņas, kas atlasietas saskaņā ar tū, kū tu esi lasiejs. Nu Poket, kas ņiuļa ir Mozilla daļa.
+section_disclaimer_topstories_linktext=Uzzynoj, kai tys strōdoj.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Skaidrs
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=Laipnai lyudzam jaunā cilnē
+welcome_body=Firefox izmontōs itū vītu, kab rōdēt pīmārōtys grōmotzeimes, rokstus, lopys un video, kurys tu naseņ apsavieri, kab tu varātu vīgļi tōs apsavērt nu jauna.
+welcome_label=Tovas izlases identifikaceja
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=<1min.
+time_label_minute={number} min.
+time_label_hour={number} st.
+time_label_day={number} d.
+
+# LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar.
+settings_pane_button_label=Īstateit sovu jaunas cilnes lopu
+settings_pane_header=Jaunas cilnes īstatiejumi
+settings_pane_body2=Izaraugi, kū gribi redzēt itymā lopā.
+settings_pane_search_header=Mekleit
+settings_pane_search_body=Mekleit škārsteiklā nu jaunas cilnes.
+settings_pane_topsites_header=Top lopys
+settings_pane_topsites_body=Sajam pīeju lopom, kuras apskoti vysvaira.
+settings_pane_topsites_options_showmore=Divejōs rindōs
+settings_pane_bookmarks_header=Naseņ saglobōtōs
+settings_pane_bookmarks_body=Tovas jaunōs grōmotzeimes ārtā vītā.
+settings_pane_visit_again_header=Apsavērt nu jauna
+settings_pane_visit_again_body=Firefox tev parōdēs porlyukōšonas viestures daļas, kuras, īspiejams, tu gribiesi apsavērt nu jauna.
+settings_pane_highlights_header=Izraudzeitī
+settings_pane_highlights_body2=Atrūņ īspieji acagrīzt pi interesantom lopom, kuras tu apsavieri voi īlyki grōmotzeimēs.
+settings_pane_highlights_options_bookmarks=Grōmotzeimes
+settings_pane_highlights_options_visited=Apsavārtys lopys
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Pīzeimes
+settings_pane_snippets_body=Losi eisas un jaukas ziņas nu Mozilla par Firefox, interneta kulturu un najaušas memes.
+settings_pane_done_button=Gotovs
+settings_pane_topstories_options_sponsored=Rōdēt apmoksōtas ziņas
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Redigeit
+edit_topsites_button_label=Īstoti sovu top lopu sadaļu
+edit_topsites_showmore_button=Rōdeit vaira
+edit_topsites_showless_button=Rōdēt mozōk
+edit_topsites_done_button=Gotovs
+edit_topsites_pin_button=Daspraust lopu
+edit_topsites_unpin_button=Atbreivōt lopu
+edit_topsites_edit_button=Maineit lopu
+edit_topsites_dismiss_button=Paslēpt lopu
+edit_topsites_add_button=Pīvīnōt
+edit_topsites_add_button_tooltip=Pīvīnōt pi popularōkōm lopom
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Jauna lopa topā
+topsites_form_edit_header=Maineit lopu topā
+topsites_form_title_placeholder=Īvodi viersrokstu
+topsites_form_url_placeholder=Īroksti voi īleimej lopas URL
+topsites_form_add_button=Pīvīnōt
+topsites_form_save_button=Saglobōt
+topsites_form_cancel_button=Atceļt
+topsites_form_url_validation=Napīcīšams korekts URL
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Popularas tēmas:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Vaira rokstu
+# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
+# to Pocket as part of the feedback form.
+pocket_feedback_header=Lobōkais nu interneta, kū atlasiejuši 25 miljoni ļaužu.
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane and
+# below (pocket_feedback_header) to provide more information about Pocket.
+pocket_description=Atklōj sev kvalitativu , kuru tu cytaižōk palaissi garom, ar Pocket, kurais ņiuļa ir Mozilla sastōvā.
+
+highlights_empty_state=Sōc porlyukōšonu un mes tev parōdēsim dažus breineigus rokstus, video un cytys lopys, kuras tu naseņ esi skatiejs voi davīnōjs grōmotzeimem.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Esi vysu izlasiejs. Īej vāļōk, kab redzēt vaira ziņu nu {provider}. Nagribi gaidēt? Izavielej popularu tēmu, kab atrostu vaira interesantu rokstu nu vysa interneta.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Paraugi Firefox ar grōmotzeimem, viesturi un parolem nu cyta porlyuka.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Nā, paļdis
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importeit
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/lv/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Jauna cilne
+
+header_top_sites=Populārākās lapas
+header_highlights=Aktualitātes
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Iesaka {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Atvērt izvēlni {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Atvērt sadaļas izvēlni
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Apmeklēta
+type_label_bookmarked=Grāmatzīmēs
+type_label_recommended=Populāri
+type_label_pocket=Saglabāts Pocket
+type_label_downloaded=Lejupielādēts
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Saglabāt
+menu_action_remove_bookmark=Noņemt grāmatzīmi
+menu_action_open_new_window=Atvērt saiti jaunā logā
+menu_action_open_private_window=Atvērt saiti jaunā privātajā logā
+menu_action_dismiss=Noraidīt
+menu_action_delete=Dzēst no vēstures
+menu_action_pin=Piespraust
+menu_action_unpin=Atspraust
+confirm_history_delete_p1=Vai tiešām vēlaties dzēst visas šīs lapas versijas no jūsu vēstures?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Šī ir neatgriezeniska darbība.
+menu_action_save_to_pocket=Saglabāt Pocket
+menu_action_delete_pocket=Dzēst no Pocket
+menu_action_archive_pocket=Arhivēt Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Parādīt Finder
+menu_action_show_file_windows=Atvērt mapi
+menu_action_show_file_linux=Atvērt mapi
+menu_action_show_file_default=Rādīt failu
+menu_action_open_file=Atvērt failu
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Kopēt lejupielādes saiti
+menu_action_go_to_download_page=Iet uz lejupielāžu lapu
+menu_action_remove_download=Noņemt no vēstures
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Meklēt
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} meklēšana
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Meklēt internetā
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Interesantākie stāsti internetā, atkasīti balstoties uz jūsu lasīto. No Pocket, kas tagad ir daļa no Mozilla.
+section_disclaimer_topstories_linktext=Apskatiet kā tas strādā.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Labi, sapratu
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox sākuma saturs
+prefs_home_description=Izvēlieties, ko redzēt Firefox sākuma lapā.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} rindu;{num} rinda;{num} rindas
+prefs_search_header=Tīmekļa meklēšana
+prefs_topsites_description=Biežāk apmeklētās lapas
+prefs_topstories_description2=Saņemiet sev pielāgotu saturu no visas pasaules
+prefs_topstories_options_sponsored_label=Sponsorētie stāsti
+prefs_topstories_sponsored_learn_more=Uzzināt vairāk
+prefs_highlights_description=Jūsu apmeklēto vai saglabāto lapu izlase
+prefs_highlights_options_visited_label=Apmeklētās lapas
+prefs_highlights_options_download_label=Nesenās lejupielādes
+prefs_highlights_options_pocket_label=Pocket saglabātās lapas
+prefs_snippets_description=Mozilla un Firefox jaunumi
+settings_pane_button_label=Pielāgojiet jaunās cilnes lapu
+settings_pane_topsites_header=Populārākās lapas
+settings_pane_highlights_header=Aktualitātes
+settings_pane_highlights_options_bookmarks=Grāmatzīmes
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Fragmenti
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Rediģēt
+edit_topsites_edit_button=Rediģēt šo lapu
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Jauna populārā lapa
+topsites_form_edit_header=Rediģēt populārās lapas
+topsites_form_title_label=Virsraksts
+topsites_form_title_placeholder=Ievadiet nosaukumu
+topsites_form_url_label=URL
+topsites_form_image_url_label=Pielāgota attēla adrese
+topsites_form_url_placeholder=Ievadiet vai iekopējiet adresi
+topsites_form_use_image_link=Izmantot citu attēlu…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Priekšskatījums
+topsites_form_add_button=Pievienot
+topsites_form_save_button=Saglabāt
+topsites_form_cancel_button=Atcelt
+topsites_form_url_validation=Nepieciešama derīga adrese
+topsites_form_image_validation=NEizdevās ielādēt attēlu. Izmēģiniet citu adresi.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Populārās tēmas:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Parādīt vairāk lapas
+
+highlights_empty_state=Sāciet pārlūkošanu un mēs šeit parādīsim lieliskus rakstus, video un citas apmeklētās lapas.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Viss ir apskatīts! Atnāciet atpakaļ nedaudz vēlāk, lai redzētu populāros stāstus no {provider}. Nevarat sagaidīt? Izvēlieties kādu no tēmām jau tagad.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Izmēģiniet Firefox ar grāmatzīmēm, vēsturi un parolēm no cita pārlūka.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Nē, paldies
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importē tagad
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ak vai, ielādējot saturu kaut kas nogājis greizi.
+error_fallback_default_refresh_suggestion=Pārlādējiet lapu, lai mēģinātu vēlreiz.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Aizvākt sadaļu
+section_menu_action_collapse_section=Sakļaut sadaļu
+section_menu_action_expand_section=Izvērst sadaļu
+section_menu_action_manage_section=Pārvaldīt sadaļu
+section_menu_action_manage_webext=Pārvaldīt paplašinājumu
+section_menu_action_add_topsite=Pievienot populāru lapu
+section_menu_action_move_up=Pārvietot augšup
+section_menu_action_move_down=Pārvietot lejup
+section_menu_action_privacy_notice=Privātuma politika
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Paņemiet Firefox sev līdz
+firstrun_content=Izmantojiet grāmatzīmes, vēsturi, saglabātās paroles un citus iestatījumus visās savās ierīcēs.
+firstrun_learn_more_link=Uzzini vairāk par Firefox kontiem
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Ievadiet savu epastu
+firstrun_form_sub_header=lai turpinātu Firefox Sync.
+
+firstrun_email_input_placeholder=Epasts
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Turpinot jūs piekrītat {terms} un {privacy}.
+firstrun_terms_of_service=Lietošanas noteikumiem
+firstrun_privacy_notice=Privātuma politikai
+
+firstrun_continue_to_login=Turpināt
+firstrun_skip_login=Izlaist šo soli
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/mai/strings.properties
@@ -0,0 +1,177 @@
+newtab_page_title=नव टैब
+
+header_top_sites=टॉप साइट
+header_highlights=हाइलाइट
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} द्वारा अनुशंसित
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr={title} कलेल कॉन्टेक्स्ट मेनू खोलू
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=सेक्शन कॉन्टेक्ट मेनू खोलू
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=देखल गेल
+type_label_bookmarked=बुकमार्क करल
+type_label_recommended=ट्रेंडिंग
+type_label_pocket=Pocket मे सहेजल
+type_label_downloaded=डाउनलोड करल
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=पुस्तचिह्न
+menu_action_remove_bookmark=पुस्तचिह्न हटाबू
+menu_action_open_new_window=नव विंडो मे खोलू
+menu_action_open_private_window=नव निजी विंडो मे खोलू
+menu_action_dismiss=खारिज करू
+menu_action_delete=इतिहास सँ मेटाबू
+menu_action_pin=पिन करू
+menu_action_unpin=पिन हटाबू
+confirm_history_delete_p1=की अहाँ वाकई ई पृष्ठक हर उदाहरण क अपन इतिहास सँ हटाबै चाहैत छी?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=ई क्रिया केँ पहिले जहिना नहि कएल जाए सकैत अछि.
+menu_action_save_to_pocket=Pocket मे सहेजू
+menu_action_delete_pocket=पॉकेट सँ हटाबू
+menu_action_archive_pocket=पॉकेट मे आर्काइव
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=फाइंडरमे देखाउ
+menu_action_show_file_windows=संग्राहक फोल्डर खोलू
+menu_action_show_file_linux=संग्राहक फोल्डर खोलू
+menu_action_show_file_default=फाइल देखाबू
+menu_action_open_file=फाइल खोलू
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=डाउनलोड लिंक कॉपी करू 
+menu_action_go_to_download_page=डाउनलोड पृष्ठ पर जाउ
+menu_action_remove_download=इतिहास सँ हटाउ
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=खोज
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} खोजू
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=वेब पर खोजू
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=वेब पर सबसँ दिलचस्प स्टोरी, अहाँक पढब आधार पर चुनल. पॉकेट द्वारा, जे आब Mozilla क भाग अछि.
+section_disclaimer_topstories_linktext=जानू जे ई कओन तरहें काज करैत अछि.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=ठीक अछि, बुझि गेलहुँ.
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox होम सामग्री
+prefs_home_description=चुनू, Firefox होम स्क्रीन पर जे सामग्री चाहैत छी.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} पंक्ति;{num} पंक्ति सभ
+prefs_search_header=वेब खोज
+prefs_topsites_description=जे साइट अहाँ सबसँ बेसी विजिट कएलहुँ
+prefs_topstories_description2=वेब सँ बढियाँ कंटेंट पाबू, अहाँ खातिर पर्सनलाइज कएल गेल 
+prefs_topstories_options_sponsored_label=स्पोंसर कएल स्टोरी
+prefs_topstories_sponsored_learn_more=आओर जानू
+prefs_highlights_description=जे साइट अहाँ विजिट कएलहुँ अथवा सहेजलहुँ ओकर चयन
+prefs_highlights_options_visited_label=विजिट कएल पेज
+prefs_highlights_options_download_label=हालुक डाउनलोड
+prefs_highlights_options_pocket_label=पॉकेट मे सहेजल पेज
+prefs_snippets_description=Mozilla आओर Firefox सँ अद्यतन
+settings_pane_button_label=अपन नव टैब पृष्ठ पसंदीदा बनाउ
+settings_pane_topsites_header=टॉप साइट
+settings_pane_highlights_header=हाइलाइट
+settings_pane_highlights_options_bookmarks=पुस्तकचिह्न
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=अंश
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=संपादन
+edit_topsites_edit_button=ई साइट केँ संपादित करू
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=नव टॉप साइट
+topsites_form_edit_header=टॉप साइट संपादित करू
+topsites_form_title_label=शीर्षक
+topsites_form_title_placeholder=शीर्षक दर्ज करू
+topsites_form_url_label=URL
+topsites_form_image_url_label=कस्टम छवि URL
+topsites_form_url_placeholder=एकटा URL टाइप अथवा साटू
+topsites_form_use_image_link=एकटा कस्टम छवि उपयोग करू...
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=पूर्वावलोकन
+topsites_form_add_button=जोड़ू
+topsites_form_save_button=सहेजू
+topsites_form_cancel_button=कैंसिल करू
+topsites_form_url_validation=मान्य URL जरूरी
+topsites_form_image_validation=छवि लोड करए मे असफल. दोसर URL सँ कोसिस करू.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=लोकप्रिय विषय:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=बेसी स्टोरी देखाबू
+
+highlights_empty_state=ब्राउजिंग आरंभ करू, आओर हम अहाँक किछु बढियाँ नवीन आर्टिकिल, वीडियो, आओर आन पेज देखाएब, जकरा अङाँ हाले में विजिट कएलहुँ अथवा एतय बुकमार्क कएलहुँ.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=अहाँ आखिर धरि पहुँचि गेलहु, {provider} सँ बाद में फिनु टॉप स्टोरी देखू. इंतजार नहि कए सकब? अधिक बढिया स्टोरी वेब सँ पाबै लेल एकटा लेकप्रिय टॉपिक चुनू.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=बुकमार्क, इतिहास आओर पासवर्ड सँग Firefox केँ आन ब्राउजर सँग आजमाबू. 
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=नहि धन्यवाद
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=आब आयात करू
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=ओह, बुझाय अछि जे कंटेंट लोड हए मे किछु गलत भ गेल.
+error_fallback_default_refresh_suggestion=फेनु प्रयास करए लेल पेज रीफ्रेश करू.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=खंड हटाबू
+section_menu_action_collapse_section=खंड संक्षिप्त करू
+section_menu_action_expand_section=खंड पसारू
+section_menu_action_manage_section=खंड प्रबंधित करू
+section_menu_action_add_topsite=टॉप साइट जोड़ू
+section_menu_action_move_up=उप्पर जाउ
+section_menu_action_move_down=नीच्चाँ जाउ
+section_menu_action_privacy_notice=गोपनीयता सूचना
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/mk/strings.properties
@@ -0,0 +1,199 @@
+newtab_page_title=Ново јазиче
+default_label_loading=Се вчитува…
+
+header_top_sites=Популарни мрежни места
+header_stories=Популарни написи
+header_highlights=Интереси
+header_visit_again=Посети повторно
+header_bookmarks=Скорешни обележувачи
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Препорачано од {provider}
+# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
+# meant to inform that section contains no information because
+# the user hasn't added any bookmarks.
+header_bookmarks_placeholder=Сѐ уште немате обележувачи.
+# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
+# corresponding content (stories) provider
+header_stories_from=од
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Посетени
+type_label_bookmarked=Обележани
+type_label_synced=Синхронизирани од други уреди
+type_label_recommended=Во тренд
+type_label_pocket=Снимено во Pocket
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=Отворени
+type_label_topic=Тема
+type_label_now=Сега
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Обележувач
+menu_action_remove_bookmark=Отстрани обележувач
+menu_action_copy_address=Копирај адреса
+menu_action_email_link=Испрати врска…
+menu_action_open_new_window=Отвори во нов прозорец
+menu_action_open_private_window=Отвори во нов приватен прозорец
+menu_action_dismiss=Откажи
+menu_action_delete=Избриши од историја
+menu_action_pin=Прикачи
+menu_action_unpin=Откачи
+confirm_history_delete_p1=Дали сте сигурни дека сакате да ја избришете оваа страница отсекаде во вашата историја на прелистување?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Ова дејство не може да се одврати.
+menu_action_save_to_pocket=Зачувај во Pocket
+menu_action_delete_pocket=Избриши од Pocket
+menu_action_archive_pocket=Архивирај во Pocket
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with=Пребарај за {search_term} со:
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Барај
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Пребарување со {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Пребарајте на Интернет
+search_settings=Промени поставувања за пребарување
+
+# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the
+# (?) icon that would show a section's description with optional feedback link.
+section_info_option=Инфо
+section_info_send_feedback=Испрати мислење
+section_info_privacy_notice=Белешка за приватност
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=Добредојдовте во новото јазиче
+welcome_body=Firefox ќе го искористи овој простор за да Ви ги прикаже најрелевантните обележувачи, написи, видеа и страници што сте ги посетиле, за да можете лесно да им се навратите.
+welcome_label=Ги откривам вашите Интереси
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=< 1 м
+time_label_minute={number} м
+time_label_hour={number} ч
+time_label_day={number} д
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+# LOCALIZATION NOTE (prefs_topstories_show_sponsored_label): {provider} is
+# replaced by the name of the content provider for this section, e.g., "Pocket"
+settings_pane_button_label=Прилагодете ја страницата на вашето Ново јазиче
+settings_pane_header=Преференци за Ново јазиче
+settings_pane_body2=Изберете што ќе гледате на оваа страница.
+settings_pane_search_header=Пребарување
+settings_pane_search_body=Пребарајте низ Интернет од вашето ново јазиче.
+settings_pane_topsites_header=Популарни мрежни места
+settings_pane_topsites_body=Пристапете до мрежните места што ги посетувате најмногу.
+settings_pane_topsites_options_showmore=Прикажи два реда
+settings_pane_bookmarks_header=Скорешни обележувачи
+settings_pane_bookmarks_body=Вашите нови обележувачи во едно згодно место.
+settings_pane_visit_again_header=Посети повторно
+settings_pane_visit_again_body=Firefox ќе прикаже делови од вашата историја на прелистување кои можеби би сакале да ги запомните или пак да им се навратите.
+settings_pane_highlights_header=Интереси
+settings_pane_highlights_body2=Навратете се на интересни места што неодамна сте ги посетиле или обележале.
+settings_pane_highlights_options_bookmarks=Обележувачи
+settings_pane_highlights_options_visited=Посетени мрежни места
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Исечоци
+settings_pane_snippets_body=Прочитајте кратки и слатки новости од Mozilla во врска со Firefox, Интернет-културата и повремените случајни меми.
+settings_pane_done_button=Готово
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Уреди
+edit_topsites_button_label=Прилагодете ги вашите Популарни мрежни места
+edit_topsites_showmore_button=Прикажи повеќе
+edit_topsites_showless_button=Прикажи помалку
+edit_topsites_done_button=Готово
+edit_topsites_pin_button=Прикачи го ова мрежно место
+edit_topsites_unpin_button=Откачи го ова мрежно место
+edit_topsites_edit_button=Уреди го ова место
+edit_topsites_dismiss_button=Отфрли го ова место
+edit_topsites_add_button=Додај
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Ново врвно мрежно место
+topsites_form_edit_header=Уреди врвно мрежно место
+topsites_form_title_placeholder=Внесете наслов
+topsites_form_url_placeholder=Внесете или вметнете URL
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_add_button=Додај
+topsites_form_save_button=Сними
+topsites_form_cancel_button=Откажи
+topsites_form_url_validation=Потребен е валиден URL
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Популарни теми:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Види повеќе написи
+# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
+# to Pocket as part of the feedback form.
+pocket_feedback_header=Најдоброто од Интернет, одбрано од повеќе од 25 милиони луѓе.
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane and
+# below (pocket_feedback_header) to provide more information about Pocket.
+pocket_description=Откријте високо-квалитетни содржини, коишто инаку би можеле да ги пропуштите, со помош на Pocket, кој сега е дел од Mozilla.
+
+highlights_empty_state=Започнете со прелистување и ние овде ќе ви прикажеме некои од одличните написи, видеа и други страници што неодамна сте ги поселите или обележале.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Имате видено сѐ! Навратете се подоцна за нови содржини од {provider}. Не можете да чекате? Изберете популарна тема и откријте уште одлични содржини ширум Интернет.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Пробајте го Firefox со обележувачите, историјата и лозинките на друг прелистувач.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Не, благодарам
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Увези сега
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ml/strings.properties
@@ -0,0 +1,146 @@
+newtab_page_title=പുതിയ ടാബ്
+
+header_top_sites=മികച്ച സൈറ്റുകൾ
+header_highlights=ഹൈലൈറ്റുകൾ
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} ശുപാർശ ചെയ്തത്
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=സന്ദർശിച്ചത്‌
+type_label_bookmarked=അടയാളപ്പെടുത്തിയത്
+type_label_recommended=ട്രെൻഡിംഗ്
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=അടയാളം
+menu_action_remove_bookmark=അടയാളം മാറ്റുക
+menu_action_open_new_window=പുതിയ ജാലകത്തിൽ തുറക്കുക
+menu_action_open_private_window=പുതിയ രസഹ്യജാലകത്തിൽ തുറക്കുക
+menu_action_dismiss=പുറത്താക്കുക
+menu_action_delete=ചരിത്രത്തിൽ നിന്ന് ഒഴിവാക്കുക
+menu_action_pin=പിൻ ചെയ്യുക
+menu_action_unpin=അൺപിൻ ചെയ്യുക
+confirm_history_delete_p1=നിങ്ങളുടെ ചരിത്രത്തിൽ നിന്ന് ഈ പേജിന്റെ എല്ലാ ഉദാഹരണങ്ങളും ഇല്ലാതാക്കാൻ നിങ്ങൾ താൽപ്പര്യപ്പെടുന്നുവെന്ന് തീർച്ചയാണോ?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=ഈ പ്രവർത്തനം പഴയപടിയാക്കാനാവില്ല.
+menu_action_save_to_pocket=പോക്കറ്റിലേയ്ക്ക് സംരക്ഷിയ്ക്കുക
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=തിരയുക
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} തിരയുക
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=ഇൻറർനെറ്റിൽ തിരയുക
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=വെബിലെ ഏറ്റവും രസകരമായ അറിവുകൾ, നിങ്ങൾ വായിച്ചവ അടിസ്ഥാനമാക്കി തിരഞ്ഞെടുത്തത്. ഇപ്പോൾ മോസില്ലയുടെ ഭാഗമായ പോക്കറ്റിൽ നിന്നും.
+section_disclaimer_topstories_linktext=എങ്ങനെ പ്രവര്‍ത്തിക്കുന്നു എന്ന് കാണുക.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=ശരി, മനസ്സിലായി
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+settings_pane_button_label=നിങ്ങളുടെ പുതിയ ടാബ് താള് ഇഷ്ടാനുസൃതമാക്കുക
+settings_pane_topsites_header=മുന്നേറിയ സൈറ്റുകൾ
+settings_pane_highlights_header=ഹൈലൈറ്റുകൾ
+settings_pane_highlights_options_bookmarks=ബുക്ക്മാർക്കുകൾ
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=ലഘു കുറിപ്പുകൾ
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=തിരുത്തുക
+edit_topsites_edit_button=ഈ സൈറ്റ് തിരുത്തുക
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=പുതിയ മികച്ച സൈറ്റുകൾ
+topsites_form_edit_header=മികച്ച സൈറ്റ് ലിസ്റ്റ് തിരുത്തൂ
+topsites_form_title_placeholder=തലക്കെട്ട് നൽകൂ
+topsites_form_url_placeholder=വെബ്URLനൽകൂ
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_add_button=ചേർക്കൂ
+topsites_form_save_button=സംരക്ഷിയ്ക്കൂ
+topsites_form_cancel_button=ഒഴിവാക്കൂ
+topsites_form_url_validation=പ്രവർത്തിയ്ക്കുന്ന URL ആവശ്യമാണ്
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=ജനപ്രിയ വിഷയങ്ങൾ:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=കൂടുതൽ ലേഖനങ്ങൾ കാണുക
+
+highlights_empty_state=ബ്രൗസിംഗ് ആരംഭിക്കുക, നിങ്ങൾ സമീപകാലത്ത് സന്ദർശിച്ചതോ ബുക്ക്മാർക്ക് ചെയ്തതോ ആയ മികച്ച ലേഖനങ്ങളിൽ നിന്നോ, വീഡിയോകളിൽ നിന്നോ, മറ്റു പേജുകളിൽ നിന്നോ ചിലത് ഞങ്ങൾ ഇവിടെ കാണിക്കും.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=നിങ്ങൾ ഇവിടെ വരെ എത്തി. {provider}ൽ നിന്നുള്ള കൂടുതൽ പ്രധാന വാർത്തകൾക്കായി പിന്നീട് വീണ്ടും പരിശോധിക്കുക. കാത്തിരിക്കാൻ പറ്റില്ലേ? വെബിൽ നിന്ന് കൂടുതൽ മികച്ച കഥകൾ കണ്ടെത്തുന്നതിന് ഒരു ജനപ്രിയ വിഷയം തിരഞ്ഞെടുക്കുക.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=മറ്റൊരു ബ്രൗസറിൽ നിന്നുള്ള ബുക്ക്മാർക്കുകൾ, ചരിത്രം, പാസ്വേഡുകൾ എന്നിവ ഉപയോഗിച്ച് ഫയർഫോക്സ് പരീക്ഷിക്കുക.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=വേണ്ട, നന്ദി
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=ഇപ്പോൾ ഇറക്കുമതി ചെയ്യുക
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/mr/strings.properties
@@ -0,0 +1,85 @@
+newtab_page_title=नवीन टॅब
+default_label_loading=दाखल करीत आहे…
+
+header_top_sites=खास साईट्स
+header_highlights=ठळक
+header_stories=महत्वाच्या गोष्टी
+# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
+# corresponding content (stories) provider
+header_stories_from=कडून
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=भेट दिलेले
+type_label_bookmarked=वाचनखुण लावले
+type_label_synced=इतर साधनावरुन ताळमेळ केले
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=उघडा
+type_label_topic=विषय
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=वाचनखुण
+menu_action_remove_bookmark=वाचनखुण काढा
+menu_action_copy_address=पत्त्याची प्रत बनवा
+menu_action_email_link=दुवा इमेल करा…
+menu_action_open_new_window=नवीन पटलात उघडा
+menu_action_open_private_window=नवीन खाजगी पटलात उघडा
+menu_action_dismiss=रद्द करा
+menu_action_delete=इतिहासातून नष्ट करा
+menu_action_save_to_pocket=Pocket मध्ये जतन करा
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with=शोधा {search_term} सोबत:
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=शोधा
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} शोध
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=वेबवर शोधा
+search_settings=शोध सेटिंग बदला
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=नवीन टॅबवर स्वागत आहे
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=<1मि
+time_label_minute={number}मि
+time_label_hour={number}ता
+time_label_day={number}दि
+
+# LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar.
+settings_pane_button_label=आपले नवीन टॅब पृष्ठ सानुकूलित करा
+settings_pane_header=नवीन टॅब प्राधान्ये
+settings_pane_body=नवीन टॅब उघडल्यानंतर काय दिसायला हवे ते निवडा.
+settings_pane_search_header=शोध
+settings_pane_search_body=आपल्या नवीन टॅब वरून वेबवर शोधा.
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
+# to Pocket as part of the feedback form.
+# LOCALIZATION NOTE (pocket_feedback_body): This is shown below
+# (pocket_feedback_header) to provide more information about Pocket.
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ms/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Tab Baru
+
+header_top_sites=Laman Teratas
+header_highlights=Serlahan
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Disyorkan oleh {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Buka menu konteks untuk {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Buka bahagian menu konteks
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Dilawati
+type_label_bookmarked=Ditandabuku
+type_label_recommended=Sohor kini
+type_label_pocket=Disimpan ke Pocket
+type_label_downloaded=Telah dimuat turun
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Tandabuku
+menu_action_remove_bookmark=Buang Tandabuku
+menu_action_open_new_window=Buka dalam Tetingkap Baru
+menu_action_open_private_window=Buka dalam Tetingkap Peribadi Baru
+menu_action_dismiss=Abai
+menu_action_delete=Buang daripada Sejarah
+menu_action_pin=Pin
+menu_action_unpin=Nyahpin
+confirm_history_delete_p1=Adakah anda pasti mahu membuang setiap contoh halaman ini daripada sejarah anda?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Tindakan ini tidak boleh dibatalkan.
+menu_action_save_to_pocket=Simpan ke Pocket
+menu_action_delete_pocket=Buang dari Pocket
+menu_action_archive_pocket=Arkib dalam Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Papar dalam Finder
+menu_action_show_file_windows=Buka Kandungan Folder
+menu_action_show_file_linux=Buka Kandungan Folder
+menu_action_show_file_default=Papar Fail
+menu_action_open_file=Buka Fail
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Salin Pautan Muat Turun
+menu_action_go_to_download_page=Pergi ke Halaman Muat Turun
+menu_action_remove_download=Buang daripada Sejarah
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Cari
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} Cari
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Cari dalam Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Kisah paling menarik dalam web yang dipilih berdasarkan yang anda baca. Dari Pocket, kini sebahagian daripada Mozilla.
+section_disclaimer_topstories_linktext=Ketahui fungsi ciri ini.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ok, faham
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Kandungan Halaman Utama Firefox
+prefs_home_description=Pilih kandungan yang mahu dalam skrin Halaman Utama Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} rows
+prefs_search_header=Carian Web
+prefs_topsites_description=Laman yang anda kerap lawati
+prefs_topstories_description2=Kandungan hebat dalam seluruh web, khas untuk anda
+prefs_topstories_options_sponsored_label=Kisah Tajaan
+prefs_topstories_sponsored_learn_more=Ketahui selanjutnya
+prefs_highlights_description=Pilihan laman yang anda sudah simpan atau lawati
+prefs_highlights_options_visited_label=Halaman Dilawati
+prefs_highlights_options_download_label=Muat Turun Terbaru
+prefs_highlights_options_pocket_label=Halaman Disimpan ke Pocket
+prefs_snippets_description=Kemas kini daripada Mozilla dan Firefox
+settings_pane_button_label=Sesuaikan halaman Tab Baru anda
+settings_pane_topsites_header=Laman Teratas
+settings_pane_highlights_header=Serlahan
+settings_pane_highlights_options_bookmarks=Tandabuku
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Cebisan
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Edit
+edit_topsites_edit_button=Edit laman ini
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Laman Teratas Baru
+topsites_form_edit_header=Edit Laman Teratas
+topsites_form_title_label=Tajuk
+topsites_form_title_placeholder=Masukkan tajuk
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL Imej Penyesuaian
+topsites_form_url_placeholder=Taip atau tampal URL
+topsites_form_use_image_link=Guna imej penyesuaian…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Previu
+topsites_form_add_button=Tambah
+topsites_form_save_button=Simpan
+topsites_form_cancel_button=Batal
+topsites_form_url_validation=Perlukan URL yang sah
+topsites_form_image_validation=Imej gagal dimuatkan. Cuba URL lain.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Topik Popular:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Papar Kisah Selanjutnya
+
+highlights_empty_state=Mulakan melayar dan kami akan paparkan beberapa artikel, video dan halaman menarik lain yang sudah anda layari dan tandabuku di sini.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Anda sudah di sini. Tapi sila datang lagi untuk mendapatkan lebih banyak berita hangat daripada {provider}. Tidak boleh tunggu? Pilih topik untuk mendapatkannya dari serata dunia.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Cuba Firefox dengan tandabuku, sejarah dan kata laluan yang disimpan dalam pelayar lain.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Tidak, Terima kasih
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Import Sekarang
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ooops, ada kesilapan memuatkan kandungan ini.
+error_fallback_default_refresh_suggestion=Muat semula halaman untuk cuba lagi.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Buang Seksyen
+section_menu_action_collapse_section=Runtuhkan Seksyen
+section_menu_action_expand_section=Kembangkan Seksyen
+section_menu_action_manage_section=Urus Seksyen
+section_menu_action_manage_webext=Urus Ekstensi
+section_menu_action_add_topsite=Tambah Laman Teratas
+section_menu_action_move_up=Pindah Atas
+section_menu_action_move_down=Pindah Bawah
+section_menu_action_privacy_notice=Notis Privasi
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Bawa Firefox bersama Anda
+firstrun_content=Dapatkan tandabuku, sejarah, kata laluan dan tetapan lain dalam semua peranti anda.
+firstrun_learn_more_link=Ketahui selanjutnya perihal Akaun Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Masukkan e-mel anda
+firstrun_form_sub_header=untuk ke Firefox Sync.
+
+firstrun_email_input_placeholder=E-mel
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Dengan meneruskan, anda bersetuju dengan {terms} dan {privacy}.
+firstrun_terms_of_service=Terma Perkhidmatan
+firstrun_privacy_notice=Notis Privasi
+
+firstrun_continue_to_login=Teruskan
+firstrun_skip_login=Langkau langkah ini
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/my/strings.properties
@@ -0,0 +1,162 @@
+newtab_page_title=တပ်ဗ်အသစ်ဖွင့်
+default_label_loading=ရယူနေသှ်…
+
+header_top_sites=အများဆုံးသုံးဆိုက်များ
+header_stories=အကြည့်အများဆုံးသတင်းများ
+header_highlights=ဦးစားပေးအကြောင်းအရာများ
+header_visit_again=ထပ်မံလည်ပတ်ရန်
+header_bookmarks=လတ်တလော စာမှတ်များ
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} က အကြံပြုထားသည်
+# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
+# meant to inform that section contains no information because
+# the user hasn't added any bookmarks.
+header_bookmarks_placeholder=မည်သည့်စာမှတ်မျှ မရှိသေးပါ။
+# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
+# corresponding content (stories) provider
+header_stories_from=မှ
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=သွားလည်ခဲ့သော
+type_label_bookmarked=စာအမှတ်မှတ်ထားသော
+type_label_synced=အခြားပစ္စည်းတစ်ခုမှရယူထားသှ်
+type_label_recommended=လူကြိုက်များနေသော
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=ဖွင့်ပါ
+type_label_topic=အကြောင်းအရာ
+type_label_now=ယခု
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=စာအမှတ်
+menu_action_remove_bookmark=စာအမှတ်အားဖယ်ပါ
+menu_action_copy_address=လိပ်စာအားကူးယူပါ
+menu_action_email_link=လင်ခ့်အားအီးမေလ်းဖြင့်ပို့ပါ…
+menu_action_open_new_window=အခြားဝင်းဒိုးတစ်ခုမှဖွင့်ပါ
+menu_action_open_private_window=အခြားတစ်ကိုယ်ရေသုံးဝင်းဒိုးတစ်ခုဖွင့်ပါ
+menu_action_dismiss=ပိတ်လိုက်ပါ
+menu_action_delete=မှတ်တမ်းမှ ဖျက်ပါ
+menu_action_pin=တွယ်ရန်
+menu_action_unpin=တွယ်ဖြုတ်ရန်
+confirm_history_delete_p1=ယခုစာမျက်နှာနှင့် ဆိုင်သော အရာအားလုံးကို မှတ်တမ်းမှ ဖယ်ရှားလိုပါသလား။
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=ယခုလုပ်ဆောင်မှုသည် နောက်ပြန်ဆုတ်၍မရသော လုပ်ဆောင်မှု ဖြစ်သည်။
+menu_action_save_to_pocket=Pocket သို့ သိမ်းရန်
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with={search_term} အားရှာပါ -
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=ရှာ
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} ရှာဖွေမှု
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=ဝတ်ဘ်ပေါ်တွင် ရှာဖွေခြင်း
+search_settings=ရှာဖွေမှုအပြင်အဆင်အားပြောင်းလဲပါ
+
+# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the
+# (?) icon that would show a section's description with optional feedback link.
+section_info_option=အချက်အလက်
+section_info_send_feedback=အကြံပေးချက် ပေးပို့ရန်
+section_info_privacy_notice=ကိုယ်ရေးကာကွယ်မှု သတိပေးချက်
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=တပ်ဗ်အသစ်တစ်ခုမှကြိုဆိုပါတယ်
+welcome_body=ယခုနေရာအား Firefox မှ အသင့်လျော်ဆုံး သင်သွားလည်ခဲ့ဖူးသော စာအမှတ်များ၊ ဆောင်းပါးများ၊ ရုပ်ရှင်များ နှင့် စာမျက်နှာများအား ပြသဖို့အသုံးပြုမည်ဖြစ်ပါတယ်။
+welcome_label=သင့် အသားပေးဖော်ပြချက်များကိုသတိထားမည်
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=<1မီတာ
+time_label_minute={number}မီတာ
+time_label_hour={number}အမြင့်
+time_label_day={number}နေ့
+
+# LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar.
+settings_pane_button_label=သင့်တပ်ဗ်အသစ်စာမျက်နှာအား ပြင်ဆင်မည်
+settings_pane_header=စာတပ်ဗ်အသစ်အပြင်အဆင်များ
+settings_pane_body2=ယခုစာမျက်နှာတွင် ကြည့်လိုသည်များကို ရွေးပါ။
+settings_pane_search_header=ရှာဖွေပါ
+settings_pane_search_body=ဝက်ဘ်ပေါ်တွင် သင့်တပ်ဗ်အသစ်မှရှာဖွေပါ
+settings_pane_topsites_header=ထိပ်တန်းဝတ်ဘ်ဆိုက်များ
+settings_pane_topsites_body=သင်အများဆုံးသွားလည်သော ဝတ်ဘ်ဆိုက်များကို ရယူပါ
+settings_pane_topsites_options_showmore=အတန်းနှစ်တန်းနှင့်ပြပါ
+settings_pane_bookmarks_header=လတ်တလော စာမှတ်များ
+settings_pane_bookmarks_body=အသစ်မှတ်သားထားသော စာမှတ်များကို တစ်နေရာတည်းတွင် စုစည်းထားသည်။
+settings_pane_visit_again_header=ထပ်မံလည်ပတ်ရန်
+settings_pane_visit_again_body=မှတ်ထားလိုသော သို့မဟုတ် ပြန်ဖွင့်လိုသော လည်ပတ်မှတ်တမ်းထဲမှ တချို့ကို Firefox က ပြပါမည်။
+settings_pane_highlights_header=ဦးစားပေးအကြောင်းအရာများ
+settings_pane_highlights_options_bookmarks=စာမှတ်များ
+settings_pane_highlights_options_visited=လည်ပတ်ထားသော ဆိုက်များ
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=မှတ်စုတိုများ
+settings_pane_snippets_body=Mozilla မှ Firefox အကြောင်း၊ အင်တာနက်ယဉ်ကျေးမှုနှင့် အခါအားလျော်စွာ ဖြစ်ပေါ်လာသော ကျပန်း meme စသည့် နောက်ဆုံးရသတင်းများကို ဖတ်ရှုပါ။
+settings_pane_done_button=ပြီးပြီ
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=ပြင်ဆင်မည်
+edit_topsites_button_label=သင့်ထိပ်တန်းဆိုက် အမြင်အားပြင်ဆင်ပါ
+edit_topsites_showmore_button=ထပ်ပြပါ
+edit_topsites_showless_button=ချုံ့ပြရန်
+edit_topsites_done_button=ပြီးပြီ
+edit_topsites_pin_button=ဝတ်ဆိုဒ်အားpinလုပ်ထားမည်
+edit_topsites_unpin_button=ယခုဆိုက်ကို တွယ်ဖြုတ်ရန်
+edit_topsites_edit_button=ဆိုက်အားပြင်မည်
+edit_topsites_dismiss_button=ဆိုက်အားဖျက်လိုက်မည်
+edit_topsites_add_button=ထည့်ရန်
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=ထိပ်တန်းဆိုက် အသစ်
+topsites_form_edit_header=ထိပ်တန်းဆိုက်ကို တည်းဖြတ်ရန်
+topsites_form_title_placeholder=ခေါင်းစဉ် ရေးပါ
+topsites_form_url_placeholder=URL ကို ရိုက်ပါ သို့မဟုတ် ပွားထည့်ပါ
+topsites_form_add_button=ထည့်ရန်
+topsites_form_save_button=သိမ်းရန်
+topsites_form_cancel_button=မလုပ်တော့ပါ
+topsites_form_url_validation=URL အမှန် လိုအပ်သည်
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=လူကြိုက်များခေါင်းစဉ်များ
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=နောက်ထပ်သတင်းများ ကြည့်ရန်
+# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
+# to Pocket as part of the feedback form.
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane and
+# below (pocket_feedback_header) to provide more information about Pocket.
+
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=အခြားဘရောင်ဇာမှ စာမှတ်များ၊ မှတ်တမ်းများ၊ စကားဝှက်များနှင့်အတူ Firefox တွင် စမ်းသုံးကြည့်ပါ။
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=မလိုတော့ပါ၊ ကျေးဇူးတင်ပါသည်။
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=ထည့်သွင်းရန်
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/nb-NO/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Ny fane
+
+header_top_sites=Mest besøkte nettsider
+header_highlights=Høydepunkter
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Anbefalt av {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Åpne kontekstmeny for {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Åpne seksjonens kontekstmeny
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Besøkt
+type_label_bookmarked=Bokmerket
+type_label_recommended=Trender
+type_label_pocket=Lagret til Pocket
+type_label_downloaded=Lastet ned
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Bokmerke
+menu_action_remove_bookmark=Fjern bokmerke
+menu_action_open_new_window=Åpne i nytt vindu
+menu_action_open_private_window=Åpne i nytt privat vindu
+menu_action_dismiss=Avslå
+menu_action_delete=Slett fra historikk
+menu_action_pin=Fest
+menu_action_unpin=Løsne
+confirm_history_delete_p1=Er du sikker på at du vil slette alle forekomster av denne siden fra historikken?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Denne handlingen kan ikke angres.
+menu_action_save_to_pocket=Lagre til Pocket
+menu_action_delete_pocket=Slett fra Pocket
+menu_action_archive_pocket=Arkiver i Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Vis i Finder
+menu_action_show_file_windows=Åpne mappen med filen
+menu_action_show_file_linux=Åpne mappen med filen
+menu_action_show_file_default=Vis fil
+menu_action_open_file=Åpne fil
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Kopier nedlastingslenke
+menu_action_go_to_download_page=Gå til nedlastingssiden
+menu_action_remove_download=Fjern fra historikk
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Søk
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name}-søk
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Søk på nettet
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=De mest interessante nyhetene på nettet, utvalgt basert på hva du leser. Fra Pocket, nå en del av Mozilla.
+section_disclaimer_topstories_linktext=Se hvordan det fungerer.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=OK, jeg forstår det
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Innhold Firefox-startside
+prefs_home_description=Velg hvilket innhold som du vil ha på din Firefox-startside.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} rekke;{num} rekker
+prefs_search_header=Nettsøk
+prefs_topsites_description=Mest besøkte nettsteder
+prefs_topstories_description2=Bra innhold fra hele nettet, tilpasset for deg
+prefs_topstories_options_sponsored_label=Sponsede historier
+prefs_topstories_sponsored_learn_more=Les mer
+prefs_highlights_description=Et utvalg av nettsteder som du har lagret eller besøkt
+prefs_highlights_options_visited_label=Besøkte nettsider
+prefs_highlights_options_download_label=Siste nedlasting
+prefs_highlights_options_pocket_label=Side lagret til Pocket
+prefs_snippets_description=Nyheter fra Mozilla og Firefox
+settings_pane_button_label=Tilpass siden for Ny fane
+settings_pane_topsites_header=Mest besøkte
+settings_pane_highlights_header=Høydepunkter
+settings_pane_highlights_options_bookmarks=Bokmerker
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Snutter
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Rediger
+edit_topsites_edit_button=Rediger denne nettsiden
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nytt toppsted
+topsites_form_edit_header=Rediger toppsted
+topsites_form_title_label=Tittel
+topsites_form_title_placeholder=Oppgi en tittel
+topsites_form_url_label=URL
+topsites_form_image_url_label=Egendefinert bilde-URL
+topsites_form_url_placeholder=Skriv eller lim inn en URL
+topsites_form_use_image_link=Bruk et egendefinert bilde…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Forhåndsvis
+topsites_form_add_button=Legg til
+topsites_form_save_button=Lagre
+topsites_form_cancel_button=Avbryt
+topsites_form_url_validation=Gyldig URL er nødvendig
+topsites_form_image_validation=Kunne ikke lese inn bildet. Prøv en annen URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Populære emner:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Vis flere saker
+
+highlights_empty_state=Begynn å surfe, og vi viser noen av de beste artiklene, videoer og andre sider du nylig har besøkt eller bokmerket her.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Du har tatt igjen. Kom tilbake senere for flere topphistorier fra {provider}. Kan du ikke vente? Velg et populært emne for å finne flere gode artikler fra hele Internett.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Prøv Firefox med bokmerkene, historikk og passord fra en annen nettleser.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Nei takk
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importer nå
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ups, noe gikk galt når innholdet skulle lastes inn.
+error_fallback_default_refresh_suggestion=Oppdater siden for å prøve igjen.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Fjern seksjon
+section_menu_action_collapse_section=Slå sammen seksjon
+section_menu_action_expand_section=Utvid seksjon
+section_menu_action_manage_section=Håndter seksjon
+section_menu_action_manage_webext=Behandle utvidelse
+section_menu_action_add_topsite=Legg til toppsted
+section_menu_action_move_up=Flytt opp
+section_menu_action_move_down=Flytt ned
+section_menu_action_privacy_notice=Personvernbestemmelser
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Ta med deg Firefox
+firstrun_content=Få dine bokmerker, historikk, passord, og andre innstillinger på alle enhetene dine.
+firstrun_learn_more_link=Les mer om Firefox-konto
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Skriv inn e-postadressen din
+firstrun_form_sub_header=for å fortsette til Firefox Sync.
+
+firstrun_email_input_placeholder=E-post
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Ved å fortsette, godtar du {terms} og {privacy}.
+firstrun_terms_of_service=Tjenestevilkår
+firstrun_privacy_notice=Personvernbestemmelser
+
+firstrun_continue_to_login=Fortsett
+firstrun_skip_login=Hopp over dette trinnet
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ne-NP/strings.properties
@@ -0,0 +1,177 @@
+newtab_page_title=नयाँ ट्याब
+
+header_top_sites=शीर्ष साइटहरु
+header_highlights=विशेषताहरू
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} द्वारा सिफारिस गरिएको
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr={title} को लागि सन्दर्भ मेनु खोल्नुहोस्
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=खण्ड सन्दर्भ मेनु खोल्नुहोस्
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=भ्रमण गरिएको
+type_label_bookmarked=पुस्तकचिनो लागाइएको
+type_label_recommended=प्रचलनमा
+type_label_pocket=Pocket मा सङ्ग्रह गरियो
+type_label_downloaded=डाउनलोड भयो
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=पुस्तकचिनो
+menu_action_remove_bookmark=पुस्तकचिनो हटाउनुहोस्
+menu_action_open_new_window=नयाँ सञ्झ्यालमा खोल्नुहोस्
+menu_action_open_private_window=नयाँ निजी सञ्झ्यालमा खोल्नुहोस्
+menu_action_dismiss=खारेज गर्नुहोस्
+menu_action_delete=इतिहासबाट मेट्नुहोस्
+menu_action_pin=पिन गर्नुहोस्
+menu_action_unpin=अन पिन गर्नुहोस्
+confirm_history_delete_p1=के तपाईं पक्का हुनुहुन्छ कि तपाइँ यस पृष्ठको हरेक उदाहरण तपाइँको इतिहासबाट हटाउन चाहनुहुन्छ ?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=यो कार्य पूर्ववत गर्न सकिँदैन ।
+menu_action_save_to_pocket=Pocketमा बचत गर्नुहोस्
+menu_action_delete_pocket=Pocket बाट मेट्नुहोस्
+menu_action_archive_pocket=Pocket मा संग्रह गर्नुहोस्
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Finder मा देखाउनुहोस्
+menu_action_show_file_windows=समाविष्ट भएको फोल्डर खोल्नुहोस्
+menu_action_show_file_linux=समाविष्ट भएको फोल्डर खोल्नुहोस्
+menu_action_show_file_default=फाइल देखाउनुहोस्
+menu_action_open_file=फाइल खोल्नुहोस्
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=डाउनलोड लिङ्क प्रतिलिपि गर्नुहोस्
+menu_action_go_to_download_page=डाउनलोड पेजमा जानुहोस्
+menu_action_remove_download=इतिहासबाट हटाउनुहोस्
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=खोजी गर्नुहोस्
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} खोजी
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=वेबमा खोज्नुहोस्
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=वेबमा सबैभन्दा रोचक कथाहरू, तपाईंले पढ्नु भएको आधारमा Pocket बाट चयन गर्नुभएको छ।
+section_disclaimer_topstories_linktext=कसरी काम गर्छ हेर्नुहोस्।
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=बुझेँ
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox गृह सामग्री
+prefs_home_description=तपाईंको Firefox गृह पृष्ठमा तपाईँ कुन सामग्री राख्न चाहनुहुन्छ छान्नुहोस् ।
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} पक्ति;{num} पक्ति
+prefs_search_header=वेब खोजि
+prefs_topsites_description=तपाईंले धेरै भ्रमण गर्नुभएका साइटहरू
+prefs_topstories_description2=वेब वरिपरिका राम्रा सामग्रीहरु, तपाईंको लागि निजीकृत गरिएको
+prefs_topstories_options_sponsored_label=प्रायोजित गरिएको कथाहरू
+prefs_topstories_sponsored_learn_more=अझ जान्नुहोस्
+prefs_highlights_description=तपाईंले सुरक्षित गर्नुभएको वा भ्रमण गर्नुभएको साइटहरू
+prefs_highlights_options_visited_label=भ्रमण गरिएका पृष्ठहरू
+prefs_highlights_options_download_label=सबैभन्दा नयाँ डाउनलोड
+prefs_highlights_options_pocket_label=Pocket मा सङ्ग्रह गरिएका पृष्ठहरू
+prefs_snippets_description=Mozilla र Firefox का अद्यावधिकहरू
+settings_pane_button_label=तपाईंको नयाँ ट्याब पृष्ठ अनुकूलन गर्नुहोस्
+settings_pane_topsites_header=शीर्ष साइटहरू
+settings_pane_highlights_header=विशेषताहरू
+settings_pane_highlights_options_bookmarks=पुस्तकचिनोहरू
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=स्निप्पेटस्
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=सम्पादन गर्नुहोस्
+edit_topsites_edit_button=यस साइटलाई सम्पादन गर्नुहोस्
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=नयाँ शीर्ष साइट
+topsites_form_edit_header=शीर्ष साइट सम्पादन गर्नुहोस्
+topsites_form_title_label=शीर्षक
+topsites_form_title_placeholder=शीर्षक प्रविष्ट गर्नुहोस्
+topsites_form_url_label=URL
+topsites_form_image_url_label=अनुकूल तस्बिर URL
+topsites_form_url_placeholder=URL लेख्नुहोस् 
+topsites_form_use_image_link=अनुकूल तस्बिर प्रयोग गर्नुहोस्…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=पूर्ववलोकन
+topsites_form_add_button=थप्नुहोस्
+topsites_form_save_button=सङ्ग्रह गर्नुहोस्
+topsites_form_cancel_button=रद्द गर्नुहोस्
+topsites_form_url_validation=मान्य URL चाहिन्छ
+topsites_form_image_validation=तस्बिर लोड गर्न असफल भयो । फरक URL प्रयास गर्नुहोस् ।
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=लोकप्रिय शीर्षकहरू:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=अरू कथा देखाउनुहोस्
+
+highlights_empty_state=ब्राउज गर्न सुरू गर्नुहोस्, र हामी केहि उत्कृष्ट लेखहरू, भिडियोहरू, र अन्य पृष्ठहरू जुन तपाईंले भर्खरै भ्रमण गर्नुभएको वा पुस्तकचिनो राख्नुभएको छ यहाँ देखाउँछौ ।
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=अहिले यति नै । {provider} बाट थप शीर्ष कथाहरूको हेर्नका लागि पछि फेरि जाँच गर्नुहोस् । अाफुलाई रोक्न सक्नुहुदैन ? वेबभरिका राम्रा कथाहरु भेटाउन कुनै एउटा लोकप्रिय विषय छान्नुहोस् । 
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=अन्य ब्राउजरका पुस्तकचिनोहरु, इतिहास र गोप्यशब्दहरु सहित Firefox प्रयोग गर्नुहोस् ।
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=पर्दैन, धन्यबाद
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=अहिले आयात गर्नुहोस्
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=उफ्, सामाग्री लोड गर्न खोजदा केहि गलत भयो ।
+error_fallback_default_refresh_suggestion=पुनः प्रयास गर्न पृष्ठ ताजा गर्नुहोस् ।
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=खण्ड हटाउनुहोस्
+section_menu_action_collapse_section=खण्ड संक्षिप्त गर्नुहोस्
+section_menu_action_expand_section=खण्ड विस्तार गर्नुहोस्
+section_menu_action_manage_section=खण्ड प्रबन्ध गर्नुहोस्
+section_menu_action_add_topsite=शीर्ष साइट थप्नुहोस्
+section_menu_action_move_up=माथि सार्नुहोस्
+section_menu_action_move_down=तल सार्नुहोस्
+section_menu_action_privacy_notice=गोपनीयता नीति
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/nl/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Nieuw tabblad
+
+header_top_sites=Topwebsites
+header_highlights=Highlights
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Aanbevolen door {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Contextmenu openen voor {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Contextmenu van sectie openen
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Bezocht
+type_label_bookmarked=Bladwijzer gemaakt
+type_label_recommended=Trending
+type_label_pocket=Opgeslagen naar Pocket
+type_label_downloaded=Gedownload
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Bladwijzer maken
+menu_action_remove_bookmark=Bladwijzer verwijderen
+menu_action_open_new_window=Openen in een nieuw venster
+menu_action_open_private_window=Openen in een nieuw privévenster
+menu_action_dismiss=Verwijderen
+menu_action_delete=Verwijderen uit geschiedenis
+menu_action_pin=Vastmaken
+menu_action_unpin=Losmaken
+confirm_history_delete_p1=Weet u zeker dat u alle exemplaren van deze pagina uit uw geschiedenis wilt verwijderen?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Deze actie kan niet ongedaan worden gemaakt.
+menu_action_save_to_pocket=Opslaan naar Pocket
+menu_action_delete_pocket=Verwijderen uit Pocket
+menu_action_archive_pocket=Archiveren in Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Tonen in Finder
+menu_action_show_file_windows=Bijbehorende map openen
+menu_action_show_file_linux=Bijbehorende map openen
+menu_action_show_file_default=Bestand tonen
+menu_action_open_file=Bestand openen
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Downloadkoppeling kopiëren
+menu_action_go_to_download_page=Naar downloadpagina gaan
+menu_action_remove_download=Verwijderen uit geschiedenis
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Zoeken
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} doorzoeken
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Zoeken op het web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=De meest interessante verhalen op het web, geselecteerd op basis van wat u hebt gelezen. Van Pocket, nu onderdeel van Mozilla.
+section_disclaimer_topstories_linktext=Lees hoe het werkt.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Oké, begrepen
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Inhoud van Firefox-startpagina
+prefs_home_description=Kies welke inhoud u op uw Firefox-startscherm wilt laten weergeven.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} rij;{num} rijen
+prefs_search_header=Zoeken op het web
+prefs_topsites_description=De websites die u het vaakst bezoekt
+prefs_topstories_description2=Geweldige inhoud van het web, gepersonaliseerd voor u
+prefs_topstories_options_sponsored_label=Gesponsorde verhalen
+prefs_topstories_sponsored_learn_more=Meer info
+prefs_highlights_description=Een selectie van websites die u hebt opgeslagen of bezocht
+prefs_highlights_options_visited_label=Bezochte pagina’s
+prefs_highlights_options_download_label=Meest recent gedownload
+prefs_highlights_options_pocket_label=Naar Pocket opgeslagen pagina’s
+prefs_snippets_description=Updates van Mozilla en Firefox
+settings_pane_button_label=Uw Nieuw-tabbladpagina aanpassen
+settings_pane_topsites_header=Topwebsites
+settings_pane_highlights_header=Highlights
+settings_pane_highlights_options_bookmarks=Bladwijzers
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Snippets
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Bewerken
+edit_topsites_edit_button=Deze website bewerken
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nieuwe topwebsite
+topsites_form_edit_header=Topwebsite bewerken
+topsites_form_title_label=Titel
+topsites_form_title_placeholder=Voer een titel in
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL van aangepaste afbeelding
+topsites_form_url_placeholder=Typ of plak een URL
+topsites_form_use_image_link=Een aangepaste afbeelding gebruiken…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Voorbeeld
+topsites_form_add_button=Toevoegen
+topsites_form_save_button=Opslaan
+topsites_form_cancel_button=Annuleren
+topsites_form_url_validation=Geldige URL vereist
+topsites_form_image_validation=Afbeelding kon niet worden geladen. Probeer een andere URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Populaire onderwerpen:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Meer verhalen bekijken
+
+highlights_empty_state=Begin met surfen, en we tonen hier een aantal geweldige artikelen, video’s en andere pagina’s die u onlangs hebt bezocht of waarvoor u een bladwijzer hebt gemaakt.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=U bent weer bij. Kijk later nog eens voor meer topverhalen van {provider}. Kunt u niet wachten? Selecteer een populair onderwerp voor meer geweldige verhalen van het hele web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Probeer Firefox met de bladwijzers, geschiedenis en wachtwoorden van een andere browser.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Nee bedankt
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Nu importeren
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Oeps, er is iets misgegaan bij het laden van deze inhoud.
+error_fallback_default_refresh_suggestion=Vernieuw de pagina om het opnieuw te proberen.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Sectie verwijderen
+section_menu_action_collapse_section=Sectie samenvouwen
+section_menu_action_expand_section=Sectie uitvouwen
+section_menu_action_manage_section=Sectie beheren
+section_menu_action_manage_webext=Extensie beheren
+section_menu_action_add_topsite=Topwebsite toevoegen
+section_menu_action_move_up=Omhoog verplaatsen
+section_menu_action_move_down=Omlaag verplaatsen
+section_menu_action_privacy_notice=Privacyverklaring
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Neem Firefox met u mee
+firstrun_content=Bereik uw bladwijzers, geschiedenis, wachtwoorden en andere instellingen op al uw apparaten.
+firstrun_learn_more_link=Meer info over Firefox Accounts
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Voer uw e-mailadres in
+firstrun_form_sub_header=om door te gaan naar Firefox Sync.
+
+firstrun_email_input_placeholder=E-mailadres
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Door verder te gaan, gaat u akkoord met de {terms} en {privacy}.
+firstrun_terms_of_service=Servicevoorwaarden
+firstrun_privacy_notice=Privacyverklaring
+
+firstrun_continue_to_login=Doorgaan
+firstrun_skip_login=Deze stap overslaan
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/nn-NO/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Ny fane
+
+header_top_sites=Mest besøkte nettsider
+header_highlights=Høgdepunkt
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Tilrådd av {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Opne kontekstmeny for {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Opne seksjonens kontekstmeny
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Besøkt
+type_label_bookmarked=Bokmerkte
+type_label_recommended=Trendar
+type_label_pocket=Lagra til Pocket
+type_label_downloaded=Nedlasta
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Bokmerke
+menu_action_remove_bookmark=Fjern bokmerke
+menu_action_open_new_window=Opne i nytt vindauge
+menu_action_open_private_window=Opne i eit nytt privat vindauge
+menu_action_dismiss=Avvis
+menu_action_delete=Slett frå historikk
+menu_action_pin=Fest
+menu_action_unpin=L:ys
+confirm_history_delete_p1=Er du sikker på at du vil slette alle førekomstar av denne sida frå historikken din?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Denne handlinga kan ikkje angrast.
+menu_action_save_to_pocket=Lagre til Pocket
+menu_action_delete_pocket=Slett frå Pocket
+menu_action_archive_pocket=Arkiver i Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Vis i Finder
+menu_action_show_file_windows=Opne mappa med fila
+menu_action_show_file_linux=Opne mappa med fila
+menu_action_show_file_default=Vis fil
+menu_action_open_file=Opne fil
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Kopier nedlastingslenke
+menu_action_go_to_download_page=Gå til nedlastingsside
+menu_action_remove_download=Fjern frå historikk
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Søk
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Søk på nettet
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Dei mest interessante historiane på nettet, utvalde basert på kva du les. Frå Pocket, no ein del av Mozilla.
+section_disclaimer_topstories_linktext=Sjå korleis det fungerer.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=OK, eg forstår det!
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Innhald Firefox-startside
+prefs_home_description=Vel kva for innhald du vil ha på Firefox-startsida di.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} rekke;{num} rekkjer
+prefs_search_header=Nettsøk
+prefs_topsites_description=Sidene du besøker mest
+prefs_topstories_description2=Bra innhald frå heile nettet, tilpassa for deg
+prefs_topstories_options_sponsored_label=Sponsa historiar
+prefs_topstories_sponsored_learn_more=Les meir
+prefs_highlights_description=Eit utval av nettsider som du har lagra eller besøkt
+prefs_highlights_options_visited_label=Besøkte sider
+prefs_highlights_options_download_label=Siste nedlasting
+prefs_highlights_options_pocket_label=Sider lagra til Pocket
+prefs_snippets_description=Oppdateringar frå Mozilla og Firefox
+settings_pane_button_label=Tilpass sida for Ny fane
+settings_pane_topsites_header=Mest besøkte
+settings_pane_highlights_header=Høgdepunkt
+settings_pane_highlights_options_bookmarks=Bokmerke
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Snuttar
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Rediger
+edit_topsites_edit_button=Rediger denne nettsida
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Ny Mest besøkt
+topsites_form_edit_header=Rediger Mest besøkt
+topsites_form_title_label=Tittel
+topsites_form_title_placeholder=Skriv inn ein tittel
+topsites_form_url_label=URL
+topsites_form_image_url_label=Tilpassa bilde-URL
+topsites_form_url_placeholder=Skriv eller lim inn ein URL
+topsites_form_use_image_link=Bruk eit tilpassa bilde…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Førehandsvis
+topsites_form_add_button=Legg til
+topsites_form_save_button=Lagre
+topsites_form_cancel_button=Avbryt
+topsites_form_url_validation=Gyldig URL er påkravd
+topsites_form_image_validation=Klarte ikkje å lesa bildet. Prøv ein annan URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Populære emne:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Vis fleire saker
+
+highlights_empty_state=Begynn å surfe, og vi vil vise deg nokre av dei beste artiklane, videoane og andre sider du nyleg har besøkt eller bokmerka her.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Det finst ikkje fleire. Kom tilbake seinare for fleire topphistoriar frå {provider}. Kan du ikkje vente? Vel eit populært emne for å finne fleire gode artiklar frå heile nettet.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Prøv Firefox med bokmerka, historikk og passord frå ein annan nettlesar.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Nei takk
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importer no
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ops, noko gjekk gale då innhaldet skulle lastast inn.
+error_fallback_default_refresh_suggestion=Oppdater sida for å prøve på nytt.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Fjern seksjon
+section_menu_action_collapse_section=Slå saman seksjon
+section_menu_action_expand_section=Utvid seksjon
+section_menu_action_manage_section=Handter seksjon
+section_menu_action_manage_webext=Handter utviding
+section_menu_action_add_topsite=Legg til mest besøkte
+section_menu_action_move_up=Flytt opp
+section_menu_action_move_down=Flytt ned
+section_menu_action_privacy_notice=Personvernmerknad
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Ta med deg Firefox
+firstrun_content=Få bokmerke, historikk, passord, og andre innstillingar på alle einingane dine.
+firstrun_learn_more_link=Les meir om Firefox-kontoen
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Skriv inn e-postadressa di
+firstrun_form_sub_header=for å fortsetje til Firefox Sync.
+
+firstrun_email_input_placeholder=E-post
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Ved å fortsetje, godtek du {terms} og {privacy}.
+firstrun_terms_of_service=Tenestevilkår
+firstrun_privacy_notice=Personvernpraksis
+
+firstrun_continue_to_login=Fortset
+firstrun_skip_login=Hopp over dette steget
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/oc/strings.properties
@@ -0,0 +1,118 @@
+newtab_page_title=Onglet novèl
+
+header_top_sites=Sites favorits
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visitat
+type_label_bookmarked=Apondut als marcapaginas
+type_label_recommended=Tendéncia
+type_label_pocket=Pagina enregistrada dins Pocket
+type_label_downloaded=Telecargat
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Marcar aquesta pagina
+menu_action_remove_bookmark=Suprimir lo marcapagina
+menu_action_open_new_window=Dobrir lo ligam dins una fenèstra novèla
+menu_action_open_private_window=Dobrir lo ligam dins una fenèstra de navegacion privada
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_default=Mostrar lo fichièr
+menu_action_open_file=Dobrir lo fichièr
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_remove_download=Tirar de l’istoric
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Recercar
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Recèrca sul web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories_linktext=Vejatz cossí fonciona.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Comprés
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/pa-IN/strings.properties
@@ -0,0 +1,186 @@
+newtab_page_title=ਨਵੀਂ ਟੈਬ
+
+header_top_sites=ਸਿਖਰਲੀਆਂ ਸਾਈਟਾਂ
+header_highlights=ਸੁਰਖੀਆਂ
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} ਵਲੋਂ ਸਿਫਾਰਸ਼ੀ
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr={title} ਦੇ ਲਈ ਪ੍ਰਸੰਗ ਮੀਨੂੰ ਖ੍ਹੋਲੋ
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=ਪ੍ਰਸੰਗ ਮੀਨੂੰ ਚੋਣ ਖ੍ਹੋਲੋ
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=ਖੋਲ੍ਹੀਆਂ
+type_label_bookmarked=ਬੁੱਕਮਾਰਕ ਕੀਤੀਆਂ
+type_label_recommended=ਪ੍ਰਚਲਿਤ
+type_label_pocket=Pocket ਵਿੱਚ ਸੰਭਾਲਿਆ ਗਿਆ
+type_label_downloaded=ਡਾਊਨਲੋਡ ਕਰੋ
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=ਬੁੱਕਮਾਰਕ
+menu_action_remove_bookmark=ਬੁੱਕਮਾਰਕ ਨੂੰ ਹਟਾਓ
+menu_action_open_new_window=ਨਵੀਂ ਵਿੰਡੋ ਵਿੱਚ ਖੋਲ੍ਹੋ
+menu_action_open_private_window=ਨਵੀਂ ਪ੍ਰਾਈਵੇਟ ਵਿੰਡੋ ਵਿੱਚ ਖੋਲ੍ਹੋ
+menu_action_dismiss=ਰੱਦ ਕਰੋ
+menu_action_delete=ਅਤੀਤ ਵਿੱਚੋਂ ਹਟਾਓ
+menu_action_pin=ਟੰਗੋ
+menu_action_unpin=ਅਨਪਿੰਨ ਕਰੋ
+confirm_history_delete_p1=ਕੀ ਤੁਸੀਂ ਯਕੀਨੀ ਤੌਰ 'ਤੇ ਆਪਣੇ ਅਤੀਤ ਵਿੱਚ ਇਸ ਪੰਨੇ ਦੀ ਹਰੇਕ ਉਦਾਹਰਨ ਨੂੰ ਮਿਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=ਇਕ ਕਾਰਵਾਈ ਨੂੰ ਅਣਕੀਤਾ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।
+menu_action_save_to_pocket=Pocket ਵਿੱਚ ਸੰਭਾਲੋ
+menu_action_delete_pocket=Pocket ਤੋਂ ਮਿਟਾਓ
+menu_action_archive_pocket=Pocket ਵਿੱਚ ਪੁਰਾਲੇਖਬੱਧ ਕਰੋ
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=ਫਾਈਡਰ ਵਿੱਚ ਵੇਖੋ
+menu_action_show_file_windows=ਸ਼ਾਮਲ ਫੋਲਡਰ ਖੋਲ੍ਹੋ
+menu_action_show_file_linux=ਸ਼ਾਮਲ ਕੀਤੇ ਫੋਲਡਰ ਖੋਲ੍ਹੋ
+menu_action_show_file_default=ਫਾਈਲ ਵੇਖਾਓ
+menu_action_open_file=ਫਾਈਲ ਖੋਲ੍ਹੋ
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=ਡਾਊਨਲੋਡ ਲਿੰਕ ਕਾਪੀ ਕਰੋ
+menu_action_go_to_download_page=ਡਾਊਨਲੋਡ ਪੰਨੇ 'ਤੇ ਜਾਓ
+menu_action_remove_download=ਅਤੀਤ ਤੋਂ ਹਟਾਓ
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=ਖੋਜ
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} ਖੋਜ
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=ਵੈੱਬ ਨੂੰ ਖੋਜੋ
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories_linktext=ਜਾਣੋ ਕਿ ਇਹ ਕਿਵੇਂ ਕੰਮ ਕਰਦਾ ਹੈ।
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=ਠੀਕ ਹੈ, ਸਮਝ ਲਿਆ
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=ਫਾਇਰਫਾਕਸ ਮੁੱਖ ਪੰਨਾ
+prefs_home_description=ਉਹ ਸਮੱਗਰੀ ਚੁਣੋ ਜੋ ਤੁਸੀਂ ਆਪਣੇ ਫਾਇਰਫਾਕਸ ਮੁੱਖ ਪੰਨੇ 'ਤੇ ਚਾਹੁੰਦੇ ਹੋ।
+prefs_restore_defaults_button=ਡਿਫੌਲਟ 'ਤੇ ਰੀਸਟੋਰ ਕਰੋ
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} ਕਤਾਰ;{num} ਕਤਾਰਾਂ
+prefs_search_header=ਵੈੱਬ ਖੋਜ
+prefs_topsites_description=ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਭ ਤੋਂ ਵੱਧ ਵੇਖੀਆਂ ਸਾਈਟਾਂ
+prefs_topstories_description2=ਸਮੁੱਚੇ ਵੈੱਬ ਤੋਂ ਸ਼ਾਨਦਾਰ ਸਮੱਗਰੀ, ਤੁਹਾਡੇ ਲਈ ਵਿਅਕਤੀਗਤ ਹੈ
+prefs_topstories_options_sponsored_label=ਪ੍ਰਾਯੋਜਿਤ ਕਹਾਣੀਆਂ
+prefs_topstories_sponsored_learn_more=ਹੋਰ ਜਾਣੋ
+prefs_highlights_description=ਉਹਨਾਂ ਸਾਈਟਾਂ ਦੀ ਚੋਣ ਕਰੋ ਜੋ ਤੁਸੀਂ ਸੁਰੱਖਿਅਤ ਜਾਂ ਵਿਜ਼ਿਟ ਕੀਤੀ ਹੈ
+prefs_highlights_options_visited_label=ਵੇਖੇ ਗਏ ਸਫੇ
+prefs_highlights_options_download_label=ਸਭ ਤੋਂ ਤਾਜ਼ਾ ਕੀਤੇ ਡਾਊਨਲੋਡ
+prefs_highlights_options_pocket_label=ਪੰਨਿਆਂ ਨੂੰ ਪਾਕੈਟ ਵਿੱਚ ਸੁਰੱਖਿਅਤ ਕੀਤਾ ਗਿਆ ਹੈ
+prefs_snippets_description=ਮੋਜ਼ੀਲਾ ਅਤੇ ਫਾਇਰਫਾਕਸ ਤੋਂ ਅੱਪਡੇਟ
+settings_pane_button_label=ਆਪਣੇ ਨਵੀਂ ਟੈਬ ਸਫ਼ੇ ਨੂੰ ਆਪਣੇ ਮੁਤਾਬਕ ਢਾਲੋ
+settings_pane_header=ਨਵੀਂ ਟੈਬ ਲਈ ਪਸੰਦਾਂ
+settings_pane_body2=ਚੁਣੋ ਕਿ ਤੁਸੀਂ ਇਸ ਸਫ਼ੇ ਤੇ ਕੀ ਦੇਖਿਆ।
+settings_pane_search_header=ਖੋਜੋ
+settings_pane_search_body=ਆਪਣੀ ਨਵੀਂ ਟੈਬ ਤੋਂ ਵੈੱਬ ਨੂੰ ਖੋਜੋ।
+settings_pane_topsites_header=ਸਿਖਰਲੀਆਂ ਸਾਈਟਾਂ
+settings_pane_topsites_body=ਵੈੱਬਸਾਈਟਾਂ, ਜਿਹਨਾਂ ਨੂੰ ਤੁਸੀਂ ਸਭ ਤੋਂ ਵੱਧ ਖੋਲ੍ਹਿਆ ਹੈ, ਲਈ ਪਹੁੰਚ।
+settings_pane_topsites_options_showmore=ਦੋ ਕਤਾਰਾਂ ਵੇਖਾਓ
+settings_pane_highlights_header=ਹਾਈਲਾਈਟ
+settings_pane_highlights_body2=ਜਿਹੜੀਆਂ ਦਿਲਚਸਪ ਚੀਜ਼ਾਂ ਤੁਸੀਂ ਹਾਲ ਹੀ ਵਿੱਚ ਦੇਖੀਆਂ ਹਨ ਜਾਂ ਬੁੱਕਮਾਰਕ ਕੀਤੀਆਂ ਹਨ, ਬਾਰੇ ਆਪਣਾ ਵਾਪਸੀ ਰਸਤਾ ਲੱਭੋ।
+settings_pane_highlights_options_bookmarks=ਬੁੱਕਮਾਰਕ
+settings_pane_highlights_options_visited=ਦੇਖੀਆਂ ਗਈਆਂ ਸਾਈਟਾਂ
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=ਛੋਟੇ ਟੋਟੇ
+settings_pane_done_button=ਮੁਕੰਮਲ
+settings_pane_topstories_options_sponsored=ਸਪਾਂਸਰ ਕੀਤੀਆਂ ਕਹਾਣੀਆਂ ਵੇਖਾਓ
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=ਸੋਧੋ
+edit_topsites_edit_button=ਇਹ ਸਾਈਟ ਨੂੰ ਸੋਧੋ
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=ਨਵੀਂ ਉਪਰਲੀ ਸਾਈਟ
+topsites_form_edit_header=ਉਪਰਲੀ ਸਾਈਟ ਸੋਧੋ
+topsites_form_title_label=ਸਿਰਲੇਖ
+topsites_form_title_placeholder=ਸਿਰਲੇਖ ਦਾਖਲ ਕਰੋ
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL ਕਸਟਮ ਚਿੱਤਰ
+topsites_form_url_placeholder=ਕੋਈ URL ਲਿਖੋ ਜਾਂ ਚੇਪੋ
+topsites_form_use_image_link=ਇੱਕ ਕਸਟਮ ਚਿੱਤਰ ਵਰਤੋ…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=ਪੂਰਵ ਦਰਸ਼ਨ
+topsites_form_add_button=ਜੋੜੋ
+topsites_form_save_button=ਸੰਭਾਲੋ
+topsites_form_cancel_button=ਰੱਦ ਕਰੋ
+topsites_form_url_validation=ਲੋੜੀਂਦਾ URL ਯੋਗ ਹੈ
+topsites_form_image_validation=ਚਿੱਤਰ ਲੋਡ ਕਰਨ ਤੋਂ ਅਸਫ਼ਲ ਰਿਹਾ। ਕਿਸੇ ਵੱਖਰੇ URL ਨਾਲ ਕੋਸ਼ਿਸ਼ ਕਰੋ।
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=ਪ੍ਰਸਿੱਧ ਵਿਸ਼ੇ:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=ਹੋਰ ਕਹਾਣੀਆਂ ਵੇਖੋ
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=ਨਹੀਂ, ਧੰਨਵਾਦ
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=ਹੁਣੇ ਇੰਪੋਰਟ ਕਰੋ
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=ਓਹ ਹੋ, ਇਸ ਸਮੱਗਰੀ ਨੂੰ ਲੋਡ ਕਰਨ ਵਿੱਚ ਕੁਝ ਗਲਤ ਹੋ ਗਿਆ।
+error_fallback_default_refresh_suggestion=ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਨ ਲਈ ਪੰਨਾ ਤਾਜ਼ਾ ਕਰੋ।
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=ਸੈਕਸ਼ਨ ਹਟਾਓ
+section_menu_action_collapse_section=ਸੈਕਸ਼ਨ ਨੂੰ ਸਮੇਟੋ
+section_menu_action_expand_section=ਸੈਕਸ਼ਨ ਦੀ ਫੈਲਾਓ
+section_menu_action_manage_section=ਸੈਕਸ਼ਨ ਦਾ ਪ੍ਰਬੰਧ ਕਰੋ
+section_menu_action_add_topsite=ਚੋਟੀ ਦੀਆਂ ਸਾਈਟਾਂ ਜੋੜੋ
+section_menu_action_move_up=ਉੱਤੇ ਭੇਜੋ
+section_menu_action_move_down=ਹੇਠਾਂ ਭੇਜੋ
+section_menu_action_privacy_notice=ਨਿੱਜੀ ਨੋਟਿਸ
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/pl/strings.properties
@@ -0,0 +1,116 @@
+newtab_page_title=Nowa karta
+header_top_sites=Popularne
+header_highlights=Wyróżnione
+header_recommended_by=Polecane przez {provider}
+context_menu_button_sr=Otwórz menu kontekstowe „{title}”
+section_context_menu_button_sr=Otwórz menu kontekstowe sekcji
+type_label_visited=Z odwiedzonych
+type_label_bookmarked=Z zakładek
+type_label_recommended=Na czasie
+type_label_pocket=Z Pocket
+type_label_downloaded=Z pobranych
+menu_action_bookmark=Dodaj zakładkę
+menu_action_remove_bookmark=Usuń zakładkę
+menu_action_open_new_window=Otwórz w nowym oknie
+menu_action_open_private_window=Otwórz w nowym oknie prywatnym
+menu_action_dismiss=Usuń z tej sekcji
+menu_action_delete=Usuń z historii
+menu_action_pin=Przypnij
+menu_action_unpin=Odepnij
+confirm_history_delete_p1=Czy na pewno usunąć wszystkie wizyty na tej stronie z historii?
+confirm_history_delete_notice_p2=Tej czynności nie można cofnąć.
+menu_action_save_to_pocket=Zachowaj w Pocket
+menu_action_delete_pocket=Usuń z Pocket
+menu_action_archive_pocket=Archiwizuj w Pocket
+menu_action_show_file_mac_os=Pokaż w Finderze
+menu_action_show_file_windows=Otwórz folder nadrzędny
+menu_action_show_file_linux=Otwórz folder nadrzędny
+menu_action_show_file_default=Wyświetl plik
+menu_action_open_file=Otwórz plik
+menu_action_copy_download_link=Kopiuj adres, z którego pobrano plik
+menu_action_go_to_download_page=Przejdź do strony pobierania
+menu_action_remove_download=Usuń z historii
+search_button=Szukaj
+search_header=Wyszukiwanie z „{search_engine_name}”
+search_web_placeholder=Szukaj w Internecie
+section_disclaimer_topstories=Najciekawsze artykuły w Internecie, wybierane na podstawie tego co czytasz. Od serwisu Pocket, będącego teraz częścią Mozilli.
+section_disclaimer_topstories_linktext=Zobacz, jak to działa
+section_disclaimer_topstories_buttontext=OK
+prefs_home_header=Strona startowa
+prefs_home_description=Wybierz, jakie treści mają być wyświetlane na stronie startowej.
+prefs_restore_defaults_button=Przywróć domyślne
+prefs_section_rows_option={num} wiersz;{num} wiersze;{num} wierszy
+prefs_search_header=Pasek wyszukiwania
+prefs_topsites_description=Popularne odwiedzane strony
+prefs_topstories_description2=Świetne rzeczy z całego Internetu, personalizowane specjalnie dla Ciebie
+prefs_topstories_options_sponsored_label=Sponsorowane treści
+prefs_topstories_sponsored_learn_more=Więcej informacji
+prefs_highlights_description=Wybierane z zachowanych i odwiedzonych stron.
+prefs_highlights_options_visited_label=Historia
+prefs_highlights_options_download_label=Ostatnio pobrane pliki
+prefs_highlights_options_pocket_label=Zachowane w Pocket
+prefs_snippets_description=Informacje od Mozilli i Firefoksa.
+settings_pane_button_label=Dostosuj stronę nowej karty
+settings_pane_header=Ustawienia nowej karty
+settings_pane_body2=Wybierz, co wyświetlać na tej stronie
+settings_pane_search_header=Wyszukiwanie w Internecie
+settings_pane_search_body=Pasek wyszukiwania na stronie nowej karty.
+settings_pane_topsites_header=Popularne
+settings_pane_topsites_body=Dostęp do najczęściej odwiedzanych stron.
+settings_pane_topsites_options_showmore=Dwa wiersze
+settings_pane_highlights_header=Wyróżniane
+settings_pane_highlights_body2=Szybki dostęp do niedawno odwiedzonych stron i dodanych zakładek.
+settings_pane_highlights_options_bookmarks=Zakładki
+settings_pane_highlights_options_visited=Odwiedzone strony
+settings_pane_snippets_header=Od Mozilli
+settings_pane_snippets_body=Krótkie i słodkie informacje od Mozilli o Firefoksie i kulturze internetowej, a od czasu do czasu także jakiś żart.
+settings_pane_done_button=Gotowe
+settings_pane_topstories_options_sponsored=Sponsorowane treści
+edit_topsites_button_text=Edytuj
+edit_topsites_edit_button=Edytuj stronę
+topsites_form_add_header=Dodawanie strony do sekcji Popularne
+topsites_form_edit_header=Edycja strony z sekcji Popularne
+topsites_form_title_label=Tytuł
+topsites_form_title_placeholder=Tytuł strony
+topsites_form_url_label=Adres URL
+topsites_form_image_url_label=Własny obraz
+topsites_form_url_placeholder=Adres strony
+topsites_form_use_image_link=Użyj własnego obrazu…
+topsites_form_preview_button=Podgląd
+topsites_form_add_button=Dodaj
+topsites_form_save_button=Zachowaj
+topsites_form_cancel_button=Anuluj
+topsites_form_url_validation=Wymagany jest prawidłowy adres URL
+topsites_form_image_validation=Wczytanie obrazu nie powiodło się. Spróbuj innego adresu.
+pocket_read_more=Popularne treści:
+pocket_read_even_more=Pokaż więcej artykułów
+pocket_description=Odkrywaj wysokiej jakości treści dzięki serwisowi Pocket, który jest teraz częścią Mozilli.
+highlights_empty_state=Zacznij przeglądać Internet, a pojawią się tutaj świetne artykuły, filmy oraz inne ostatnio odwiedzane strony i dodane zakładki.
+topstories_empty_state=To na razie wszystko. {provider} później będzie mieć więcej popularnych artykułów. Nie możesz się doczekać? Wybierz popularny temat, aby znaleźć więcej treści z całego Internetu.
+manual_migration_explanation2=Wypróbuj program Firefox z zakładkami, historią i hasłami z innej przeglądarki.
+manual_migration_cancel_button=Anuluj
+manual_migration_import_button=Importuj
+error_fallback_default_info=Coś się nie powiodło podczas wczytywania tej treści
+error_fallback_default_refresh_suggestion=Odśwież stronę, by spróbować ponownie
+
+section_menu_action_remove_section=Usuń sekcję
+section_menu_action_collapse_section=Zwiń sekcję
+section_menu_action_expand_section=Rozwiń sekcję
+section_menu_action_manage_section=Zarządzaj sekcją
+section_menu_action_manage_webext=Zarządzaj rozszerzeniem
+section_menu_action_add_topsite=Dodaj stronę do popularnych
+section_menu_action_move_up=Przesuń w górę
+section_menu_action_move_down=Przesuń w dół
+section_menu_action_privacy_notice=Uwagi dotyczące prywatności
+
+firstrun_title=Zabierz swoje dane ze sobą
+firstrun_content=Zakładki, historia, hasła i inne ustawienia mogą być dostępne i synchronizowane na wszystkich urządzeniach.
+firstrun_learn_more_link=Więcej informacji
+firstrun_form_header=Wprowadź adres e-mail
+firstrun_form_sub_header=, aby skorzystać z Firefox Sync.
+firstrun_email_input_placeholder=E-mail
+firstrun_extra_legal_links=Kontynuując, akceptujesz {terms} i {privacy}.
+firstrun_terms_of_service=warunki korzystania z usługi
+firstrun_privacy_notice=uwagi dotyczące prywatności
+firstrun_continue_to_login=Kontynuuj
+firstrun_skip_login=Pomiń
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/pt-BR/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Nova aba
+
+header_top_sites=Sites preferidos
+header_highlights=Destaques
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recomendado por {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Abrir menu de contexto para {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Abrir o menu de contexto da seção
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visitado
+type_label_bookmarked=Adicionado aos favoritos
+type_label_recommended=Tendência
+type_label_pocket=Salvo no Pocket
+type_label_downloaded=Baixado
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Adicionar aos favoritos
+menu_action_remove_bookmark=Remover favorito
+menu_action_open_new_window=Abrir em uma nova janela
+menu_action_open_private_window=Abrir em uma nova janela privativa
+menu_action_dismiss=Dispensar
+menu_action_delete=Excluir do histórico
+menu_action_pin=Fixar
+menu_action_unpin=Desafixar
+confirm_history_delete_p1=Você tem certeza que deseja excluir todas as instâncias desta página do seu histórico?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Essa ação não pode ser desfeita.
+menu_action_save_to_pocket=Salvar no Pocket
+menu_action_delete_pocket=Excluir do Pocket
+menu_action_archive_pocket=Arquivar no Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Mostrar no Finder
+menu_action_show_file_windows=Abrir pasta
+menu_action_show_file_linux=Abrir pasta
+menu_action_show_file_default=Mostrar arquivo
+menu_action_open_file=Abrir arquivo
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Copiar link do download
+menu_action_go_to_download_page=Abrir página de download
+menu_action_remove_download=Remover do histórico
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Pesquisar
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Pesquisa {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Pesquisar na Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=As histórias mais interessantes na web, selecionadas baseadas no que você lê. Do Pocket, agora parte da Mozilla.
+section_disclaimer_topstories_linktext=Saiba como funciona.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ok, entendi
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Conteúdo inicial do Firefox
+prefs_home_description=Escolha qual conteúdo você quer na sua tela inicial do Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} linha;{num} linhas
+prefs_search_header=Pesquisa na web
+prefs_topsites_description=Os sites que você mais visita
+prefs_topstories_description2=Os melhores conteúdos disponíveis na Web, personalizados pra você
+prefs_topstories_options_sponsored_label=Histórias patrocinadas
+prefs_topstories_sponsored_learn_more=Saiba mais
+prefs_highlights_description=Uma seleção de sites que você salvou ou visitou
+prefs_highlights_options_visited_label=Páginas visitadas
+prefs_highlights_options_download_label=Download mais recente
+prefs_highlights_options_pocket_label=Páginas salvas no Pocket
+prefs_snippets_description=Atualizações da Mozilla e do Firefox
+settings_pane_button_label=Personalizar sua página de nova aba
+settings_pane_topsites_header=Sites preferidos
+settings_pane_highlights_header=Destaques
+settings_pane_highlights_options_bookmarks=Favoritos
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Snippets
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Editar
+edit_topsites_edit_button=Editar este site
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Novo site popular
+topsites_form_edit_header=Editar site popular
+topsites_form_title_label=Título
+topsites_form_title_placeholder=Digite um título
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL de imagem personalizada
+topsites_form_url_placeholder=Digite ou cole um URL
+topsites_form_use_image_link=Utilizar uma imagem personalizada…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Visualizar
+topsites_form_add_button=Adicionar
+topsites_form_save_button=Salvar
+topsites_form_cancel_button=Cancelar
+topsites_form_url_validation=É necessário um URL válido
+topsites_form_image_validation=Não foi possível carregar a imagem. Tente uma URL diferente.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Tópicos populares:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Ver mais histórias
+
+highlights_empty_state=Comece a navegar e nós mostraremos aqui alguns ótimos artigos, vídeos e outras páginas que você favoritou ou visitou recentemente.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Você já viu tudo. Volte mais tarde para mais histórias do {provider}. Não consegue esperar? Escolha um assunto popular para encontrar mais grandes histórias através da web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Experimente o Firefox com os favoritos, histórico e senhas salvas em outro navegador.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Não, obrigado
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importar agora
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Opa, algo deu errado ao carregar esse conteúdo.
+error_fallback_default_refresh_suggestion=Atualize a página para tentar novamente.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Remover seção
+section_menu_action_collapse_section=Recolher seção
+section_menu_action_expand_section=Expandir seção
+section_menu_action_manage_section=Gerenciar seção
+section_menu_action_manage_webext=Gerenciar extensão
+section_menu_action_add_topsite=Adicionar ao sites preferidos
+section_menu_action_move_up=Mover para cima
+section_menu_action_move_down=Mover para baixo
+section_menu_action_privacy_notice=Política de privacidade
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Leve o Firefox com você
+firstrun_content=Tenha seus favoritos, histórico, senhas e outras configurações em todos os seus dispositivos.
+firstrun_learn_more_link=Saiba mais sobre a Conta Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Insira seu email
+firstrun_form_sub_header=para continuar com o Firefox Sync.
+
+firstrun_email_input_placeholder=E-mail
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Ao continuar você concorda com os {terms} e {privacy}.
+firstrun_terms_of_service=Termos de serviço
+firstrun_privacy_notice=Política de privacidade
+
+firstrun_continue_to_login=Continuar
+firstrun_skip_login=Pular essa etapa
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/pt-PT/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Novo separador
+
+header_top_sites=Sites mais visitados
+header_highlights=Destaques
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recomendado por {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Abrir menu de contexto para {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Abrir o menu de contexto da secção
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visitados
+type_label_bookmarked=Adicionados aos marcadores
+type_label_recommended=Tendência
+type_label_pocket=Guardado no Pocket
+type_label_downloaded=Transferido
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Adicionar aos marcadores
+menu_action_remove_bookmark=Remover marcador
+menu_action_open_new_window=Abrir em nova janela
+menu_action_open_private_window=Abrir em nova janela privada
+menu_action_dismiss=Dispensar
+menu_action_delete=Apagar do histórico
+menu_action_pin=Afixar
+menu_action_unpin=Desafixar
+confirm_history_delete_p1=Tem a certeza de que deseja apagar todas as instâncias desta página do seu histórico?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Esta ação não pode ser desfeita.
+menu_action_save_to_pocket=Guardar no Pocket
+menu_action_delete_pocket=Apagar do Pocket
+menu_action_archive_pocket=Arquivar no Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Mostrar no Finder
+menu_action_show_file_windows=Abrir pasta de destino
+menu_action_show_file_linux=Abrir pasta de destino
+menu_action_show_file_default=Mostrar ficheiro
+menu_action_open_file=Abrir ficheiro
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Copiar ligação da transferência
+menu_action_go_to_download_page=Ir para a página da transferência
+menu_action_remove_download=Remover do histórico
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Pesquisar
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Pesquisa {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Pesquisar na Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=As histórias mais interessantes na web, selecionadas baseadas no que você lê. Do Pocket, agora parte da Mozilla.
+section_disclaimer_topstories_linktext=Saiba como funciona.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ok, entendi
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Conteúdo do ecrã inicial do Firefox
+prefs_home_description=Escolha que conteúdo deseja no seu ecrã inicial do Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} linha;{num} linhas
+prefs_search_header=Pesquisa Web
+prefs_topsites_description=Os sites que mais visita
+prefs_topstories_description2=Ótimo conteúdo de toda a web, personalizado para si
+prefs_topstories_options_sponsored_label=Histórias patrocinadas
+prefs_topstories_sponsored_learn_more=Saber mais
+prefs_highlights_description=Uma seleção de sites que guardou ou visitou
+prefs_highlights_options_visited_label=Páginas visitadas
+prefs_highlights_options_download_label=Transferência mais recente
+prefs_highlights_options_pocket_label=Páginas guardadas no Pocket
+prefs_snippets_description=Atualizações da Mozilla e do Firefox
+settings_pane_button_label=Personalizar a sua página de novo separador
+settings_pane_topsites_header=Sites mais visitados
+settings_pane_highlights_header=Destaques
+settings_pane_highlights_options_bookmarks=Marcadores
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Excertos
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Editar
+edit_topsites_edit_button=Editar este site
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Novo site mais visitado
+topsites_form_edit_header=Editar site mais visitado
+topsites_form_title_label=Título
+topsites_form_title_placeholder=Digite um título
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL de imagem personalizada
+topsites_form_url_placeholder=Digite ou cole um URL
+topsites_form_use_image_link=Utilizar uma imagem personalizada…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Pré-visualizar
+topsites_form_add_button=Adicionar
+topsites_form_save_button=Guardar
+topsites_form_cancel_button=Cancelar
+topsites_form_url_validation=URL válido requerido
+topsites_form_image_validation=A imagem falhou o carregamento. Tente um URL diferente.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Tópicos populares:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Ver mais histórias
+
+highlights_empty_state=Comece a navegar, e iremos mostrar-lhe alguns dos ótimos artigos, vídeos, e outras páginas que visitou recentemente ou adicionou aos marcadores aqui.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Já apanhou tudo. Verifique mais tarde para mais histórias principais de {provider}. Não pode esperar? Selecione um tópico popular para encontrar mais boas histórias de toda a web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Experimente o Firefox com marcadores, histórico e palavras-passe de outro navegador.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Não, obrigado
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importar agora
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Oops, algo correu mal ao carregar este conteúdo.
+error_fallback_default_refresh_suggestion=Atualize a página para tentar novamente.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Remover secção
+section_menu_action_collapse_section=Colapsar secção
+section_menu_action_expand_section=Expandir secção
+section_menu_action_manage_section=Gerir secção
+section_menu_action_manage_webext=Gerir extensão
+section_menu_action_add_topsite=Adicionar site mais visitado
+section_menu_action_move_up=Mover para cima
+section_menu_action_move_down=Mover para baixo
+section_menu_action_privacy_notice=Aviso de privacidade
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Leve o Firefox consigo
+firstrun_content=Obtenha os seus marcadores, histórico, palavras-passe e outras definições em todos os seus dispositivos.
+firstrun_learn_more_link=Saber mais acerca do Contas Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Introduza o seu e-mail
+firstrun_form_sub_header=para continuar para o Firefox Sync.
+
+firstrun_email_input_placeholder=Email
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Ao proceder, está a concordar com os {terms} e o {privacy}.
+firstrun_terms_of_service=Termos de serviço
+firstrun_privacy_notice=Aviso de privacidade
+
+firstrun_continue_to_login=Continuar
+firstrun_skip_login=Saltar este passo
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/rm/strings.properties
@@ -0,0 +1,177 @@
+newtab_page_title=Nov tab
+default_label_loading=Chargiar…
+
+header_top_sites=Paginas preferidas
+header_stories=Artitgels populars
+header_highlights=Accents
+header_visit_again=Turnar a visitar
+header_bookmarks=Segnapaginas novs
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recumandà da {provider}
+# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
+# meant to inform that section contains no information because
+# the user hasn't added any bookmarks.
+header_bookmarks_placeholder=Ti n'has anc nagins segnapaginas.
+# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
+# corresponding content (stories) provider
+header_stories_from=da
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Visità
+type_label_bookmarked=Cun segnapagina
+type_label_synced=Sincronisà dad auters apparats
+type_label_recommended=Popular
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=Avert
+type_label_topic=Tema
+type_label_now=Ussa
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Marcar sco segnapagina
+menu_action_remove_bookmark=Allontanar il segnapagina
+menu_action_copy_address=Copiar l'adressa
+menu_action_email_link=Trametter la colliaziun per e-mail…
+menu_action_open_new_window=Avrir en ina nova fanestra
+menu_action_open_private_window=Avrir en ina nova fanestra privata
+menu_action_dismiss=Sbittar
+menu_action_delete=Stizzar da la cronologia
+menu_action_pin=Fixar
+menu_action_unpin=Betg pli fixar
+confirm_history_delete_p1=Vuls ti propi stizzar mintga instanza da questa pagina ord la cronologia?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Questa acziun na po betg vegnir revocada.
+menu_action_save_to_pocket=Memorisar en Pocket
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with=Tschertgar {search_term} cun:
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Tschertgar
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Tschertga da {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Tschertgar en il Web
+search_settings=Midar las preferenzas per tschertgar
+
+# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the
+# (?) icon that would show a section's description with optional feedback link.
+section_info_option=Info
+section_info_send_feedback=Trametter in resun
+section_info_privacy_notice=Infurmaziuns davart la protecziun da datas
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Las istorgias las pli interessantas en il web, tschernidas a basa da quai che ti legias. Da Pocket che fa ussa part da Mozilla.
+section_disclaimer_topstories_linktext=Ve a savair co quai funcziuna.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ok, chapì
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=Bainvegni sin in nov tab
+welcome_body=Firefox utilisescha quest plaz per ta mussar ils segnapaginas, ils artitgels, ils videos e las paginas las pli relevantas che ti has visità dacurt, uschè che ti pos turnar a moda simpla tar quellas.
+welcome_label=Identifitgar tes accents
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=< 1 min
+time_label_minute={number} min
+time_label_hour={number} uras
+time_label_day={number} dis
+
+# LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar.
+settings_pane_button_label=Persunalisar tia pagina per novs tabs
+settings_pane_header=Preferenzas per novs tabs
+settings_pane_body2=Tscherna tge che vegn mussà sin questa pagina.
+settings_pane_search_header=Tschertgar
+settings_pane_search_body=Tschertgar en l'internet da tes nov tab.
+settings_pane_topsites_header=Paginas preferidas
+settings_pane_topsites_body=Acceder las websites che ti visitas il pli savens.
+settings_pane_topsites_options_showmore=Mussar duas colonnas
+settings_pane_bookmarks_header=Novs segnapaginas
+settings_pane_bookmarks_body=Tes novs segnapaginas en in lieu pratic.
+settings_pane_visit_again_header=Turnar a visitar
+settings_pane_visit_again_body=Firefox ta mussa parts da tia cronologia da navigaziun che pudessan esser interessantas per turnar.
+settings_pane_highlights_header=Accents
+settings_pane_highlights_body2=Chatta svelt puspè paginas interessantas che ti has visità u marcà sco segnapagina.
+settings_pane_highlights_options_bookmarks=Segnapaginas
+settings_pane_highlights_options_visited=Paginas visitadas
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Zinslas
+settings_pane_snippets_body=Legia infurmaziuns curtas da Mozilla davart Firefox, la cultura da l'internet e da temp en temp in meme.
+settings_pane_done_button=Finì
+settings_pane_topstories_options_sponsored=Mussar istorgias sponsorisadas
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Modifitgar
+edit_topsites_button_label=Persunalisar la secziun da paginas preferidas
+edit_topsites_showmore_button=Mussar dapli
+edit_topsites_showless_button=Mussar pli pauc
+edit_topsites_done_button=Finì
+edit_topsites_pin_button=Fixar questa pagina
+edit_topsites_unpin_button=Betg pli fixar questa pagina
+edit_topsites_edit_button=Modifitgar questa pagina
+edit_topsites_dismiss_button=Allontanar questa pagina
+edit_topsites_add_button=Agiuntar
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nova pagina populara
+topsites_form_edit_header=Modifitgar la pagina populara
+topsites_form_title_placeholder=Endatar in titel
+topsites_form_url_placeholder=Tippar u encollar ina URL
+topsites_form_add_button=Agiuntar
+topsites_form_save_button=Memorisar
+topsites_form_cancel_button=Interrumper
+topsites_form_url_validation=In URL valid è necessari
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Temas populars:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Mussar dapli artitgels
+# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
+# to Pocket as part of the feedback form.
+pocket_feedback_header=Il meglier ord il web, selecziunà da dapli che 25 milliuns umans.
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane and
+# below (pocket_feedback_header) to provide more information about Pocket.
+pocket_description=Scuvra cuntegn dad auta qualitad cun agid da Pocket che fa ussa part da Mozilla.
+
+highlights_empty_state=Cumenza a navigar e nus ta mussain qua artitgels, videos ed autras paginas che ti has visità dacurt u che ti has agiuntà dacurt sco segnapagina.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Ussa has ti legì tut las novitads. Turna pli tard per ulteriuras novitads da {provider}. Na pos betg spetgar? Tscherna in tema popular per chattar ulteriuras istorgias ord il web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Emprova Firefox cun ils segnapaginas, la cronologia ed ils pleds-clav importads d'in auter navigatur.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Na, grazia
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importar ussa
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ro/strings.properties
@@ -0,0 +1,177 @@
+newtab_page_title=Filă nouă
+
+header_top_sites=Site-uri de top
+header_highlights=Evidențieri
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Recomandat de {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Deschide meniul contextual pentru {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Deschide meniul contextual al secțiunii
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Vizitat
+type_label_bookmarked=Însemnat
+type_label_recommended=În tendințe
+type_label_pocket=Salvat în Pocket
+type_label_downloaded=Descărcat
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Marchează
+menu_action_remove_bookmark=Elimină marcajul
+menu_action_open_new_window=Deschide într-o fereastră nouă
+menu_action_open_private_window=Deschide într-o fereastră privată nouă
+menu_action_dismiss=Înlătură
+menu_action_delete=Șterge din istoric
+menu_action_pin=Fixează
+menu_action_unpin=Anulează fixarea
+confirm_history_delete_p1=Sigur vrei să ştergi fiecare instanţă a acestei pagini din istoric?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Această acțiune este ireversibilă.
+menu_action_save_to_pocket=Salvează în Pocket
+menu_action_delete_pocket=Şterge din Pocket
+menu_action_archive_pocket=Arhivează în Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Afișează în Finder
+menu_action_show_file_windows=Deschide dosarul conținător
+menu_action_show_file_linux=Deschide dosarul conținător
+menu_action_show_file_default=Afișează fișierul
+menu_action_open_file=Deschide fișierul
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Copiază linkul de descărcare
+menu_action_go_to_download_page=Mergi la pagina de descărcare
+menu_action_remove_download=Elimină din istoric
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Caută
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Căutare {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Caută pe web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Cele mai interesante articole de pe web, alese pe baza lucrurilor pe care le citești. De la Pocket, acum parte din Mozilla.
+section_disclaimer_topstories_linktext=Află cum funcționează.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ok, am înțeles
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Conținutul paginii de start Firefox
+prefs_home_description=Alege ce conținut vrei pe ecranul de start Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} rând;{num} rânduri;{num} de rânduri
+prefs_search_header=Căutare web
+prefs_topsites_description=Site-urile pe care le vizitezi cel mai des
+prefs_topstories_description2=Conținut nemaipomenit de pe web, personalizat pentru tine
+prefs_topstories_options_sponsored_label=Articole sponsorizate
+prefs_topstories_sponsored_learn_more=Află mai multe
+prefs_highlights_description=O selecție a site-urilor pe care le-ai salvat sau vizitat
+prefs_highlights_options_visited_label=Pagini vizitate
+prefs_highlights_options_download_label=Cele mai recente descărcări
+prefs_highlights_options_pocket_label=Pagini salvate în Pocket
+prefs_snippets_description=Știri de la Mozilla și Firefox
+settings_pane_button_label=Personalizează pagina pentru filă nouă
+settings_pane_topsites_header=Site-uri de top
+settings_pane_highlights_header=Evidențieri
+settings_pane_highlights_options_bookmarks=Marcaje
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Fragmente
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Editează
+edit_topsites_edit_button=Editează acest site
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Site de top nou
+topsites_form_edit_header=Editează site-ul de top
+topsites_form_title_label=Titlu
+topsites_form_title_placeholder=Introdu un titlu
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL pentru imagine personalizată
+topsites_form_url_placeholder=Tastează sau lipește un URL
+topsites_form_use_image_link=Folosește o imagine personalizată…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Previzualizare
+topsites_form_add_button=Adaugă
+topsites_form_save_button=Salvează
+topsites_form_cancel_button=Renunță
+topsites_form_url_validation=URL valid necesar
+topsites_form_image_validation=Imaginea nu s-a încărcat. Încearcă o altă adresă.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Subiecte populare:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Vezi mai multe articole
+
+highlights_empty_state=Începe să navighezi și noi îți vom arăta articole interesante, videouri sau alte pagini pe care le-ai vizitat sau marcat recent.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Ai ajuns la capăt. Revino mai târziu pentru alte articole de la {provider}. Nu mai vrei să aștepți? Selectează un subiect popular și găsește alte articole interesante de pe web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Încearcă Firefox cu marcajele, istoricul și parolele din alt browser.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Nu, mulțumesc
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importă acum
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ups, ceva a mers prost la încărcarea acestui conținut.
+error_fallback_default_refresh_suggestion=Reîmprospătează pagina pentru a încerca din nou.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Elimină secțiunea
+section_menu_action_collapse_section=Restrânge secțiunea
+section_menu_action_expand_section=Extinde secțiunea
+section_menu_action_manage_section=Gestionează secțiunea
+section_menu_action_add_topsite=Adaugă site de top
+section_menu_action_move_up=Mută în sus
+section_menu_action_move_down=Mută în jos
+section_menu_action_privacy_notice=Politica de confidențialitate
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ru/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Новая вкладка
+
+header_top_sites=Топ сайтов
+header_highlights=Избранное
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Рекомендовано {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Открыть контекстное меню для {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Открыть контекстное меню раздела
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Посещено
+type_label_bookmarked=В закладках
+type_label_recommended=Популярные
+type_label_pocket=Сохранено в Pocket
+type_label_downloaded=Загружено
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Добавить в закладки
+menu_action_remove_bookmark=Удалить закладку
+menu_action_open_new_window=Открыть в новом окне
+menu_action_open_private_window=Открыть в новом приватном окне
+menu_action_dismiss=Скрыть
+menu_action_delete=Удалить из истории
+menu_action_pin=Прикрепить
+menu_action_unpin=Открепить
+confirm_history_delete_p1=Вы действительно хотите удалить все записи об этой странице из вашей истории?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Это действие не может быть отменено.
+menu_action_save_to_pocket=Сохранить в Pocket
+menu_action_delete_pocket=Удалить из Pocket
+menu_action_archive_pocket=Архивировать в Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Показать в Finder
+menu_action_show_file_windows=Открыть папку с файлом
+menu_action_show_file_linux=Открыть папку с файлом
+menu_action_show_file_default=Показать файл
+menu_action_open_file=Открыть файл
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Копировать ссылку на загрузку
+menu_action_go_to_download_page=Перейти на страницу загрузки
+menu_action_remove_download=Удалить из истории
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Искать
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Искать в {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Искать в Интернете
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Самые интересные статьи со всего Интернета, выбираемые на основе ваших интересов. От Pocket, который теперь является частью Mozilla.
+section_disclaimer_topstories_linktext=Узнайте, как это работает.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ок, понятно
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Домашний экран Firefox
+prefs_home_description=Выберите, какое содержимое вы хотите видеть на домашнем экране Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} столбец;{num} столбца;{num} столбцов
+prefs_search_header=Поиск в Интернете
+prefs_topsites_description=Сайты, которые вы чаще всего посещаете
+prefs_topstories_description2=Отличный контент со всего Интернета, отобранный по вашему вкусу
+prefs_topstories_options_sponsored_label=Статьи спонсоров
+prefs_topstories_sponsored_learn_more=Подробнее
+prefs_highlights_description=Избранные сайты, которые вы сохранили или посещали
+prefs_highlights_options_visited_label=Посещённые страницы
+prefs_highlights_options_download_label=Недавние загрузки
+prefs_highlights_options_pocket_label=Страницы, сохранённые в Pocket
+prefs_snippets_description=Обновления от Mozilla и Firefox
+settings_pane_button_label=Настроить свою страницу новой вкладки
+settings_pane_topsites_header=Топ сайтов
+settings_pane_highlights_header=Избранное
+settings_pane_highlights_options_bookmarks=Закладки
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Заметки
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Изменить
+edit_topsites_edit_button=Изменить этот сайт
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Новый сайт в топе
+topsites_form_edit_header=Изменить сайт из топа
+topsites_form_title_label=Заголовок
+topsites_form_title_placeholder=Введите название
+topsites_form_url_label=URL
+topsites_form_image_url_label=Свой URL изображения
+topsites_form_url_placeholder=Введите или вставьте URL
+topsites_form_use_image_link=Использовать своё изображение…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Предпросмотр
+topsites_form_add_button=Добавить
+topsites_form_save_button=Сохранить
+topsites_form_cancel_button=Отмена
+topsites_form_url_validation=Введите корректный URL
+topsites_form_image_validation=Изображение не загрузилось. Попробуйте использовать другой URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Популярные темы:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Больше статей
+
+highlights_empty_state=Начните веб-сёрфинг, и мы покажем вам здесь некоторые из интересных статей, видеороликов и других страниц, которые вы недавно посетили или добавили в закладки.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Вы всё прочитали. Зайдите попозже, чтобы увидеть больше лучших статей от {provider}. Не можете ждать? Выберите популярную тему, чтобы найти больше интересных статей со всего Интернета.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Попробуйте Firefox с закладками, историей и паролями из другого браузера.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Нет, спасибо
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Импортировать сейчас
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=К сожалению что-то пошло не так при загрузке этого содержимого.
+error_fallback_default_refresh_suggestion=Обновите страницу, чтобы повторить попытку.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Удалить раздел
+section_menu_action_collapse_section=Свернуть раздел
+section_menu_action_expand_section=Развернуть раздел
+section_menu_action_manage_section=Управление разделом
+section_menu_action_manage_webext=Управление расширением
+section_menu_action_add_topsite=Добавить в топ сайтов
+section_menu_action_move_up=Вверх
+section_menu_action_move_down=Вниз
+section_menu_action_privacy_notice=Уведомление о приватности
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Возьмите Firefox с собой
+firstrun_content=Получите доступ к вашим закладкам, истории, паролям и другим параметрам на всех ваших устройствах.
+firstrun_learn_more_link=Узнайте больше об Аккаунтах Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Введите ваш адрес электронной почты
+firstrun_form_sub_header=чтобы продолжить использовать синхронизацию Firefox.
+
+firstrun_email_input_placeholder=Эл. почта
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Продолжая, вы соглашаетесь с {terms} и {privacy}.
+firstrun_terms_of_service=условиями службы
+firstrun_privacy_notice=политикой приватности
+
+firstrun_continue_to_login=Продолжить
+firstrun_skip_login=Пропустить этот шаг
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/si/strings.properties
@@ -0,0 +1,162 @@
+newtab_page_title=නව ටැබය
+default_label_loading=පූරණය වෙමින්…
+
+header_top_sites=ප්‍රමුඛ අඩවි
+header_stories=ප්‍රමුඛ පුවත්
+header_highlights=ඉස්මතු කිරීම්
+header_visit_again=යළි පිවිසෙන්න
+header_bookmarks=නැවුම් පිටු සලකුණු
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} විසින් නිර්දේශිතයි
+# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
+# meant to inform that section contains no information because
+# the user hasn't added any bookmarks.
+header_bookmarks_placeholder=ඔබ සතුව තවම පිටුසලකුණු නැත.
+# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
+# corresponding content (stories) provider
+header_stories_from=සිට​
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=ප්‍රවේශිත
+type_label_bookmarked=පිටු සලකුණු තැබූ
+type_label_synced=වෙනත් උපාංගයක් වෙතින් සමකාලීන​ කර ඇත​
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=විවෘත
+type_label_topic=මාතෘකාව
+type_label_now=දැන්
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=පිටු සලකුණ
+menu_action_remove_bookmark=පිටු සලකුණ ඉවත් කරන්න
+menu_action_copy_address=ලිපිනය පිටපත් කරන්න
+menu_action_email_link=විද්‍යුත් තැපැල් සබැඳි…
+menu_action_open_new_window=නව කවුළුවක විවෘත කරන්න
+menu_action_open_private_window=නව පුද්ගලික කවුළුවක විවෘත කරන්න
+menu_action_dismiss=ඉවත් කරන්න
+menu_action_delete=අතිතයෙන් මකන්න කරන්න
+menu_action_pin=ඇමිණීම
+menu_action_unpin=ඇමුණුම ඉවත් කරන්න
+confirm_history_delete_p1=ඔබට මෙම පිටුවට අදාල සියලුම සිදුවීම් ඔබේ අතීතයන් මැකීමට අවශ්‍ය ද?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=මෙම ක්‍රියාව අහෝසි කළ නොහැක.
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with={search_term} සදහා සෙවීමට භාවිත කළ යුත්තේ:
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=සොයන්න
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} ෙසවුම
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=ජාලය තුළ සොයන්න
+search_settings=සෙවුම් සැකසුම් වෙනස් කරන්න
+
+# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the
+# (?) icon that would show a section's description with optional feedback link.
+section_info_option=තොරතුරු
+section_info_send_feedback=ප්‍රතිචාරය යවන්න
+section_info_privacy_notice=පෞද්ගලිකත්ව දැනුම්දීම්
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories_linktext=එය ක්‍රියාකරන්නේ කෙසේදැයි අධ්‍යපනය කරන්න.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=හරි, තේරුණා
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=නව ටැබයට සාදරයෙන් පිළිගනිමු
+welcome_body=ඔබට පහසුවෙන් යළි භාවිතයට පහසු කරවීමට, Firefox මෙම ඉඩ ඔබට වඩාත් අදාල පිටු සළකුණු, ලිපි, විඩියෝ සහ ඔබ මෑතකදී පිවිසි පිටු පෙන්වීම සදහා භාවිත කරයි.
+welcome_label=ඔබේ ඉස්මතු කිරීම් හදුනාගනිමින්
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=<1m
+time_label_minute={number} මිනිත්තු
+time_label_hour={number}පැය
+time_label_day={number}දින
+
+# LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar.
+settings_pane_button_label=ඔබේ නව ටැබ පිටුව රුචිකරණය කරන්න
+settings_pane_header=නව ටැබ අභිප්‍රේත
+settings_pane_body2=මෙම පිටුවේ ඔබ දැකිය යුතු දේ තෝරන්න.
+settings_pane_search_header=සොයන්න
+settings_pane_search_body=ඔබේ නව ටැබයෙන් වෙබ් සෙවීම.
+settings_pane_topsites_header=ප්‍රමුඛ අඩවි
+settings_pane_topsites_body=ඔබ නිරතුරුව පිවිසෙන වෙබ් අඩවි වෙත ප්‍රවේශය.
+settings_pane_topsites_options_showmore=පේළි දෙකක් පෙන්වන්න
+settings_pane_bookmarks_header=නැවුම් පිටු සලකුණු
+settings_pane_bookmarks_body=ඔබේ නැවුම් පිටු සලකුණු එක් ස්ථානයක.
+settings_pane_visit_again_header=යළි පිවිසෙන්න
+settings_pane_highlights_header=ඉස්මතු කිරීම්
+settings_pane_highlights_options_bookmarks=පිටු සලකුණු
+settings_pane_highlights_options_visited=පිවිසුණු අඩවි
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_topstories_options_sponsored=අනුග්‍රහක පුවත් පෙන්වන්න
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=සැකසුම්
+edit_topsites_showmore_button=තවත් පෙන්වන්න
+edit_topsites_showless_button=අඩුවෙන් පෙන්වන්න
+edit_topsites_done_button=කළා
+edit_topsites_edit_button=මෙම අඩවිය සකසන්න
+edit_topsites_dismiss_button=මෙම අඩවිය ඉවත ලන්න
+edit_topsites_add_button=එක් කරන්න
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=නව ප්‍රමුඛ අඩවියක්
+topsites_form_edit_header=ප්‍රමුඛ අඩවිය සකසන්න
+topsites_form_title_placeholder=සිරස්තල එක් කරන්න
+topsites_form_url_placeholder=URL එකක් ඇතුළත් කරන්න
+topsites_form_add_button=එක් කරන්න
+topsites_form_save_button=සුරකින්න
+topsites_form_cancel_button=අවලංගු කරන්න
+topsites_form_url_validation=වලංගු URL එකක් අවශ්‍ය වේ
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=ජනප්‍රිය මාතෘකා:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=තවත් බොහෝ දැ
+# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
+# to Pocket as part of the feedback form.
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane and
+# below (pocket_feedback_header) to provide more information about Pocket.
+
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Firefox වෙනත් ගවේශයකය පිටය සලකුණු, අතීතය සහ මුරපද සමග උත්සාහ කර බලන්න.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=එපා, ස්තුතියි
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=දැන් ආයාත කරන්න
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/sk/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Nová karta
+
+header_top_sites=Top stránky
+header_highlights=Vybrané stránky
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Odporúča {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Otvorí kontextovú ponuku pre {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Otvorí kontextovú ponuku sekcie
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Navštívené
+type_label_bookmarked=V záložkách
+type_label_recommended=Trendy
+type_label_pocket=Uložené do služby Pocket
+type_label_downloaded=Prevzaté
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Pridať medzi záložky
+menu_action_remove_bookmark=Odstrániť záložku
+menu_action_open_new_window=Otvoriť v novom okne
+menu_action_open_private_window=Otvoriť v novom okne režimu Súkromné prehliadanie
+menu_action_dismiss=Skryť
+menu_action_delete=Odstrániť z histórie
+menu_action_pin=Pripnúť
+menu_action_unpin=Odopnúť
+confirm_history_delete_p1=Ste si istí, že chcete odstrániť všetky výskyty tejto stránky zo svojej histórie prehliadania?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Túto akciu nie je možné vrátiť späť.
+menu_action_save_to_pocket=Uložiť do služby Pocket
+menu_action_delete_pocket=Odstrániť zo služby Pocket
+menu_action_archive_pocket=Archivovať v službe Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Zobraziť vo Finderi
+menu_action_show_file_windows=Otvoriť priečinok so súborom
+menu_action_show_file_linux=Otvoriť priečinok so súborom
+menu_action_show_file_default=Zobraziť súbor
+menu_action_open_file=Otvoriť súbor
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Kopírovať adresu súboru
+menu_action_go_to_download_page=Prejsť na stránku so súborom
+menu_action_remove_download=Odstrániť z histórie
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Hľadať
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Vyhľadávanie pomocou {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Vyhľadávanie na webe
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Najzaujímavejšie príbehy na webe, vybrané na základe toho, čo čítate. Od Pocketu, súčasti Mozilly.
+section_disclaimer_topstories_linktext=Pozrite sa, ako to funguje.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ok, rozumiem
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Obsah domovskej stránky Firefoxu
+prefs_home_description=Vyberte si obsah, ktorý chcete mať na domovskej stránke svojho Firefoxu.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} riadok;{num} riadky;{num} riadkov
+prefs_search_header=Vyhľadávanie na webe
+prefs_topsites_description=Najnavštevovanejšie stránky
+prefs_topstories_description2=Skvelý obsah z celého webu, vybraný špeciálne pre vás
+prefs_topstories_options_sponsored_label=Sponzorované stránky
+prefs_topstories_sponsored_learn_more=Ďalšie informácie
+prefs_highlights_description=Výber stránok, ktoré ste si uložili alebo ste ich navštívili
+prefs_highlights_options_visited_label=Navštívené stránky
+prefs_highlights_options_download_label=Nedávne prevzatia
+prefs_highlights_options_pocket_label=Stránky uložené do služby Pocket
+prefs_snippets_description=Informácie od Mozilly a od Firefoxu
+settings_pane_button_label=Prispôsobte si svoju stránku Nová karta
+settings_pane_topsites_header=Top stránky
+settings_pane_highlights_header=Vybrané stránky
+settings_pane_highlights_options_bookmarks=Záložky
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Snippety
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Upraviť
+edit_topsites_edit_button=Upraviť túto stránku
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nová top stránka
+topsites_form_edit_header=Upraviť top stránku
+topsites_form_title_label=Názov
+topsites_form_title_placeholder=Zadajte názov
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL adresa vlastného obrázku
+topsites_form_url_placeholder=Zadajte alebo prilepte URL
+topsites_form_use_image_link=Použiť vlastný obrázok…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Ukážka
+topsites_form_add_button=Pridať
+topsites_form_save_button=Uložiť
+topsites_form_cancel_button=Zrušiť
+topsites_form_url_validation=Vyžaduje sa platná URL
+topsites_form_image_validation=Obrázok sa nepodarilo načítať. Skúste inú URL adresu.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Populárne témy:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Zobraziť ďalšie príbehy
+
+highlights_empty_state=Začnite s prehliadaním a my vám na tomto mieste ukážeme skvelé články, videá a ostatné stránky, ktoré ste nedávno navštívili alebo pridali medzi záložky.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Už ste prečítali všetko. Ďalšie príbehy zo služby {provider} tu nájdete opäť neskôr. Nemôžete sa dočkať? Vyberte si populárnu tému a pozrite sa na ďalšie skvelé príbehy z celého webu.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Vyskúšajte Firefox so záložkami, históriou prehliadania a heslami s iných prehliadačov.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Nie, ďakujem
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importovať teraz
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Hups, pri načítavaní tohto obsahu sa niečo pokazilo.
+error_fallback_default_refresh_suggestion=Obnovením stránky to skúsite znova.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Odstrániť sekciu
+section_menu_action_collapse_section=Zbaliť sekciu
+section_menu_action_expand_section=Rozbaliť sekciu
+section_menu_action_manage_section=Spravovať sekciu
+section_menu_action_manage_webext=Správa rozšírenia
+section_menu_action_add_topsite=Pridať top stránku
+section_menu_action_move_up=Posunúť vyššie
+section_menu_action_move_down=Posunúť nižšie
+section_menu_action_privacy_notice=Zásady ochrany súkromia
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Vezmite si Firefox so sebou
+firstrun_content=Majte svoje záložky, históriu, heslá a ostatné nastavenia na všetkých vašich zariadeniach.
+firstrun_learn_more_link=Ďalšie informácie o účtoch Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Zadajte e-mailovú adresu
+firstrun_form_sub_header=a používajte službu Firefox Sync.
+
+firstrun_email_input_placeholder=E-mail
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Pokračovaním súhlasíte s {terms} a {privacy}.
+firstrun_terms_of_service=podmienkami používania služby
+firstrun_privacy_notice=zásadami ochrany súkromia
+
+firstrun_continue_to_login=Pokračovať
+firstrun_skip_login=Preskočiť tento krok
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/sl/strings.properties
@@ -0,0 +1,192 @@
+newtab_page_title=Nov zavihek
+
+header_top_sites=Glavne strani
+header_highlights=Poudarki
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Priporoča {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Odpri priročni meni za {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Odpri priročni meni odseka
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Obiskano
+type_label_bookmarked=Med zaznamki
+type_label_recommended=Najbolj priljubljeno
+type_label_pocket=Shranjeno v Pocket
+type_label_downloaded=Preneseno
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Dodaj med zaznamke
+menu_action_remove_bookmark=Odstrani zaznamek
+menu_action_open_new_window=Odpri v novem oknu
+menu_action_open_private_window=Odpri v novem zasebnem oknu
+menu_action_dismiss=Opusti
+menu_action_delete=Izbriši iz zgodovine
+menu_action_pin=Pripni
+menu_action_unpin=Odpni
+confirm_history_delete_p1=Ali ste prepričani, da želite izbrisati vse primerke te strani iz zgodovine?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Tega dejanja ni mogoče razveljaviti.
+menu_action_save_to_pocket=Shrani v Pocket
+menu_action_delete_pocket=Izbriši iz Pocketa
+menu_action_archive_pocket=Arhiviraj v Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Prikaži v Finderju
+menu_action_show_file_windows=Odpri vsebujočo mapo
+menu_action_show_file_linux=Odpri vsebujočo mapo
+menu_action_show_file_default=Prikaži datoteko
+menu_action_open_file=Odpri datoteko
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Kopiraj povezavo za prenos
+menu_action_go_to_download_page=Pojdi na stran za prenos
+menu_action_remove_download=Odstrani iz zgodovine
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Iskanje
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Iskanje {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Iskanje po spletu
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Najbolj zanimive zgodbe na spletu, izbrane na podlagi vašega branja. Iz Pocketa, ki je zdaj del Mozille.
+section_disclaimer_topstories_linktext=Spoznajte, kako deluje.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Razumem
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Vsebina domače strani Firefoxa
+prefs_home_description=Izberite vsebino, ki jo želite prikazati na domači strani Firefoxa.
+prefs_restore_defaults_button=Povrni privzeto
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} vrstica;{num} vrstici;{num} vrstice;{num} vrstic
+prefs_search_header=Iskanje po spletu
+prefs_topsites_description=Strani, ki jih največkrat obiščete
+prefs_topstories_description2=Odlična vsebina iz celega spleta, prilagojena vašemu okusu
+prefs_topstories_options_sponsored_label=Zgodbe oglaševalcev
+prefs_topstories_sponsored_learn_more=Več o tem
+prefs_highlights_description=Izbor strani, ki ste jih shranili ali obiskali
+prefs_highlights_options_visited_label=Obiskane strani
+prefs_highlights_options_download_label=Najnovejši prenos
+prefs_highlights_options_pocket_label=Strani, shranjene v Pocket
+prefs_snippets_description=Novice iz sveta Mozille in Firefoxa
+settings_pane_button_label=Prilagodite stran novega zavihka
+settings_pane_header=Nastavitve novega zavihka
+settings_pane_body2=Izberite, kaj želite videti na tej strani.
+settings_pane_search_header=Iskanje
+settings_pane_search_body=Iščite po spletu z novega zavihka.
+settings_pane_topsites_header=Glavne strani
+settings_pane_topsites_body=Priročen dostop do najbolj obiskanih strani.
+settings_pane_topsites_options_showmore=Prikaži dve vrsti
+settings_pane_highlights_header=Poudarki
+settings_pane_highlights_body2=Najdite pot nazaj do zanimivih strani, ki ste jih nedavno obiskali ali dodali med zaznamke.
+settings_pane_highlights_options_bookmarks=Zaznamki
+settings_pane_highlights_options_visited=Obiskane strani
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Izrezki
+settings_pane_snippets_body=Spremljajte kratke novice o Mozilli in Firefoxu, kulturi interneta in si občasno oglejte kak meme.
+settings_pane_done_button=Končano
+settings_pane_topstories_options_sponsored=Prikaži zgodbe oglaševalcev
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Uredi
+edit_topsites_edit_button=Uredi to stran
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Nova glavna stran
+topsites_form_edit_header=Uredi glavno stran
+topsites_form_title_label=Naslov
+topsites_form_title_placeholder=Vnesite ime
+topsites_form_url_label=Spletni naslov
+topsites_form_image_url_label=Spletni naslov slike po meri
+topsites_form_url_placeholder=Vnesite ali prilepite spletni naslov
+topsites_form_use_image_link=Uporabi sliko po meri …
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Predogled
+topsites_form_add_button=Dodaj
+topsites_form_save_button=Shrani
+topsites_form_cancel_button=Prekliči
+topsites_form_url_validation=Vnesite veljaven spletni naslov
+topsites_form_image_validation=Slike ni bilo mogoče naložiti. Poskusite drug spletni naslov.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Priljubljene teme:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Prikaži več vesti
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=Odkrijte kakovostno vsebino, ki bi jo sicer spregledali, s pomočjo Pocketa (zdaj dela Mozille).
+
+highlights_empty_state=Začnite z brskanjem, mi pa vam bomo tu prikazovali odlične članke, videoposnetke ter druge strani, ki ste jih nedavno obiskali ali shranili med zaznamke.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Zdaj ste seznanjeni z novicami. Vrnite se pozneje in si oglejte nove prispevke iz {provider}. Komaj čakate? Izberite priljubljeno temo in odkrijte več velikih zgodb na spletu.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Preskusite Firefox z zaznamki, zgodovino in gesli iz drugega brskalnika.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Ne, hvala
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Uvozi zdaj
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ojoj, pri nalaganju te vsebine je šlo nekaj narobe.
+error_fallback_default_refresh_suggestion=Osvežite stran za ponoven poskus.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Odstrani odsek
+section_menu_action_collapse_section=Strni odsek
+section_menu_action_expand_section=Razširi odsek
+section_menu_action_manage_section=Upravljanje odseka
+section_menu_action_add_topsite=Dodaj glavno stran
+section_menu_action_move_up=Premakni gor
+section_menu_action_move_down=Premakni dol
+section_menu_action_privacy_notice=Obvestilo o zasebnosti
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/sq/strings.properties
@@ -0,0 +1,177 @@
+newtab_page_title=Skedë e Re
+
+header_top_sites=Sajte Kryesues
+header_highlights=Highlights
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Rekomanduar nga {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Hapni menu konteksti për {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Hap menu konteksti ndarjeje
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Të vizituara
+type_label_bookmarked=Të faqeruajtura
+type_label_recommended=Në modë
+type_label_pocket=Ruajtur te Pocket
+type_label_downloaded=Të shkarkuara
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Faqerojtës
+menu_action_remove_bookmark=Hiqe Faqerojtësin
+menu_action_open_new_window=Hape në Dritare të Re
+menu_action_open_private_window=Hape në Dritare të Re Private
+menu_action_dismiss=Hidhe tej
+menu_action_delete=Fshije prej Historiku
+menu_action_pin=Fiksoje
+menu_action_unpin=Shfiksoje
+confirm_history_delete_p1=Jeni të sigurt se doni të fshini nga historiku çdo instancë të kësaj faqeje?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Ky veprim s’mund të zhbëhet.
+menu_action_save_to_pocket=Ruaje te Pocket
+menu_action_delete_pocket=Fshije nga Pocket
+menu_action_archive_pocket=Arkivoje në Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Shfaqe Në Finder
+menu_action_show_file_windows=Hap Dosjen Përkatëse
+menu_action_show_file_linux=Hap Dosjen Përkatëse
+menu_action_show_file_default=Shfaqe Kartelën
+menu_action_open_file=Hape Kartelën
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Kopjo Lidhjen e Shkarkimit
+menu_action_go_to_download_page=Shko Te Faqja e Shkarkimit
+menu_action_remove_download=Hiqe Prej Historiku
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Kërko
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Kërkim me {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Kërkoni në Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Historitë më interesante në internet, të përzgjedhura mbi bazën e çka lexoni. Nga Pocket-i, tani pjesë e Mozilla-.
+section_disclaimer_topstories_linktext=Mësoni se si funksionon.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=OK, e mora vesh
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Lëndë Firefox Home
+prefs_home_description=Zgjidhni ç’lëndë doni në skenën tuaj Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} rresht;{num} rreshta
+prefs_search_header=Kërkim Web
+prefs_topsites_description=Sajtet që vizitoni më tepër
+prefs_topstories_description2=Lëndë e bukur nga anembanë internetit, personalizuar për ju
+prefs_topstories_options_sponsored_label=Histori të Sponsorizuara
+prefs_topstories_sponsored_learn_more=Mësoni më tepër
+prefs_highlights_description=Një përzgjedhje të sajteve që keni ruajtur ose vizituar
+prefs_highlights_options_visited_label=Faqe të Vizituara
+prefs_highlights_options_download_label=Shkarkimet Më të Reja
+prefs_highlights_options_pocket_label=Faqe të Ruajtura te Pocket
+prefs_snippets_description=Përditësime nga Mozilla dhe Firefox-i
+settings_pane_button_label=Personalizoni faqen tuaj Skedë e Re
+settings_pane_topsites_header=Sajte Kryesues
+settings_pane_highlights_header=Highlights
+settings_pane_highlights_options_bookmarks=Faqerojtës
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Copëza
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Përpunoni
+edit_topsites_edit_button=Përpunoni këtë sajt
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Sajt i Ri Kryesues
+topsites_form_edit_header=Përpunoni Sajtin Kryesues
+topsites_form_title_label=Titull
+topsites_form_title_placeholder=Jepni një titull
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL Figure Vetjake
+topsites_form_url_placeholder=Shtypni ose hidhni një URL
+topsites_form_use_image_link=Përdorni një figurë vetjake…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Paraparje
+topsites_form_add_button=Shtoje
+topsites_form_save_button=Ruaje
+topsites_form_cancel_button=Anuloje
+topsites_form_url_validation=Lypset URL e vlefshme
+topsites_form_image_validation=Dështoi ngarkimi i figurës. Provoni një URL tjetër.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Tema Popullore:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Shihni Më Tepër Histori
+
+highlights_empty_state=Filloni shfletimin, dhe do t'ju shfaqim disa nga artikujt, videot dhe të tjera faqe interesante që keni vizituar apo faqerojtur këtu kohët e fundit.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Gjithë ç’kish, e dini. Rikontrolloni më vonë për më tepër histori nga {provider}. S’pritni dot? Përzgjidhni një temë popullore që të gjenden në internet më tepër histori të goditura.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Provojeni Firefox-in me faqerojtës, historik dhe fjalëkalime nga një tjetër shfletues.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Jo, Faleminderit
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importoje Tani
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Hëm, diç shkoi ters në ngarkimin e kësaj lënde.
+error_fallback_default_refresh_suggestion=Rifreskoni faqen që të riprovohet.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Hiqe Ndarjen
+section_menu_action_collapse_section=Tkurre Ndarjen
+section_menu_action_expand_section=Zgjeroje Ndarjen
+section_menu_action_manage_section=Administroni Ndarjen
+section_menu_action_add_topsite=Shtoni Sajt Kryesues
+section_menu_action_move_up=Ngjite
+section_menu_action_move_down=Zbrite
+section_menu_action_privacy_notice=Shënim Mbi Privatësinë
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/sr/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Нови језичак
+
+header_top_sites=Омиљени сајтови
+header_highlights=Истакнуто
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Предложио {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Отвори мени поља за {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Отворите секцију контекст менија
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Посећено
+type_label_bookmarked=Забележено
+type_label_recommended=У тренду
+type_label_pocket=Сачувано у Pocket
+type_label_downloaded=Преузето
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Забележи
+menu_action_remove_bookmark=Уклони забелешку
+menu_action_open_new_window=Отвори у новом прозору
+menu_action_open_private_window=Отвори у новом приватном прозору
+menu_action_dismiss=Уклони
+menu_action_delete=Уклони из историјата
+menu_action_pin=Закачи
+menu_action_unpin=Откачи
+confirm_history_delete_p1=Да ли сте сигурни да желите да обришете све посете ове странице из ваше историје?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Ова радња се не може опозвати.
+menu_action_save_to_pocket=Сачувај на Pocket
+menu_action_delete_pocket=Обриши из Pocket-а
+menu_action_archive_pocket=Архивирај у Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Прикажи у Finder-у
+menu_action_show_file_windows=Отвори фасциклу са преузетим садржајем
+menu_action_show_file_linux=Отвори фасциклу са преузетим садржајем
+menu_action_show_file_default=Прикажи датотеку
+menu_action_open_file=Отвори датотеку
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Копирај везу за преузимање
+menu_action_go_to_download_page=Иди на станицу за преузимања
+menu_action_remove_download=Уклони из историје
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Претражи
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} претрага
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Претражи веб
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Најинтересантније приче на вебу, изабране на основу онога што читате. Од Pocket-а, који је сада део Mozilla-е.
+section_disclaimer_topstories_linktext=Сазнајте како ради.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=У реду
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Садржај Firefox почетне странице
+prefs_home_description=Изаберите садржај који желите видети на вашој Firefox почетној страници.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} ред;{num} реда;{num} редова
+prefs_search_header=Веб претрага
+prefs_topsites_description=Сајтови које највише посећујете
+prefs_topstories_description2=Одличан садржај из целог света, персонализован за вас
+prefs_topstories_options_sponsored_label=Спонзорисане приче
+prefs_topstories_sponsored_learn_more=Сазнајте више
+prefs_highlights_description=Изабрани сајтови које сте сачували или посетили
+prefs_highlights_options_visited_label=Посећене странице
+prefs_highlights_options_download_label=Најновије преузимање
+prefs_highlights_options_pocket_label=Странице сачуване у Pocket
+prefs_snippets_description=Новости од Mozilla-е и Firefox-а
+settings_pane_button_label=Прилагодите страницу новог језичка
+settings_pane_topsites_header=Омиљени сајтови
+settings_pane_highlights_header=Истакнуто
+settings_pane_highlights_options_bookmarks=Забелешке
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Исечци
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Уреди
+edit_topsites_edit_button=Уреди овај сајт
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Нови омиљени сајт
+topsites_form_edit_header=Уреди популарне сајтове
+topsites_form_title_label=Наслов
+topsites_form_title_placeholder=Унесите наслов
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL прилагођене слике
+topsites_form_url_placeholder=Унесите или налепите URL
+topsites_form_use_image_link=Користи прилагођену слику…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Преглед
+topsites_form_add_button=Додај
+topsites_form_save_button=Сачувај
+topsites_form_cancel_button=Откажи
+topsites_form_url_validation=Исправан URL се захтева
+topsites_form_image_validation=Нисам успео да учитам слику. Пробајте са другим URL-ом.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Популарне теме:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Погледајте још прича
+
+highlights_empty_state=Почните са коришћењем веба а ми ћемо вам овде приказивати неке од одличних чланака, видео записа и других страница које сте скоро посетили.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Вратите се касније за нове вести {provider}. Не можете дочекати? Изаберите популарну тему да пронађете још занимљивих вести из света.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Пробајте FIrefox са коришћењем забелешки, историјата и лозинки из другог прегледача.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Не, хвала
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Увези сада
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Упс, дошло је до грешке приликом учитавања овог садржаја.
+error_fallback_default_refresh_suggestion=Освежите страницу да покушате поново.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Уклони секцију
+section_menu_action_collapse_section=Скупи секцију
+section_menu_action_expand_section=Прошири секцију
+section_menu_action_manage_section=Управљај секцијом
+section_menu_action_manage_webext=Управљај екстензијама
+section_menu_action_add_topsite=Додај омиљени сајт
+section_menu_action_move_up=Помери горе
+section_menu_action_move_down=Помери доле
+section_menu_action_privacy_notice=Обавештење о приватности
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Понесите Firefox са собом
+firstrun_content=Имајте све забелешке, историјат, лозинке и друге поставке на свим вашим уређајима.
+firstrun_learn_more_link=Сазнајте више о Firefox Accounts
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Унесите вашу адресу е-поште
+firstrun_form_sub_header=да бисте наставили на Firefox Sync.
+
+firstrun_email_input_placeholder=Адреса е-поште
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Наставком, прихватате {terms} и {privacy}.
+firstrun_terms_of_service=услове коришћења
+firstrun_privacy_notice=обавештење о приватности
+
+firstrun_continue_to_login=Настави
+firstrun_skip_login=Прескочи овај корак
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/sv-SE/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Ny flik
+
+header_top_sites=Mest besökta
+header_highlights=Höjdpunkter
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Rekommenderas av {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Öppna snabbmeny för {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Öppna sektionens snabbmeny
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Besökta
+type_label_bookmarked=Bokmärkta
+type_label_recommended=Trend
+type_label_pocket=Spara till Pocket
+type_label_downloaded=Nedladdat
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Bokmärke
+menu_action_remove_bookmark=Ta bort bokmärke
+menu_action_open_new_window=Öppna i nytt fönster
+menu_action_open_private_window=Öppna i nytt privat fönster
+menu_action_dismiss=Avfärda
+menu_action_delete=Ta bort från historik
+menu_action_pin=Fäst
+menu_action_unpin=Lösgör
+confirm_history_delete_p1=Är du säker på att du vill radera varje förekomst av den här sidan från din historik?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Den här åtgärden kan inte ångras.
+menu_action_save_to_pocket=Spara till Pocket
+menu_action_delete_pocket=Ta bort från Pocket
+menu_action_archive_pocket=Arkivera i Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Visa i Finder
+menu_action_show_file_windows=Öppna objektets mapp
+menu_action_show_file_linux=Öppna objektets mapp
+menu_action_show_file_default=Visa fil
+menu_action_open_file=Öppna fil
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Kopiera nedladdningslänk
+menu_action_go_to_download_page=Gå till hämtningssida
+menu_action_remove_download=Ta bort från historik
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Sök
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Sök på webben
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=De mest intressanta nyheterna på webben, utvalda baserat på vad du läser. Från Pocket, nu en del av Mozilla.
+section_disclaimer_topstories_linktext=Lär dig hur det fungerar.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ok, jag förstår
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Innehåll Firefox-startskärm
+prefs_home_description=Välj vilket innehåll du vill ha på din startskärm i Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} rad;{num} rader
+prefs_search_header=Webbsök
+prefs_topsites_description=Sidorna du besöker mest
+prefs_topstories_description2=Bra innehåll från hela webben, anpassat för dig
+prefs_topstories_options_sponsored_label=Sponsrade nyheter
+prefs_topstories_sponsored_learn_more=Läs mer
+prefs_highlights_description=Ett urval av sidor du har sparat eller besökt
+prefs_highlights_options_visited_label=Besökta sidor
+prefs_highlights_options_download_label=Senaste nedladdning
+prefs_highlights_options_pocket_label=Sidor sparade till Pocket
+prefs_snippets_description=Uppdateringar från Mozilla och Firefox
+settings_pane_button_label=Anpassa sidan för Ny flik
+settings_pane_topsites_header=Mest besökta
+settings_pane_highlights_header=Höjdpunkter
+settings_pane_highlights_options_bookmarks=Bokmärken
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Kort information
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Redigera
+edit_topsites_edit_button=Redigera denna webbplats
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Ny mest besökt
+topsites_form_edit_header=Redigera mest besökta
+topsites_form_title_label=Titel
+topsites_form_title_placeholder=Ange en titel
+topsites_form_url_label=URL
+topsites_form_image_url_label=Anpassad bild URL
+topsites_form_url_placeholder=Skriv eller klistra in en URL
+topsites_form_use_image_link=Använd en anpassad bild…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Förhandsvisa
+topsites_form_add_button=Lägg till
+topsites_form_save_button=Spara
+topsites_form_cancel_button=Avbryt
+topsites_form_url_validation=Giltig URL krävs
+topsites_form_image_validation=Bilden misslyckades att ladda. Prova en annan URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Populära ämnen:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Visa fler nyheter
+
+highlights_empty_state=Börja surfa, och vi visar några av de bästa artiklarna, videoklippen och andra sidor du nyligen har besökt eller bokmärkt här.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Det finns inte fler. Kom tillbaka senare för fler huvudnyheter från {provider}. Kan du inte vänta? Välj ett populärt ämne för att hitta fler bra nyheter från hela världen.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Testa Firefox med bokmärken, historik och lösenord från en annan webbläsare.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Nej tack
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Importera nu
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Oj, något gick fel när innehållet skulle laddas.
+error_fallback_default_refresh_suggestion=Uppdatera sidan för att försöka igen.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Ta bort sektion
+section_menu_action_collapse_section=Fäll ihop sektion
+section_menu_action_expand_section=Expandera sektion
+section_menu_action_manage_section=Hantera sektion
+section_menu_action_manage_webext=Hantera tillägg
+section_menu_action_add_topsite=Lägg till mest besökta
+section_menu_action_move_up=Flytta upp
+section_menu_action_move_down=Flytta ner
+section_menu_action_privacy_notice=Sekretesspolicy
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Ta med dig Firefox
+firstrun_content=Få dina bokmärken, historik, lösenord och andra inställningar på alla dina enheter.
+firstrun_learn_more_link=Lär dig mer om Firefox-konton
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Ange din e-postadress
+firstrun_form_sub_header=för att fortsätta till Firefox Sync.
+
+firstrun_email_input_placeholder=E-post
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Genom att fortsätta godkänner du {terms} och {privacy}.
+firstrun_terms_of_service=Användarvillkor
+firstrun_privacy_notice=Sekretesspolicy
+
+firstrun_continue_to_login=Fortsätt
+firstrun_skip_login=Hoppa över det här steget
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ta/strings.properties
@@ -0,0 +1,177 @@
+newtab_page_title=புதிய கீற்று
+
+header_top_sites=சிறந்த தளங்கள்
+header_highlights=மிளிர்ப்புகள்
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} என்பவரால் பரிந்துரைக்கப்பட்டது
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr={title} என்பதற்கான உள்ளடக்க பட்டியலைத் திற
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=பிரிவு உள்ளடக்க பட்டியலைத் திற
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=பார்த்தவை
+type_label_bookmarked=புத்தகக்குறியிடப்பட்டது
+type_label_recommended=பிரபலமான
+type_label_pocket=பாக்கெட்டில் சேமிக்கப்பட்டது
+type_label_downloaded=பதிவிறக்கப்பட்டது
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=புத்தகக்குறி
+menu_action_remove_bookmark=புத்தகக்குறியை நீக்கு
+menu_action_open_new_window=ஒரு புதிய சாளரத்தில் திற
+menu_action_open_private_window=ஒரு புதிய அந்தரங்க சாளரத்தில் திற
+menu_action_dismiss=வெளியேற்று
+menu_action_delete=வரலாற்றிலருந்து அழி
+menu_action_pin=பொருத்து
+menu_action_unpin=விடுவி
+confirm_history_delete_p1=இப்பக்கத்தை உங்களின் வரலாற்றிலிருந்து முழுமையாக நீக்க விரும்புகிறீர்களா?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=இச்செயலை மீட்க முடியாது.
+menu_action_save_to_pocket=பாக்கட்டில் சேமி
+menu_action_delete_pocket=பாக்கெட்டிலிருந்து நீக்கு
+menu_action_archive_pocket=பாக்கெட்டில் காப்பெடு
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=தேடு
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} தேடுபொறியில் தேடு
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=இணையத்தில் தேடு
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=இணையத்தின் சுவாரசியமான கதைகள், நீங்கள் படிப்பவற்றின் அடிப்படையில் தேர்ந்தெடுக்கப்பட்டுள்ளன. பாக்கெட், இப்போது மொசில்லாவின் ஒரு பகுதியாகும்.
+section_disclaimer_topstories_linktext=இது எப்படி வேலை செய்கிறது என்று தெரிந்துகொள்ளவும்.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=சரி, புரிந்தது
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox முகப்பு உள்ளடக்கம்
+prefs_home_description=உங்கள் பயர்பாக்ஸ் முகப்புத் திரையில் என்ன உள்ளடக்கம் வேண்டுமென்று தேர்ந்தெடு.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} வரிசை;{num} வரிசைகள்
+prefs_search_header=வலைதள தேடல்
+prefs_topsites_description=நீங்கள் மிகவும் பார்வையிடும் தளங்கள்
+prefs_topstories_description2=இணையத்திலிருந்து சிறந்த உள்ளடக்கங்கள், உங்களுக்காக தனிப்பயனாக்கப்பட்டவை
+prefs_topstories_sponsored_learn_more=மேலும் அறிய
+prefs_highlights_description=நீங்கள் சேமித்த அல்லது பார்வையிட்ட தளங்களின் தேர்வு
+prefs_snippets_description=மொசில்லா மற்றும் பயர்பாக்சிலிருந்து புதுப்பிப்புகள்
+settings_pane_button_label=உங்கள் புதிய கீற்றுப் பக்கத்தை விருப்பமை
+settings_pane_topsites_header=சிறந்த தளங்கள்
+settings_pane_highlights_header=மிளிர்ப்புகள்
+settings_pane_highlights_options_bookmarks=புத்தகக்குறிகள்
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=துணுக்குகள்
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=தொகு
+edit_topsites_edit_button=இத்தளத்தை தொகு
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=புதிய முக்கிய தளம்
+topsites_form_edit_header=முக்கிய தளத்தை தொகு
+topsites_form_title_label=தலைப்பு
+topsites_form_title_placeholder=தலைப்பை இடு
+topsites_form_url_label=URL
+topsites_form_image_url_label=தனிப்பயன் பட URL
+topsites_form_url_placeholder=உள்ளிடு (அ) ஒரு URL ஒட்டு
+topsites_form_use_image_link=தனிப்பயன் படத்தை பயன்படுத்தவும்…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=முன்தோற்றம்
+topsites_form_add_button=சேர்
+topsites_form_save_button=சேமி
+topsites_form_cancel_button=தவிர்
+topsites_form_url_validation=சரியான URL தேவை
+topsites_form_image_validation=படத்தை ஏற்றுவதில் தோல்வி. வேறு URL ஐ முயற்சிக்கவும்.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=பிரபலமான தலைப்புகள்:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=இன்னும் கதைகளைப் பார்க்கவும்
+
+highlights_empty_state=உலாவலைத் தொடங்கவும், மேலும் நாங்கள் சில சிறந்த கட்டுரைகள், காணொளிகள், மற்றும் நீங்கள் சமீபத்தில் பார்த்த பிற பக்கங்கள் அல்லது இங்கே புத்தகக்குறியிட்டவற்றைக் காட்டுவோம்.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=நீங்கள் முடித்துவிட்டீர்கள். {provider} இலிருந்து கூடுதல் கதைகளுக்கு பின்னர் பாருங்கள். காத்திருக்க முடியவில்லையா? இணையத்திலிருந்து கூடுதலான கதைகளைக் கண்டுபிடிக்க பிரபலமான தலைப்பைத் தேர்ந்தெடுங்கள்.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=மற்றொரு உலாவியின் புத்தகக்குறிகள், வரலாறு மற்றும் கடவுச்சொற்களுடன் பயர்பாக்சை முயற்சித்துப் பாருங்கள்.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=பரவாயில்லை
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=இப்போது இறக்கு
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=அச்சச்சோ, இந்த உள்ளடக்கத்தை ஏற்றுவதில் ஏதோ தவறு ஏற்பட்டது.
+error_fallback_default_refresh_suggestion=மீண்டும் முயற்சிக்க பக்கத்தை புதுப்பி.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=பகுதியை நீக்கவும்
+section_menu_action_collapse_section=பகுதியைச் சுருக்கு
+section_menu_action_expand_section=பகுதியை விரி
+section_menu_action_manage_section=பகுதியை நிர்வகி
+section_menu_action_add_topsite=முதன்மை தளத்தைச் சேர்
+section_menu_action_move_up=மேலே நகர்த்து
+section_menu_action_move_down=கீழே நகர்த்து
+section_menu_action_privacy_notice=தனியுரிமை அறிவிப்பு
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/te/strings.properties
@@ -0,0 +1,192 @@
+newtab_page_title=కొత్త ట్యాబు
+
+header_top_sites=మేటి సైట్లు
+header_highlights=విశేషాలు
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider}చే సిఫార్సు చేయబడినది
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr={title} కోసం సందర్భోచిత మెనుని తెరవండి
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=విభాగపు కంటెక్స్టు మెనూ తెరువు
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=సందర్శించారు
+type_label_bookmarked=ఇష్టాంశంగా గుర్తుపెట్టారు
+type_label_recommended=ట్రెండింగ్
+type_label_pocket=పాకెట్‌లో భద్రపరచినది
+type_label_downloaded=దింపుకున్నవి
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=ఇష్టాంశం
+menu_action_remove_bookmark=ఇష్టాంశాన్ని తొలగించు
+menu_action_open_new_window=కొత్త విండోలో తెరువు
+menu_action_open_private_window=కొత్త వ్యక్తిగత విండోలో తెరువు
+menu_action_dismiss=విస్మరించు
+menu_action_delete=చరిత్ర నుంచి తీసివేయి
+menu_action_pin=పిన్ను
+menu_action_unpin=పిన్ను తీసివేయి
+confirm_history_delete_p1=మీరు మీ చరిత్ర నుండి ఈ పేజీ యొక్క ప్రతి ఉదాహరణకు తొలగించాలనుకుంటున్నారా?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=ఈ చర్యను రద్దు చేయలేము.
+menu_action_save_to_pocket=Pocket కి సేవ్ చేయండి
+menu_action_delete_pocket=పాకెట్ నుండి తొలగించు
+menu_action_archive_pocket=పాకెట్‌లో ఆర్కయివ్ చెయ్యి
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=ఫైండర్‌లో చూపించు
+menu_action_show_file_windows=కలిగిఉన్న సంచయాన్ని తెరువు
+menu_action_show_file_linux=కలిగివున్న సంచయాన్ని తెరువు
+menu_action_show_file_default=దస్త్రాన్ని చూపించు
+menu_action_open_file=దస్త్రాన్ని తెరువు
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=దింపుకోలు లంకెను కాపీచేయి
+menu_action_go_to_download_page=దింపుకోళ్ళ పేజీకి వెళ్ళు
+menu_action_remove_download=చరిత్ర నుండి తొలగించు
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=వెతకండి
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} శోధన
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=జాలంలో వెతకండి
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=జాలంలో అత్యంత ఆసక్తికరమైన కథనాలు, మీరు చదివేవాటి ఆధారంగా ఎంచుకున్నవి. ఇప్పుడు Mozillaలో భాగమైన Pocket నుండి.
+section_disclaimer_topstories_linktext=ఇది ఎలా పనిచేస్తుందో తెలుసుకోండి.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=సరే, అర్థమయ్యింది
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox ముంగిలి విషయం
+prefs_home_description=మీ Firefox ముంగిలి తెరలో మీకు కావలసిన విషయాల్ని ఎంచుకోండి.
+prefs_restore_defaults_button=అప్రమేయాలను పునరుద్ధరించు
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} వరుస;{num} వరుసలు
+prefs_search_header=జాల వెతుకులాట
+prefs_topsites_description=మీరు తరచూ చూసే సైట్లు
+prefs_topstories_description2=ప్రపంచం నలుమూలలనుండి మీకోసం వ్యక్తిగతీకరించబడిన ఆసక్తికర సమాచారం
+prefs_topstories_options_sponsored_label=ప్రాయోజిక కథనాలు
+prefs_topstories_sponsored_learn_more=ఇంకా తెలుసుకోండి
+prefs_highlights_description=మీరు భద్రపరచిన లేదా సందర్శించిన సైట్ల నుండి ఎంపికచేసినవి
+prefs_highlights_options_visited_label=చూసిన పేజీలు
+prefs_highlights_options_download_label=ఇటీవలి దింపుకోలు
+prefs_highlights_options_pocket_label=పాకెట్‌కు భద్రపరచిన పేజీలు
+prefs_snippets_description=మొజిల్లా, ఫైర్‌ఫాక్స్ నుండి విశేషాలు
+settings_pane_button_label=మీ కొత్త ట్యాబు పేజీని మలచుకోండి
+settings_pane_header=కొత్త ట్యాబు అభిరుచులు
+settings_pane_body2=ఈ పేజీలో ఏమేం కనబడాలో ఎంచుకోండి.
+settings_pane_search_header=వెతకడం
+settings_pane_search_body=కొత్త ట్యాబు నుండే జాలంలో వెతకండి.
+settings_pane_topsites_header=మేటి సైట్లు
+settings_pane_topsites_body=మీరు ఎక్కువగా చూసే వెబ్‌సైట్లకు ఇట్టే వెళ్ళండి.
+settings_pane_topsites_options_showmore=రెండు వరుసలు చూపించు
+settings_pane_highlights_header=విశేషాలు
+settings_pane_highlights_body2=ఇటీవలే మీరు చూసిన లేదా ఇష్టపడిన ఆసక్తికరమైన విషయాలు మళ్ళీ మీ ముందుకొస్తాయి.
+settings_pane_highlights_options_bookmarks=ఇష్టాంశాలు
+settings_pane_highlights_options_visited=చూసిన సైట్లు
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=సంగతులు
+settings_pane_snippets_body=Firefox గురించి, అంతర్జాల సంస్కృతి గురించి, ఏదో ఒక సరదా పుకారు గురించి Mozilla వారు చెప్పే చిట్టి పొట్టి సంగతులు చదవండి.
+settings_pane_done_button=పూర్తయింది
+settings_pane_topstories_options_sponsored=ప్రాయోజిత కథనాలను చూపించు
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=మార్చు
+edit_topsites_edit_button=ఈ సైటును మార్చు
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=కొత్త మేటి సైటు
+topsites_form_edit_header=టాప్ సైట్ను సవరించండి
+topsites_form_title_label=శీర్షిక
+topsites_form_title_placeholder=శీర్షికను నమోదు చేయండి
+topsites_form_url_label=చిరునామా
+topsites_form_image_url_label=అభిమత చిత్రపు చిరునామా
+topsites_form_url_placeholder=URL ను టైప్ చేయండి లేదా అతికించండి
+topsites_form_use_image_link=అభిమత చిత్రాన్ని వాడు…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=మునుజూపు
+topsites_form_add_button=చేర్చు
+topsites_form_save_button=భద్రపరచు
+topsites_form_cancel_button=రద్దుచేయి
+topsites_form_url_validation=చెల్లుబాటు అయ్యే URL అవసరం
+topsites_form_image_validation=చిత్రాన్ని లోడు చెయ్యలేకపోయాం. మరో చిరునామా ప్రయత్నించండి.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=ప్రముఖ అంశాలు:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=మరిన్ని కథలను వీక్షించండి
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=తప్పక చూడాల్సిన మిక్కిలి-నాణ్యమైన విషయం పాకెట్ సహాయంతో. పాకెట్ ఇప్పుడు మొజిల్లాలో భాగం.
+
+highlights_empty_state=విహారించడం మొదలుపెట్టండి, మీరు ఈమధ్య చూసిన లేదా ఇష్టపడిన గొప్ప వ్యాసాలను, వీడియోలను, ఇతర పేజీలను ఇక్కడ చూపిస్తాం.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=మీరు పట్టుబడ్డారు. {provider} నుండి మరింత అగ్ర కథనాల కోసం తరువాత తనిఖీ చేయండి. వేచి ఉండలేరా? జాలములోని అంతటి నుండి మరింత గొప్ప కథనాలను కనుగొనడానికి ప్రసిద్ధ అంశం ఎంచుకోండి.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=మరొక విహారిణి లోని ఇష్టాంశాలు, చరిత్ర, సంకేతపదాలతో Firefoxను ప్రయత్నించండి.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=అడిగినందుకు ధన్యవాదాలు, వద్దు
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=ఇప్పుడే దిగుమతి చేయండి
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=అయ్యో, ఈ విషయం తేవడంలో ఏదో తప్పు దొర్లింది.
+error_fallback_default_refresh_suggestion=మళ్ళీ ప్రయత్నించడానికి పేజీని రీఫ్రెష్ చెయ్యండి.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=విభాగాన్ని తీసివేయి
+section_menu_action_collapse_section=విభాగాన్ని ముడిచివేయి
+section_menu_action_expand_section=విభాగాన్ని విస్తరించు
+section_menu_action_manage_section=విభాగ నిర్వహణ
+section_menu_action_add_topsite=మేటి సైటును చేర్చు
+section_menu_action_move_up=పైకి జరుపు
+section_menu_action_move_down=కిందకి జరుపు
+section_menu_action_privacy_notice=అంతరంగికత గమనిక
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/th/strings.properties
@@ -0,0 +1,200 @@
+newtab_page_title=แท็บใหม่
+
+header_top_sites=ไซต์เด่น
+header_highlights=รายการเด่น
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=แนะนำโดย {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=เปิดเมนูบริบทสำหรับ {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=เปิดเมนูบริบทของส่วน
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=เยี่ยมชมแล้ว
+type_label_bookmarked=เพิ่มที่คั่นหน้าแล้ว
+type_label_recommended=กำลังนิยม
+type_label_pocket=บันทึกไปยัง Pocket แล้ว
+type_label_downloaded=ดาวน์โหลดแล้ว
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=เพิ่มที่คั่นหน้า
+menu_action_remove_bookmark=เอาที่คั่นหน้าออก
+menu_action_open_new_window=เปิดในหน้าต่างใหม่
+menu_action_open_private_window=เปิดในหน้าต่างส่วนตัวใหม่
+menu_action_dismiss=ยกเลิก
+menu_action_delete=ลบออกจากประวัติ
+menu_action_pin=ปักหมุด
+menu_action_unpin=ถอนหมุด
+confirm_history_delete_p1=คุณแน่ใจหรือไม่ว่าต้องการลบทุกอินสแตนซ์ของหน้านี้ออกจากประวัติของคุณ?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=การกระทำนี้ไม่สามารถเลิกทำได้
+menu_action_save_to_pocket=บันทึกไปยัง Pocket
+menu_action_delete_pocket=ลบจาก Pocket
+menu_action_archive_pocket=เก็บถาวรใน Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=แสดงใน Finder
+menu_action_show_file_windows=เปิดโฟลเดอร์ที่บรรจุ
+menu_action_show_file_linux=เปิดโฟลเดอร์ที่บรรจุ
+menu_action_show_file_default=แสดงไฟล์
+menu_action_open_file=เปิดไฟล์
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=คัดลอกลิงก์ดาวน์โหลด
+menu_action_go_to_download_page=ไปยังหน้าดาวน์โหลด
+menu_action_remove_download=เอาออกจากประวัติ
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=ค้นหา
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=ค้นหา {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=ค้นหาเว็บ
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=เรื่องราวที่น่าสนใจที่สุดบนเว็บ เลือกตามสิ่งที่คุณอ่าน จาก Pocket ซึ่งขณะนี้เป็นส่วนหนึ่งของ Mozilla
+section_disclaimer_topstories_linktext=เรียนรู้วิธีการทำงาน
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=ตกลง เข้าใจแล้ว
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=เนื้อหาหน้าแรก Firefox
+prefs_home_description=เลือกเนื้อหาที่คุณต้องการในหน้าจอหน้าแรก Firefox ของคุณ
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} แถว
+prefs_search_header=การค้นหาเว็บ
+prefs_topsites_description=ไซต์ที่คุณเยี่ยมชมมากที่สุด
+prefs_topstories_description2=เนื้อหาที่ยอดเยี่ยมจากเว็บต่าง ๆ ปรับแต่งให้เป็นส่วนบุคคลเพื่อคุณ
+prefs_topstories_options_sponsored_label=เรื่องราวที่ได้รับการสนับสนุน
+prefs_topstories_sponsored_learn_more=เรียนรู้เพิ่มเติม
+prefs_highlights_description=การคัดเลือกไซต์ที่คุณได้บันทึกไว้หรือเยี่ยมชม
+prefs_highlights_options_visited_label=หน้าที่เยี่ยมชมแล้ว
+prefs_highlights_options_download_label=การดาวน์โหลดล่าสุด
+prefs_highlights_options_pocket_label=หน้าที่บันทึกไว้ใน Pocket
+prefs_snippets_description=ข้อมูลอัปเดตจาก Mozilla และ Firefox
+settings_pane_button_label=ปรับแต่งหน้าแท็บใหม่ของคุณ
+settings_pane_topsites_header=ไซต์เด่น
+settings_pane_highlights_header=รายการเด่น
+settings_pane_highlights_options_bookmarks=ที่คั่นหน้า
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=ส่วนย่อย
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=แก้ไข
+edit_topsites_edit_button=แก้ไขไซต์นี้
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=ไซต์เด่นใหม่
+topsites_form_edit_header=แก้ไขไซต์เด่น
+topsites_form_title_label=ชื่อเรื่อง
+topsites_form_title_placeholder=ป้อนชื่อเรื่อง
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL ภาพที่กำหนดเอง
+topsites_form_url_placeholder=พิมพ์หรือวาง URL
+topsites_form_use_image_link=ใช้ภาพที่กำหนดเอง…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=แสดงตัวอย่าง
+topsites_form_add_button=เพิ่ม
+topsites_form_save_button=บันทึก
+topsites_form_cancel_button=ยกเลิก
+topsites_form_url_validation=ต้องการ URL ที่ถูกต้อง
+topsites_form_image_validation=ไม่สามารถโหลดภาพ ลอง URL อื่น
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=หัวข้อยอดนิยม:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=ดูเรื่องราวเพิ่มเติม
+
+highlights_empty_state=เริ่มการท่องเว็บและเราจะแสดงบทความ, วิดีโอ และหน้าอื่น ๆ บางส่วนที่ยอดเยี่ยมที่คุณได้เยี่ยมชมหรือเพิ่มที่คั่นหน้าไว้ล่าสุดที่นี่
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=คุณได้อ่านเรื่องราวครบทั้งหมดแล้ว คุณสามารถกลับมาตรวจดูเรื่องราวเด่นจาก {provider} ได้ภายหลัง อดใจรอไม่ได้งั้นหรือ? เลือกหัวข้อยอดนิยมเพื่อค้นหาเรื่องราวที่ยอดเยี่ยมจากเว็บต่าง ๆ
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=ลอง Firefox ด้วยที่คั่นหน้า, ประวัติ และรหัสผ่านจากเบราว์เซอร์อื่น
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=ไม่ ขอบคุณ
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=นำเข้าตอนนี้
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=อุปส์ มีบางอย่างผิดพลาดในการโหลดเนื้อหานี้
+error_fallback_default_refresh_suggestion=เรียกหน้าใหม่เพื่อลองอีกครั้ง
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=เอาส่วนออก
+section_menu_action_collapse_section=ยุบส่วน
+section_menu_action_expand_section=ขยายส่วน
+section_menu_action_manage_section=จัดการส่วน
+section_menu_action_manage_webext=จัดการส่วนขยาย
+section_menu_action_add_topsite=เพิ่มไซต์เด่น
+section_menu_action_move_up=ย้ายขึ้น
+section_menu_action_move_down=ย้ายลง
+section_menu_action_privacy_notice=ประกาศความเป็นส่วนตัว
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=นำ Firefox ไปกับคุณ
+firstrun_content=รับที่คั่นหน้า, ประวัติ, รหัสผ่าน และการตั้งค่าอื่น ๆ ของคุณในอุปกรณ์ทั้งหมดของคุณ
+firstrun_learn_more_link=เรียนรู้เพิ่มเติมเกี่ยวกับบัญชี Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=ป้อนอีเมลของคุณ
+firstrun_form_sub_header=เพื่อดำเนินการต่อไปยัง Firefox Sync
+
+firstrun_email_input_placeholder=อีเมล
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_terms_of_service=เงื่อนไขการให้บริการ
+firstrun_privacy_notice=ประกาศความเป็นส่วนตัว
+
+firstrun_continue_to_login=ดำเนินการต่อ
+firstrun_skip_login=ข้ามขั้นตอนนี้
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/tl/strings.properties
@@ -0,0 +1,232 @@
+newtab_page_title=Bagong Tab
+default_label_loading=Pagkarga…
+
+header_top_sites=Tuktok na mga Site
+header_stories=Nangunguna na mga Kwento
+header_highlights=Naka-highlight
+header_visit_again=Bisitahin Muli
+header_bookmarks=Kamakailang mga Bookmark
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Inirekomenda ni {provider}
+# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
+# meant to inform that section contains no information because
+# the user hasn't added any bookmarks.
+header_bookmarks_placeholder=Wala kang anumang mga bookmark.
+# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
+# corresponding content (stories) provider
+header_stories_from=mula sa
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Buksan ang menu ng konteksto para sa {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Buksan ang menu ng konteksto ng seksyon
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Binisita
+type_label_bookmarked=Bookmarked
+type_label_synced=Naka-sync mula sa ibang kagamitan
+type_label_recommended=Nagte-trend
+type_label_pocket=I-save sa Pocket
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=Bukas
+type_label_topic=Topiko
+type_label_now=Ngayon
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Bookmark
+menu_action_remove_bookmark=Alisin ang Bookmark
+menu_action_copy_address=Kopyahin ang Address
+menu_action_email_link=Email Link…
+menu_action_open_new_window=Buksan sa isang Bagong Window
+menu_action_open_private_window=Buksan sa isang Pribadong Bago na Window
+menu_action_dismiss=Paalisin
+menu_action_delete=Tanggalin mula History
+menu_action_pin=I-pin
+menu_action_unpin=I-unpin
+confirm_history_delete_p1=Sigurado ka bang gusto mong tanggalin ang bawat pagkakataon ng pahinang ito mula sa iyong kasaysayan?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Ang aksyon na ito ay hindi na mababawi.
+menu_action_save_to_pocket=I-save sa Pocket
+menu_action_delete_pocket=I-delete sa Pocket
+menu_action_archive_pocket=Mag-archive sa Pocket
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with=Maghanap ng mga {search_term} na may:
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Hanapin
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} Hanapin
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Hanapin sa Web
+search_settings=Baguhin ang mga Setting ng Paghahanap
+
+# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the
+# (?) icon that would show a section's description with optional feedback link.
+section_info_option=Impormasyon
+section_info_send_feedback=Magbigay ng Feedback
+section_info_privacy_notice=Abiso sa Privacy
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Ang pinaka-kagiliw-giliw na mga kwento sa web, pinili batay sa kung ano ang iyong nabasa. Mula sa Pocket, bahagi na ngayon ng Mozilla.
+section_disclaimer_topstories_linktext=Alamin kung paano ito gumagana.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Sige, nakuha ko
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=Maligayang pagdating sa bagong tab
+welcome_body=Firefox ay gagamit ng puwang upang ipakita ang iyong mga pinaka-kaugnay na bookmark, artikulo, video, at mga pahina ng kamakailan na iyong binisita, kaya maaari kang bumalik sa mga ito ng madali.
+welcome_label=Ang pagkilala sa iyong Highlights
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=<1m
+time_label_minute={number}m
+time_label_hour={number}h
+time_label_day={number}d
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Nilalaman ng Home ng Firefox
+prefs_home_description=Piliin kung anong nilalaman ang gusto mo sa iyong screen ng Home ng Firefox.
+prefs_restore_defaults_button=Ibalik sa dating ayos
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} hilera;{num} mga hilera
+prefs_search_header=Paghahanap sa Web
+prefs_topsites_description=Ang mga site na iyong pinupuntahan
+prefs_topstories_description=Maaaring makaligtaan ang mataas na kalidad na nilalaman
+# LOCALIZATION NOTE (prefs_topstories_show_sponsored_label): {provider} is
+# replaced by the name of the content provider for this section, e.g., "Pocket"
+prefs_topstories_show_sponsored_label={provider} Mga Na-sponsor na Kwento
+prefs_topstories_sponsored_learn_more=Matuto ng higit pa
+prefs_highlights_description=Ang isang seleksyon ng mga site na iyong nai-save o binisita
+prefs_snippets_description=Mga Update mula sa Mozilla at Firefox
+settings_pane_button_label=I-customize ang iyong pahina ng Bagong Tab
+settings_pane_header=Bagong Kagustuhan na Tab
+settings_pane_body2=Piliin kung ano ang gusto mong makita sa pahinang ito.
+settings_pane_search_header=Paghahanap
+settings_pane_search_body=Hanapin sa Web mula sa iyong bagong tab.
+settings_pane_topsites_header=Tuktok na mga Site
+settings_pane_topsites_body=Ma-access ang mga website na karamihang binibisita.
+settings_pane_topsites_options_showmore=Ipakita ang dalawang mga hanay
+settings_pane_bookmarks_header=Kamakailang mga Bookmark
+settings_pane_bookmarks_body=Ang iyong mga bagong gawang bookmark ay nsa isang madaling gamiting lokasyon.
+settings_pane_visit_again_header=Bisitahin Muli
+settings_pane_visit_again_body=Ipapakita sa iyo ng Firefox ang mga bahagi ng iyong kasaysayan ng pagba-browse na maaaring gusto mong matandaan o makabalik.
+settings_pane_highlights_header=Mga highlight
+settings_pane_highlights_body2=Hanapin ang iyong daan pabalik sa mga kagiliw-giliw na bagay na kamakailan mong binisita o na-bookmark.
+settings_pane_highlights_options_bookmarks=Mga bookmark
+settings_pane_highlights_options_visited=Mga binisitang site
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Mga snippet
+settings_pane_snippets_body=Magbasa ng maikli at matamis na mga update mula sa Mozilla tungkol sa Firefox, kultura sa internet, at paminsan-minsang random na meme.
+settings_pane_done_button=Tapos
+settings_pane_topstories_options_sponsored=Ipakita ang Mga Na-sponsor na Kuwento
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=I-edit
+edit_topsites_button_label=I-customize ang iyong Tuktok na mga seksyon ng Sites
+edit_topsites_showmore_button=Magpakita ng higit pa
+edit_topsites_showless_button=Magpakita ng mas kaunti
+edit_topsites_done_button=Tapos
+edit_topsites_pin_button=I-pin sa site na ito
+edit_topsites_unpin_button=I-unpin ang site na ito
+edit_topsites_edit_button=I-edit ang site na ito
+edit_topsites_dismiss_button=I-dismiss sa site na ito
+edit_topsites_add_button=Idagdag
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Bagong nangungunang site
+topsites_form_edit_header=I-edit ang nangungunang site
+topsites_form_title_label=Pamagat
+topsites_form_title_placeholder=Magpasok ng isang pamagat
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL ng Custom na Larawan
+topsites_form_url_placeholder=I-type o i-paste ang URL
+topsites_form_use_image_link=Gamitin ang URL custom na larawan...
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=I-preview
+topsites_form_add_button=Idagdag
+topsites_form_save_button=I-save
+topsites_form_cancel_button=Kanselahin
+topsites_form_url_validation=Wastong URL ang kinakailangan
+topsites_form_image_validation=Nabigo ang pag-load ng larawan. Subukan ang ibang URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Tanyag na mga paksa:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Tignan ang higit pang mga kuwento
+# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
+# to Pocket as part of the feedback form.
+pocket_feedback_header=Ang pinakamahusay sa web, na gawa ng higit sa 25 milyong tao.
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane and
+# below (pocket_feedback_header) to provide more information about Pocket.
+pocket_description=Tuklasin ang mataas na kalidad na nilalaman na maaari mong makaligtaan, sa tulong ng Pocket, ay bahagi na ngayon ng Mozilla.
+
+highlights_empty_state=Magsimulang mag-browse, at ipapakita namin ang ilan sa mga magagandang artikulo, video, at iba pang mga pahina na kamakailan mong binisita o na-bookmark dito.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Nakahabol ka na. Bumalik sa ibang pagkakataon para sa higit pang mga nangungunang kuwento mula sa {provider}. Hindi makapaghintay? Pumili ng isang tanyag na paksa upang makahanap ng higit pang mahusay na mga kuwento mula sa buong web.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Subukan ang Firefox gamit ang mga bookmark, kasaysayan at mga password mula sa isa pang browser.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Salamat na lang
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Angkatin Ngayon
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Oops, may naganap na mali sa paglo-load ng nilalamang ito.
+error_fallback_default_refresh_suggestion=I-refresh ang pahina upang subukang muli.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Alisin ang Seksyon
+section_menu_action_collapse_section=I-collapse ang Seksyon
+section_menu_action_expand_section=Palawakin ang Seksyon
+section_menu_action_manage_section=Pamahalaan ang Seksyon
+section_menu_action_add_topsite=Magdagdag ng Nangungunang Site
+section_menu_action_move_up=Ilipat Up
+section_menu_action_move_down=Ilipat sa Baba
+section_menu_action_privacy_notice=Paunawa sa Privacy
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/tr/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Yeni Sekme
+
+header_top_sites=Sık Kullanılan Siteler
+header_highlights=Öne Çıkanlar
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} öneriyor
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr={title} sağ tıklama menüsünü aç
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Bölüm bağlam menüsünü aç
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Ziyaret etmiştiniz
+type_label_bookmarked=Yer imlerinizde
+type_label_recommended=Popüler
+type_label_pocket=Pocket’a kaydedildi
+type_label_downloaded=İndirildi
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Yer imlerine ekle
+menu_action_remove_bookmark=Yer imini sil
+menu_action_open_new_window=Yeni pencerede aç
+menu_action_open_private_window=Yeni gizli pencerede aç
+menu_action_dismiss=Kapat
+menu_action_delete=Geçmişten sil
+menu_action_pin=Sabitle
+menu_action_unpin=Sabitleneni kaldır
+confirm_history_delete_p1=Bu sayfanın tüm kayıtlarını geçmişinizden silmek istediğinizden emin misiniz?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Bu işlem geri alınamaz.
+menu_action_save_to_pocket=Pocket’a kaydet
+menu_action_delete_pocket=Pocket’tan sil
+menu_action_archive_pocket=Pocket’ta arşivle
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Finder’da göster
+menu_action_show_file_windows=Bulunduğu klasörü aç
+menu_action_show_file_linux=Bulunduğu dizini aç
+menu_action_show_file_default=Dosyayı göster
+menu_action_open_file=Dosyayı aç
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=İndirme bağlantısını kopyala
+menu_action_go_to_download_page=İndirme sayfasına git
+menu_action_remove_download=Geçmişten kaldır
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Ara
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} Araması
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Web’de ara
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Daha önce okuduklarınıza dayanarak seçtiğimiz en ilginç yazılar. Mozilla ailesinin yeni üyesi Pocket’tan.
+section_disclaimer_topstories_linktext=Nasıl çalıştığını görün.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Tamam, anladım
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox giriş sayfası içeriği
+prefs_home_description=Firefox giriş sayfasında görmek istediğiniz içerikleri seçin.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} satır;{num} satır
+prefs_search_header=Web araması
+prefs_topsites_description=En çok ziyaret ettiğiniz siteler
+prefs_topstories_description2=İnternetin her yanından sizin için seçtiğimiz kaliteli içerikler
+prefs_topstories_options_sponsored_label=Sponsorlu haberler
+prefs_topstories_sponsored_learn_more=Daha fazla bilgi al
+prefs_highlights_description=Kaydettiğiniz ve ziyaret ettiğiniz sitelerin bir seçkisi
+prefs_highlights_options_visited_label=Ziyaret ettiğim sayfalar
+prefs_highlights_options_download_label=Son indirme
+prefs_highlights_options_pocket_label=Pocket’a kaydettiğim sayfalar
+prefs_snippets_description=Mozilla ve Firefox’tan haberler
+settings_pane_button_label=Yeni Sekme sayfanızı özelleştirin
+settings_pane_topsites_header=Sık kullanılan siteler
+settings_pane_highlights_header=Öne çıkanlar
+settings_pane_highlights_options_bookmarks=Yer imleri
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Duyurular
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Düzenle
+edit_topsites_edit_button=Bu siteyi düzenle
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Yeni sık kullanılan site
+topsites_form_edit_header=Sık kullanılan siteyi düzenle
+topsites_form_title_label=Başlık
+topsites_form_title_placeholder=Başlık yazın
+topsites_form_url_label=Adres
+topsites_form_image_url_label=Özel resim adresi
+topsites_form_url_placeholder=Adres yazın ve yapıştırın
+topsites_form_use_image_link=Özel resim kullan…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Ön izleme yap
+topsites_form_add_button=Ekle
+topsites_form_save_button=Kaydet
+topsites_form_cancel_button=İptal
+topsites_form_url_validation=Geçerli bir adres gerekli
+topsites_form_image_validation=Resim yüklenemedi. Başka bir adres deneyin.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Popüler konular:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Daha fazla yazı göster
+
+highlights_empty_state=Gezinmeye başlayın. Son zamanlarda baktığınız veya yer imlerinize eklediğiniz bazı güzel makaleleri, videoları ve diğer sayfaları burada göstereceğiz.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Hepsini bitirdiniz. Yeni {provider} haberleri için daha fazla yine gelin. Beklemek istemiyor musunuz? İlginç yazılara ulaşmak için popüler konulardan birini seçebilirsiniz.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Öteki tarayıcılarınızdaki yer imlerinizi, geçmişinizi ve parolalarınızı Firefox’a aktarabilirsiniz.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Gerek yok
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Olur, aktaralım
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Bu içerik yüklenirken bir hata oluştu.
+error_fallback_default_refresh_suggestion=Yeniden denemek için sayfayı tazeleyin.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Bölümü sil
+section_menu_action_collapse_section=Bölümü daralt
+section_menu_action_expand_section=Bölümü genişlet
+section_menu_action_manage_section=Bölümü yönet
+section_menu_action_manage_webext=Eklentiyi yönet
+section_menu_action_add_topsite=Sık kullanılan site ekle
+section_menu_action_move_up=Yukarı taşı
+section_menu_action_move_down=Aşağı taşı
+section_menu_action_privacy_notice=Gizlilik bildirimi
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Firefox’u yanınızda taşıyın
+firstrun_content=Yer imlerinizi, geçmişinizi, parolalarınızı ve diğer ayarlarınızı tüm cihazlarınızda kullanabilirsiniz.
+firstrun_learn_more_link=Firefox Hesapları hakkında bilgi alın
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Firefox Sync’e devam etmek için
+firstrun_form_sub_header=e-posta adresinizi yazın.
+
+firstrun_email_input_placeholder=E-posta
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Devam ederseniz {terms} ve {privacy} kabul etmiş sayılırsınız.
+firstrun_terms_of_service=Kullanım Koşullarını
+firstrun_privacy_notice=Gizlilik Bildirimini
+
+firstrun_continue_to_login=Devam et
+firstrun_skip_login=Bu adımı atla
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/uk/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=Нова вкладка
+
+header_top_sites=Популярні сайти
+header_highlights=Обране
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Рекомендовано {provider}
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=Відкрити контекстне меню для {title}
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Відкрити контекстне меню розділу
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Відвідано
+type_label_bookmarked=Закладено
+type_label_recommended=Популярне
+type_label_pocket=Збережено в Pocket
+type_label_downloaded=Завантажено
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Додати до закладок
+menu_action_remove_bookmark=Вилучити закладку
+menu_action_open_new_window=Відкрити в новому вікні
+menu_action_open_private_window=Відкрити в приватному вікні
+menu_action_dismiss=Сховати
+menu_action_delete=Видалити з історії
+menu_action_pin=Прикріпити
+menu_action_unpin=Відкріпити
+confirm_history_delete_p1=Ви справді хочете видалити всі записи про цю сторінку з історії?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Цю дію неможливо скасувати.
+menu_action_save_to_pocket=Зберегти в Pocket
+menu_action_delete_pocket=Видалити з Pocket
+menu_action_archive_pocket=Архівувати в Pocket
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Показати у Finder
+menu_action_show_file_windows=Відкрити теку з файлом
+menu_action_show_file_linux=Відкрити теку з файлом
+menu_action_show_file_default=Показати файл
+menu_action_open_file=Відкрити файл
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Копіювати адресу завантаження
+menu_action_go_to_download_page=Перейти на сторінку завантаження
+menu_action_remove_download=Видалити з історії
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Пошук
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Шукати з {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Пошук в Інтернеті
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Найцікавіші матеріали в Інтернеті, обрані на основі того, що ви читаєте. З Pocket, який тепер входить до складу Mozilla.
+section_disclaimer_topstories_linktext=Дізнайтеся, як це працює.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Гаразд, зрозуміло
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Домівка Firefox
+prefs_home_description=Оберіть бажаний вміст для показу в домівці Firefox.
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} рядок;{num} рядки;{num} рядків
+prefs_search_header=Веб пошук
+prefs_topsites_description=Сайти, які ви відвідуєте найчастіше
+prefs_topstories_description2=Чудові матеріали з усього інтернету, відібрані спеціально для вас
+prefs_topstories_options_sponsored_label=Матеріали від спонсорів
+prefs_topstories_sponsored_learn_more=Докладніше
+prefs_highlights_description=Відібрані веб-сайти, які ви зберегли чи відвідали
+prefs_highlights_options_visited_label=Відвідані сторінки
+prefs_highlights_options_download_label=Останні завантаження
+prefs_highlights_options_pocket_label=Збережене в Pocket
+prefs_snippets_description=Оновлення від Mozilla та Firefox
+settings_pane_button_label=Налаштуйте свою сторінку нової вкладки
+settings_pane_topsites_header=Популярні сайти
+settings_pane_highlights_header=Обране
+settings_pane_highlights_options_bookmarks=Закладки
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Фрагменти
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Змінити
+edit_topsites_edit_button=Змінити цей сайт
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Новий популярний сайт
+topsites_form_edit_header=Редагувати популярний сайт
+topsites_form_title_label=Заголовок
+topsites_form_title_placeholder=Введіть назву
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL власного зображення
+topsites_form_url_placeholder=Введіть або вставте URL-адресу
+topsites_form_use_image_link=Використати власне зображення…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Попередній перегляд
+topsites_form_add_button=Додати
+topsites_form_save_button=Зберегти
+topsites_form_cancel_button=Скасувати
+topsites_form_url_validation=Необхідна дійсна адреса URL
+topsites_form_image_validation=Не вдалося завантажити зображення. Спробуйте інший URL.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Популярні теми:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Переглянути більше історій
+
+highlights_empty_state=Почніть перегляд і ми покажемо вам деякі чудові статті, відео та інші сторінки, нещодавно відвідані чи збережені вами до закладок тут.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Готово. Перевірте згодом, щоб побачити більше матеріалів від {provider}. Не хочете чекати? Оберіть популярну тему, щоб знайти більше цікавих матеріалів з усього Інтернету.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Спробуйте Firefox із закладками, історією та паролями з іншого браузера.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Ні, дякую
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Імпортувати зараз
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Ой, при завантаженні цього вмісту щось пішло не так.
+error_fallback_default_refresh_suggestion=Оновіть сторінку, щоб спробувати знову.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Вилучити розділ
+section_menu_action_collapse_section=Згорнути розділ
+section_menu_action_expand_section=Розгорнути розділ
+section_menu_action_manage_section=Керувати розділом
+section_menu_action_manage_webext=Керувати розширенням
+section_menu_action_add_topsite=Додати до популярних сайтів
+section_menu_action_move_up=Вгору
+section_menu_action_move_down=Вниз
+section_menu_action_privacy_notice=Повідомлення про приватність
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Візьміть Firefox з собою
+firstrun_content=Ваші закладки, історія, паролі та інші налаштування на всіх ваших пристроях.
+firstrun_learn_more_link=Дізнайтеся більше про обліковий запис Firefox
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=Введіть свою адресу е-пошти
+firstrun_form_sub_header=для продовження в Синхронізації Firefox.
+
+firstrun_email_input_placeholder=Е-пошта
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=Продовжуючи, ви приймаєте {terms} і {privacy}.
+firstrun_terms_of_service=Умови надання послуги
+firstrun_privacy_notice=Повідомлення про приватність
+
+firstrun_continue_to_login=Продовжити
+firstrun_skip_login=Пропустити цей крок
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/ur/strings.properties
@@ -0,0 +1,148 @@
+newtab_page_title=نیا ٹیب
+
+header_top_sites=بہترین سائٹیں
+header_highlights=شہ سرخياں
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} کی جانب سے تجویز کردہ
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=دورہ شدہ
+type_label_bookmarked=نشان شدہ
+type_label_recommended=رجحان سازی
+type_label_pocket=Pocket میں محفوظ شدہ
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=نشانی
+menu_action_remove_bookmark=نشانى ہٹائيں
+menu_action_open_new_window=نئے دریچے میں کھولیں
+menu_action_open_private_window=نئی نجی دریچے میں کھولیں
+menu_action_dismiss=برخاست کریں
+menu_action_delete=تاریخ سے حذف کریں
+menu_action_pin=پن
+menu_action_unpin=ان پن
+confirm_history_delete_p1=کیا آپ کو یقین ہے کہ آپ اس صفحہ کا ہر نمونہ اپنے سابقات سے حذف کرنا چاہتے ہیں؟
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=یہ عمل کلعدم نہیں ہو سکتا۔
+menu_action_save_to_pocket=Pocket میں محفوظ کریں
+menu_action_delete_pocket=Pocket سے جزف کریں
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=تلاش
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} پر تلاش کریں
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=ويب پر تلاش کريں
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories_linktext=سیکھیں کہ یہ کیسے کام کرتا ہے۔
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=ٹھیک ہے مجھے سمجھ آگئی ہے
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox ابتائی مواد
+prefs_restore_defaults_button=طےشدہ بحال کریں
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_topsites_description=سائٹس جو آُپ سب سے زیادہ ملاحظہ کرتے ہیں
+prefs_topstories_description=اعلی میعار کا مواد جو شاید آپ بصورت دیگر کھو دیں
+# LOCALIZATION NOTE (prefs_topstories_show_sponsored_label): {provider} is
+# replaced by the name of the content provider for this section, e.g., "Pocket"
+prefs_topstories_sponsored_learn_more=مزید سیکھیں
+prefs_snippets_description=Mozilla اورFirefox کی جانب سے تازہ کاریاں
+settings_pane_button_label=اپنے نئے ٹیب کہ صفحہ کی تخصیص کریں
+settings_pane_header=نئے َٹیب کی ترجیحات
+settings_pane_body2=انتخاب کریں آپ اس صفحہ پر کیا دیکھنا چاہیں گے۔
+settings_pane_search_header=تلاش
+settings_pane_search_body=اپنے نئے ٹیب سے وہب پر تلاش کریں۔
+settings_pane_topsites_header=بہترین سائٹیں
+settings_pane_topsites_body=اپنی سب سے زیادہ دورہ کردہ ویب سائٹ تک رسائی حاصل کریں۔
+settings_pane_topsites_options_showmore=دو قطاریں دکھائیں
+settings_pane_highlights_header=شہ سرخياں
+settings_pane_highlights_options_bookmarks=نشانیاں
+settings_pane_highlights_options_visited=ملاحظہ کیے گئے سائٹس
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=سنپیٹ
+settings_pane_done_button=ہوگیا
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=تدوین
+edit_topsites_edit_button=اس سائٹ کی تدوین کریں
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=نئی بہترین سائٹ
+topsites_form_edit_header=بہترین سائٹٹ کیی تدوین کریں
+topsites_form_title_label=عنوان
+topsites_form_title_placeholder=ایک عنوان داخل کریں
+topsites_form_url_label=URL
+topsites_form_url_placeholder=ٹائپ کریں یا ایک URL چسباں کریں
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=پیش منظر
+topsites_form_add_button=اظافہ کریں
+topsites_form_save_button=محفوظ کریں
+topsites_form_cancel_button=منسوخ کریں
+topsites_form_url_validation=جائز URL درکار ہے
+topsites_form_image_validation=نقش لوڈ ہونے میں ناکام رہا۔ براہ مہربانی ایک مختلف URL کو آزمائیں۔
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=مشہور مضامین:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=مزید کہانیاں دیکھیں
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=نہیں شکریہ
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=ابھی درآمد کری
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_move_up=اوپر کریں
+section_menu_action_move_down=نیچے کریں
+section_menu_action_privacy_notice=رازداری کا نوٹس
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/uz/strings.properties
@@ -0,0 +1,192 @@
+newtab_page_title=Yangi ichki oyna
+
+header_top_sites=Ommabop saytlar
+header_highlights=Saralangan saytlar
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} tomonidan tavsiya qilingan
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr={title} uchun menyu matnini ochish
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=Bo‘lim kontekst menyusini ochish
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Kirilgan
+type_label_bookmarked=Xatcho‘pga qo‘shilgan
+type_label_recommended=Trendda
+type_label_pocket=Pocket xizmatiga saqlandi
+type_label_downloaded=Yuklab olindi
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Xatcho‘p
+menu_action_remove_bookmark=Xatcho‘pni olib tashlash
+menu_action_open_new_window=Yangi oynada ochish
+menu_action_open_private_window=Yangi maxfiy oynada ochish
+menu_action_dismiss=Rad etish
+menu_action_delete=Tarixdan o‘chirish
+menu_action_pin=Yopishtirish
+menu_action_unpin=Ajratish
+confirm_history_delete_p1=Ushbu sahifaning har bir nusxasini tarixingizdan o‘chirmoqchimisiz?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Bu amalni ortga qaytarib bo‘lmaydi.
+menu_action_save_to_pocket=Pocket xizmatiga saqlash
+menu_action_delete_pocket=Pocket xizmatidan o‘chirish
+menu_action_archive_pocket=Pocket orqali arxivlash
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=Topkichda ko‘rsatish
+menu_action_show_file_windows=Saqlangan jildni ochish
+menu_action_show_file_linux=Saqlangan jildni ochish
+menu_action_show_file_default=Faylni ko‘rsatish
+menu_action_open_file=Faylni ochish
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=Havoladan nusxa olish
+menu_action_go_to_download_page=Yuklab olish sahifasiga o‘tish
+menu_action_remove_download=Tarixdan olib tashlash
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Qidiruv
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} Qidiruv bilan izlash
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Internetda izlash
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=Internetdagi eng qiziqarli maqolalar siz o‘qiyotgan ma’lumotlar asosida. Hozirda Mozillaning qismiga aylangan Pocket xizmatidan.
+section_disclaimer_topstories_linktext=Uning qanday ishlashini o‘rganing.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ok, tushundim
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox bosh sahifasi
+prefs_home_description=Firefox bosh sahifasida qaysi kontent chiqishi kerakligini tanlang.
+prefs_restore_defaults_button=Asliga tiklash
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} qator;{num} qator
+prefs_search_header=Internetdan qidirish
+prefs_topsites_description=Tez-tez tashrif buyuradigan saytlaringiz
+prefs_topstories_description2=Siz uchun moslangan internetdagi ajoyib kontent
+prefs_topstories_options_sponsored_label=Homiylik maqolalari
+prefs_topstories_sponsored_learn_more=Batafsil
+prefs_highlights_description=Saqlangan yoki tashrif buyurgan saralangan saytlaringiz
+prefs_highlights_options_visited_label=Kirilgan sahifalar
+prefs_highlights_options_download_label=Oxirgi yuklanmalar
+prefs_highlights_options_pocket_label=Pocket’ga saqlangan sahifalar
+prefs_snippets_description=Mozilla va Firefox yangilanishlari
+settings_pane_button_label=Yangi ichki oyna sahifasini sozlash
+settings_pane_header=Yangi ichki oyna parametrlari
+settings_pane_body2=Bu sahifada nimani ko‘rishni xohlasangiz, o‘shani tanlang.
+settings_pane_search_header=Izlash
+settings_pane_search_body=Yangi ichki oynada internetdan izlash.
+settings_pane_topsites_header=Ommabop saytlar
+settings_pane_topsites_body=Eng ko‘p kirilgan saytlarga kirish.
+settings_pane_topsites_options_showmore=Ikki qatorda ko‘rsatish
+settings_pane_highlights_header=Ajratilgan saytlar
+settings_pane_highlights_body2=So‘nggi kirilgan qiziqarli saytlar yoki xatcho‘plarga qaytish yo‘lini toping.
+settings_pane_highlights_options_bookmarks=Xatcho‘plar
+settings_pane_highlights_options_visited=Kirilgan saytlar
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=Parchalar
+settings_pane_snippets_body=Mozilladan internet madaniyati, tasodifiy memlar, Firefox haqidagi qisqa va oxirgi yangiliklarni o‘qib turing.
+settings_pane_done_button=Tayyor
+settings_pane_topstories_options_sponsored=Homiylik maqolalarini ko‘rsatish
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Tahrirlash
+edit_topsites_edit_button=Bu saytni tahrirlash
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=Yangi ommabop sayt
+topsites_form_edit_header=Ommabop saytni tahrirlash
+topsites_form_title_label=Sarlavha
+topsites_form_title_placeholder=Nomini kiriting
+topsites_form_url_label=URL
+topsites_form_image_url_label=URL rasmi
+topsites_form_url_placeholder=URL manzilini kiriting
+topsites_form_use_image_link=Boshqa rasmdan foydalaning…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=Ko’rib chiqish
+topsites_form_add_button=Qo‘shish
+topsites_form_save_button=Saqlash
+topsites_form_cancel_button=Bekor qilish
+topsites_form_url_validation=URL manzilini bexato kiriting
+topsites_form_image_validation=Rasm yuklanmadi. Boshqa URL manzildan foydalaning.
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Mashhur mavzular:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Yana maqolalar ko‘rish
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane
+# to provide more information about Pocket.
+pocket_description=Endi Mozilla tarkibiga kiruvchi Pocket xizmati yordamida yuqori sifatli kontentni o‘zingiz uchun kashf qiling. Endi siz o‘qishga vaqtingiz bo‘lmagan saytlarni keyinroq ham o‘qiy olasiz.
+
+highlights_empty_state=Saytlarni ko‘rishni boshlashingiz bilan biz sizga ajoyib maqola, video va oxirgi kirilgan yoki xatcho‘plarga qo‘shilgan sahifalarni ko‘rsatamiz.
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=Hammasini ko‘rib chiqdingiz. {provider}dan so‘nggi hikoyalarni o‘qish uchun keyinroq bu sahifaga qayting. Kuta olmaysizmi? Internetdan eng zo‘r hikoyalarni topish uchun ommabop mavzuni tanlang.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Firefox brauzerida boshqa brauzerdagi xatcho‘p, tarix va parollarni ochib ko‘ring.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Yoʻq, kerak emas
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Hozir import qilish
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=Kontent yuklanayotganda qandaydir xatolik yuz berdi.
+error_fallback_default_refresh_suggestion=Yana urinib ko‘rish uchun sahifani yangilang.
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=Qismni olib tashlash
+section_menu_action_collapse_section=Qismni yig‘ish
+section_menu_action_expand_section=Qismni yoyish
+section_menu_action_manage_section=Qismni boshqarish
+section_menu_action_add_topsite=Ommabop saytga qo‘shish
+section_menu_action_move_up=Tepaga ko‘tarish
+section_menu_action_move_down=Pastga tushirish
+section_menu_action_privacy_notice=Maxfiylik eslatmalari
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/vi/strings.properties
@@ -0,0 +1,165 @@
+newtab_page_title=Tab mới
+default_label_loading=Đang tải…
+
+header_top_sites=Trang web hàng đầu
+header_stories=Câu chuyện hàng đầu
+header_highlights=Nổi bật
+header_visit_again=Truy cập lại
+header_bookmarks=Các bookmark gần đây
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by=Được đề nghị bởi {provider}
+# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
+# meant to inform that section contains no information because
+# the user hasn't added any bookmarks.
+header_bookmarks_placeholder=Bạn chưa có bookmark nào.
+# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
+# corresponding content (stories) provider
+header_stories_from=từ
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=Đã truy cập
+type_label_bookmarked=Đã được đánh dấu
+type_label_synced=Đồng bộ từ thiết bị khác
+type_label_recommended=Xu hướng
+# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
+type_label_open=Mở
+type_label_topic=Chủ đề
+type_label_now=Bây giờ
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=Đánh dấu
+menu_action_remove_bookmark=Xóa đánh dấu
+menu_action_copy_address=Chép địa chỉ
+menu_action_email_link=Liên kết Email...
+menu_action_open_new_window=Mở trong Cửa Sổ Mới
+menu_action_open_private_window=Mở trong cửa sổ riêng tư mới
+menu_action_dismiss=Bỏ qua
+menu_action_delete=Xóa từ lịch xử
+menu_action_pin=Ghim
+menu_action_unpin=Bỏ ghim
+confirm_history_delete_p1=Bạn có chắc bạn muốn xóa bỏ mọi thứ của trang này từ lịch sử?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=Hành động này không thể hoàn tác.
+menu_action_save_to_pocket=Lưu vào Pocket
+
+# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
+# for what the user has typed in the search input field, e.g. 'Search for ' +
+# search_term + 'with:' becomes 'Search for abc with:'
+# The search engine name is displayed as an icon and does not need a translation
+search_for_something_with=Tìm {search_term} với:
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=Tìm kiếm
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header=Công cụ tìm kiếm {search_engine_name}
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=Tìm trên mạng
+search_settings=Thay đổi thiết lập tìm kiếm
+
+# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the
+# (?) icon that would show a section's description with optional feedback link.
+section_info_option=Thông tin
+section_info_send_feedback=Gửi phản hồi
+section_info_privacy_notice=Chính sách riêng tư
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=Ok, đã hiểu
+
+# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
+# first-run experience when there's no data to display yet
+welcome_title=Chào mừng đến với tab mới
+welcome_body=Firefox sẽ sử dụng không gian này để hiển thị của bạn có liên quan nhất đánh dấu, bài viết, video và các trang bạn đã truy cập gần đây, do đó, bạn có thể quay lại công việc một cách dễ dàng.
+welcome_label=Đang xác định phần nổi bật của bạn
+
+# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
+# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
+time_label_less_than_minute=<1phút
+time_label_minute={number}phút
+time_label_hour={number}giờ
+time_label_day={number}ngày
+
+# LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar.
+settings_pane_button_label=Tùy biến trang Tab mới
+settings_pane_header=Tùy chỉnh cho tab mới
+settings_pane_body2=Chọn những gì bạn thấy trên trang này.
+settings_pane_search_header=Tìm kiếm
+settings_pane_search_body=Tìm kiếm Web từ thẻ mới của bạn.
+settings_pane_topsites_header=Các trang Web hàng đầu
+settings_pane_topsites_body=Truy cập vào các trang web mà bạn truy cập vào nhiều nhất.
+settings_pane_topsites_options_showmore=Hiển thị hai hàng
+settings_pane_bookmarks_header=Trang đánh dấu gần đây
+settings_pane_visit_again_header=Truy cập lại
+settings_pane_highlights_header=Nổi bật
+settings_pane_highlights_options_bookmarks=Trang đánh dấu
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_done_button=Xong
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=Chỉnh sửa
+edit_topsites_showmore_button=Xem thêm
+edit_topsites_showless_button=Hiển thị ngắn gọn lại
+edit_topsites_done_button=Xong
+edit_topsites_pin_button=Ghim trang này
+edit_topsites_unpin_button=Bỏ ghim trang này
+edit_topsites_edit_button=Chỉnh sửa trang web này
+edit_topsites_dismiss_button=Bỏ qua trang này
+edit_topsites_add_button=Thêm
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_url_placeholder=Nhập hoặc dán URL
+topsites_form_add_button=Thêm
+topsites_form_save_button=Lưu lại
+topsites_form_cancel_button=Hủy bỏ
+topsites_form_url_validation=Yêu cầu URL hợp lệ
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=Các chủ đề phổ biến:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=Xem nhiều câu chuyện hơn
+# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
+# to Pocket as part of the feedback form.
+pocket_feedback_header=Tốt nhất của web, được quản lý bởi hơn 25 triệu người.
+# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane and
+# below (pocket_feedback_header) to provide more information about Pocket.
+
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=Thử Firefox với trang đánh dấu, lịch sử và mật khẩu từ trình duyệt khác.
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=Không, cảm ơn
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=Nhập ngay bây giờ
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/zh-CN/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=新标签页
+
+header_top_sites=常用网站
+header_highlights=集锦
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} 推荐
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=打开 {title} 的快捷菜单
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=打开板块快捷菜单
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=曾经访问
+type_label_bookmarked=已加书签
+type_label_recommended=趋势
+type_label_pocket=已保存到 Pocket
+type_label_downloaded=已下载
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=添加书签
+menu_action_remove_bookmark=移除书签
+menu_action_open_new_window=新建窗口打开
+menu_action_open_private_window=新建隐私浏览窗口打开
+menu_action_dismiss=隐藏
+menu_action_delete=从历史记录中删除
+menu_action_pin=固定
+menu_action_unpin=取消固定
+confirm_history_delete_p1=确定删除此页面在您的历史记录中的所有记录?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=此操作不能撤销。
+menu_action_save_to_pocket=保存到 Pocket
+menu_action_delete_pocket=从 Pocket 删除
+menu_action_archive_pocket=在 Pocket 中存档
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=显示于访达
+menu_action_show_file_windows=打开所在文件夹
+menu_action_show_file_linux=打开所在文件夹
+menu_action_show_file_default=显示文件
+menu_action_open_file=打开文件
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=复制下载链接
+menu_action_go_to_download_page=前往下载页面
+menu_action_remove_download=从历史记录中移除
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=搜索
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} 搜索
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=在网络上搜索
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=根据您的阅读喜好推荐网上的有趣报道。出自 Pocket,现在是 Mozilla 的一部分。
+section_disclaimer_topstories_linktext=了解它的工作原理。
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=我明白了
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox 主页内容
+prefs_home_description=选择要在您的 Firefox 主页上显示的板块。
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} 行
+prefs_search_header=网络搜索
+prefs_topsites_description=您经常访问的网站
+prefs_topstories_description2=来自网络的精彩内容,为您量身打造
+prefs_topstories_options_sponsored_label=赞助内容
+prefs_topstories_sponsored_learn_more=详细了解
+prefs_highlights_description=您访问过或保存过的网站精选
+prefs_highlights_options_visited_label=访问过的页面
+prefs_highlights_options_download_label=最近下载
+prefs_highlights_options_pocket_label=保存在 Pocket 的页面
+prefs_snippets_description=来自 Mozilla 和 Firefox 的快讯
+settings_pane_button_label=定制您的新标签页
+settings_pane_topsites_header=常用网站
+settings_pane_highlights_header=集锦
+settings_pane_highlights_options_bookmarks=书签
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=只言片语
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=编辑
+edit_topsites_edit_button=编辑此网站
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=新建常用网站
+topsites_form_edit_header=编辑常用网站
+topsites_form_title_label=标题
+topsites_form_title_placeholder=输入标题
+topsites_form_url_label=网址
+topsites_form_image_url_label=自定义图像网址
+topsites_form_url_placeholder=输入或粘贴网址
+topsites_form_use_image_link=使用自定义图像…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=预览
+topsites_form_add_button=添加
+topsites_form_save_button=保存
+topsites_form_cancel_button=取消
+topsites_form_url_validation=需要有效的网址
+topsites_form_image_validation=图像加载失败。请尝试其他网址。
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=热门主题:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=查看更多文章
+
+highlights_empty_state=开始网上冲浪之旅吧,之后这里会显示您最近看过或加了书签的精彩文章、视频与其他页面。
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=所有文章都读完啦!晚点再来,{provider} 将推荐更多热门文章。等不及了?选择一个热门话题,找到更多网上的好文章。
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=把在其他浏览器中保存的书签、历史记录和密码带到 Firefox 吧。
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=不用了
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=立即导入
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=哎呀,加载此内容出错了。
+error_fallback_default_refresh_suggestion=刷新页面以重试。
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=移除板块
+section_menu_action_collapse_section=折叠板块
+section_menu_action_expand_section=展开板块
+section_menu_action_manage_section=管理板块
+section_menu_action_manage_webext=管理扩展
+section_menu_action_add_topsite=添加常用网站
+section_menu_action_move_up=上移
+section_menu_action_move_down=下移
+section_menu_action_privacy_notice=隐私声明
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=随身携带 Firefox
+firstrun_content=在您的所有设备上获取您的书签、历史记录、密码以及其他设置。
+firstrun_learn_more_link=详细了解 Firefox 账户
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=请输入您的电子邮箱
+firstrun_form_sub_header=继续使用 Firefox 同步服务。
+
+firstrun_email_input_placeholder=电子邮件
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=若您选择继续,即表示您同意我们的{terms}和{privacy}。
+firstrun_terms_of_service=服务条款
+firstrun_privacy_notice=隐私声明
+
+firstrun_continue_to_login=继续
+firstrun_skip_login=跳过此步骤
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/locales/zh-TW/strings.properties
@@ -0,0 +1,201 @@
+newtab_page_title=新分頁
+
+header_top_sites=熱門網站
+header_highlights=精選網站
+# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
+# of the corresponding content provider.
+header_recommended_by={provider} 推薦
+
+# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
+# the context menu button is focused/active. Title is the label or hostname of
+# the site.
+context_menu_button_sr=開啟 {title} 的右鍵選單
+
+# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
+# the section edit context menu button is focused/active.
+section_context_menu_button_sr=開啟段落內容選單
+
+# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
+# context on how the element is related to the user, e.g. type indicates that
+# the page is bookmarked, or is currently open on another device
+type_label_visited=造訪過的網站
+type_label_bookmarked=已加入書籤
+type_label_recommended=熱門
+type_label_pocket=已儲存至 Pocket
+type_label_downloaded=已下載
+
+# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
+# menu and are meant as a call to action for a given page.
+# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
+# bookmarks"
+menu_action_bookmark=書籤
+menu_action_remove_bookmark=移除書籤
+menu_action_open_new_window=用新視窗開啟
+menu_action_open_private_window=用新隱私視窗開啟
+menu_action_dismiss=隱藏
+menu_action_delete=從瀏覽紀錄刪除
+menu_action_pin=釘選
+menu_action_unpin=取消釘選
+confirm_history_delete_p1=您確定要刪除此頁面的所有瀏覽紀錄?
+# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
+# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
+# page from history.
+confirm_history_delete_notice_p2=無法還原此操作。
+menu_action_save_to_pocket=儲存至 Pocket
+menu_action_delete_pocket=從 Pocket 刪除
+menu_action_archive_pocket=在 Pocket 裡封存
+
+# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
+# found in the context menu of an item that has been downloaded. The intention behind
+# "this action" is that it will show where the downloaded file exists on the file system
+# for each operating system.
+menu_action_show_file_mac_os=顯示於 Finder
+menu_action_show_file_windows=開啟所在資料夾
+menu_action_show_file_linux=開啟所在資料夾
+menu_action_show_file_default=顯示檔案
+menu_action_open_file=開啟檔案
+
+# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
+# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
+# link that belongs to this downloaded item"
+menu_action_copy_download_link=複製下載鏈結
+menu_action_go_to_download_page=前往下載頁面
+menu_action_remove_download=自下載記錄移除
+
+# LOCALIZATION NOTE (search_button): This is screenreader only text for the
+# search button.
+search_button=搜尋
+
+# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
+# showing search suggestions. {search_engine_name} is replaced with the name of
+# the current default search engine. e.g. 'Google Search'
+search_header={search_engine_name} 搜尋
+
+# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
+# the user hasn't typed anything yet.
+search_web_placeholder=搜尋 Web
+
+# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
+# the topstories section title to provide additional information about
+# how the stories are selected.
+section_disclaimer_topstories=依照您閱讀過的內容,向您推薦網路上最有趣的內容。本功能由 Pocket(Mozilla 的一員)提供。
+section_disclaimer_topstories_linktext=了解運作原理。
+# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
+# the button used to acknowledge, and hide this disclaimer in the future.
+section_disclaimer_topstories_buttontext=好的,知道了
+
+# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
+# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
+# in English, while "Home" should be localized matching the about:preferences
+# sidebar mozilla-central string for the panel that has preferences related to
+# what is shown for the homepage, new windows, and new tabs.
+prefs_home_header=Firefox 首頁內容
+prefs_home_description=選擇要在您的 Firefox 首頁顯示哪些內容。
+# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
+# plural forms used in a drop down of multiple row options (1 row, 2 rows).
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+prefs_section_rows_option={num} 行
+prefs_search_header=網頁搜尋
+prefs_topsites_description=最常造訪的網站
+prefs_topstories_description2=網路上的各種超棒內容,為您量身打造
+prefs_topstories_options_sponsored_label=贊助內容
+prefs_topstories_sponsored_learn_more=了解更多
+prefs_highlights_description=您儲存或造訪過的網站精選
+prefs_highlights_options_visited_label=造訪過的頁面
+prefs_highlights_options_download_label=最新下載
+prefs_highlights_options_pocket_label=已將頁面儲存至 Pocket
+prefs_snippets_description=來自 Mozilla 及 Firefox 的大小事
+settings_pane_button_label=自訂您的新分頁頁面
+settings_pane_topsites_header=熱門網站
+settings_pane_highlights_header=精選網站
+settings_pane_highlights_options_bookmarks=書籤
+# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
+# traditionally on about:home. Alternative translation options: "Small Note" or
+# something that expresses the idea of "a small message, shortened from
+# something else, and non-essential but also not entirely trivial and useless."
+settings_pane_snippets_header=隻字片語
+
+# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
+# dialog.
+edit_topsites_button_text=編輯
+edit_topsites_edit_button=編輯此網站
+
+# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
+topsites_form_add_header=新增熱門網站
+topsites_form_edit_header=編輯熱門網站
+topsites_form_title_label=標題
+topsites_form_title_placeholder=輸入標題
+topsites_form_url_label=網址
+topsites_form_image_url_label=自訂圖片網址
+topsites_form_url_placeholder=輸入或貼上網址
+topsites_form_use_image_link=使用自訂圖片…
+# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
+topsites_form_preview_button=預覽
+topsites_form_add_button=新增
+topsites_form_save_button=儲存
+topsites_form_cancel_button=取消
+topsites_form_url_validation=請輸入有效的網址
+topsites_form_image_validation=圖片載入失敗,請改用不同網址。
+
+# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
+# trending stories section and precedes a list of links to popular topics.
+pocket_read_more=熱門主題:
+# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
+# end of the list of popular topic links.
+pocket_read_even_more=檢視更多文章
+
+highlights_empty_state=開始上網,我們就會把您在網路上發現的好文章、影片、剛加入書籤的頁面顯示於此。
+# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
+# in the space that would have shown a few stories, this is shown instead.
+# {provider} is replaced by the name of the content provider for this section.
+topstories_empty_state=所有文章都讀完啦!晚點再來,{provider} 將提供更多推薦故事。等不及了?選擇熱門主題,看看 Web 上各式精采資訊。
+
+# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
+# import their browser profile from another browser they might be using.
+manual_migration_explanation2=試試將其他瀏覽器的書籤、瀏覽記錄與密碼匯入 Firefox。
+# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
+# process of importing another browser’s profile into Firefox.
+manual_migration_cancel_button=不必了
+# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
+# of importing another browser’s profile profile into Firefox.
+manual_migration_import_button=立即匯入
+
+# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
+# action link are shown in each section of UI that fails to render
+error_fallback_default_info=唉唷,載入內容時發生錯誤。
+error_fallback_default_refresh_suggestion=請重新整理頁面再試一次。
+
+# LOCALIZATION NOTE (section_menu_action_*).  These strings are displayed in the section
+# context menu and are meant as a call to action for the given section.
+section_menu_action_remove_section=移除段落
+section_menu_action_collapse_section=摺疊段落
+section_menu_action_expand_section=展開段落
+section_menu_action_manage_section=管理段落
+section_menu_action_manage_webext=管理擴充套件
+section_menu_action_add_topsite=新增熱門網站
+section_menu_action_move_up=上移
+section_menu_action_move_down=下移
+section_menu_action_privacy_notice=隱私權公告
+
+# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
+# firstrun of the browser, they give an introduction to Firefox and Sync.
+firstrun_title=Firefox 隨身帶著走
+firstrun_content=在您的任何裝置上取得書籤、瀏覽紀錄、密碼及其他設定。
+firstrun_learn_more_link=了解 Firefox Accounts 的更多資訊
+
+# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
+# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
+# firstrun_form_header is displayed more boldly as the call to action.
+firstrun_form_header=輸入您的電子郵件地址
+firstrun_form_sub_header=繼續前往 Firefox Sync。
+
+firstrun_email_input_placeholder=電子郵件
+
+# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
+# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
+firstrun_extra_legal_links=若繼續,代表您同意{terms}及{privacy}。
+firstrun_terms_of_service=服務條款
+firstrun_privacy_notice=隱私權公告
+
+firstrun_continue_to_login=繼續
+firstrun_skip_login=跳過這步
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/package-lock.json
@@ -0,0 +1,11849 @@
+{
+  "name": "activity-streams",
+  "version": "1.14.3",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "@octokit/rest": {
+      "version": "15.3.0",
+      "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.3.0.tgz",
+      "integrity": "sha512-c1nR42ZhZI014lJerh73H2lOLu/3aLXVlpT7gJwg2UqUHQ58lKSGaDbGlRWpwXl7R8bxHeIf0oKpfZjq0Mn+Tw==",
+      "dev": true,
+      "requires": {
+        "before-after-hook": "1.1.0",
+        "btoa-lite": "1.0.0",
+        "debug": "3.1.0",
+        "http-proxy-agent": "2.1.0",
+        "https-proxy-agent": "2.2.1",
+        "lodash": "4.17.4",
+        "node-fetch": "2.1.2",
+        "url-template": "2.0.8"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "node-fetch": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
+          "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=",
+          "dev": true
+        }
+      }
+    },
+    "@sinonjs/formatio": {
+      "version": "2.0.0",
+      "resolved": "http://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz",
+      "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==",
+      "dev": true,
+      "requires": {
+        "samsam": "1.3.0"
+      }
+    },
+    "@types/node": {
+      "version": "9.4.1",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-9.4.1.tgz",
+      "integrity": "sha512-9ESUxmXt1Isc1xKfDBZ7tpULyTPY5ZCywcfvQTXoLUqP+n4D+MBH+0n75hdzrcmfCc3eWByOi27+GLmMuAvcUA==",
+      "dev": true
+    },
+    "abbrev": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
+      "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
+      "dev": true
+    },
+    "accepts": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
+      "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
+      "dev": true,
+      "requires": {
+        "mime-types": "2.1.18",
+        "negotiator": "0.6.1"
+      },
+      "dependencies": {
+        "mime-db": {
+          "version": "1.33.0",
+          "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
+          "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
+          "dev": true
+        },
+        "mime-types": {
+          "version": "2.1.18",
+          "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
+          "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
+          "dev": true,
+          "requires": {
+            "mime-db": "1.33.0"
+          }
+        }
+      }
+    },
+    "acorn": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz",
+      "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==",
+      "dev": true
+    },
+    "acorn-dynamic-import": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz",
+      "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=",
+      "dev": true,
+      "requires": {
+        "acorn": "4.0.13"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "4.0.13",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
+          "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
+          "dev": true
+        }
+      }
+    },
+    "acorn-jsx": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+      "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
+      "dev": true,
+      "requires": {
+        "acorn": "3.3.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+          "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
+          "dev": true
+        }
+      }
+    },
+    "addressparser": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz",
+      "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y=",
+      "dev": true,
+      "optional": true
+    },
+    "after": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
+      "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=",
+      "dev": true
+    },
+    "agent-base": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz",
+      "integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==",
+      "dev": true,
+      "requires": {
+        "es6-promisify": "5.0.0"
+      }
+    },
+    "ajv": {
+      "version": "5.5.2",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+      "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+      "dev": true,
+      "requires": {
+        "co": "4.6.0",
+        "fast-deep-equal": "1.0.0",
+        "fast-json-stable-stringify": "2.0.0",
+        "json-schema-traverse": "0.3.1"
+      },
+      "dependencies": {
+        "co": {
+          "version": "4.6.0",
+          "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+          "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+          "dev": true
+        }
+      }
+    },
+    "ajv-keywords": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
+      "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
+      "dev": true
+    },
+    "align-text": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
+      "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2",
+        "longest": "1.0.1",
+        "repeat-string": "1.6.1"
+      }
+    },
+    "amdefine": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+      "dev": true
+    },
+    "amqplib": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.5.2.tgz",
+      "integrity": "sha512-l9mCs6LbydtHqRniRwYkKdqxVa6XMz3Vw1fh+2gJaaVgTM6Jk3o8RccAKWKtlhT1US5sWrFh+KKxsVUALURSIA==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "bitsyntax": "0.0.4",
+        "bluebird": "3.5.1",
+        "buffer-more-ints": "0.0.2",
+        "readable-stream": "1.1.14",
+        "safe-buffer": "5.1.1"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+          "dev": true,
+          "optional": true
+        },
+        "readable-stream": {
+          "version": "1.1.14",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+          "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "0.0.1",
+            "string_decoder": "0.10.31"
+          }
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "ansi-escapes": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
+      "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==",
+      "dev": true
+    },
+    "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
+    },
+    "anymatch": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
+      "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
+      "dev": true,
+      "requires": {
+        "micromatch": "2.3.11",
+        "normalize-path": "2.1.1"
+      }
+    },
+    "aproba": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+      "dev": true
+    },
+    "are-we-there-yet": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
+      "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
+      "dev": true,
+      "requires": {
+        "delegates": "1.0.0",
+        "readable-stream": "2.3.3"
+      }
+    },
+    "argparse": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
+      "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "1.0.3"
+      }
+    },
+    "arr-diff": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+      "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+      "dev": true,
+      "requires": {
+        "arr-flatten": "1.1.0"
+      }
+    },
+    "arr-flatten": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+      "dev": true
+    },
+    "arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true
+    },
+    "array-filter": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz",
+      "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=",
+      "dev": true
+    },
+    "array-find-index": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+      "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+      "dev": true
+    },
+    "array-includes": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz",
+      "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
+      "dev": true,
+      "requires": {
+        "define-properties": "1.1.2",
+        "es-abstract": "1.9.0"
+      }
+    },
+    "array-map": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz",
+      "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=",
+      "dev": true
+    },
+    "array-reduce": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz",
+      "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=",
+      "dev": true
+    },
+    "array-slice": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
+      "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=",
+      "dev": true
+    },
+    "array-union": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+      "dev": true,
+      "requires": {
+        "array-uniq": "1.0.3"
+      }
+    },
+    "array-uniq": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+      "dev": true
+    },
+    "array-unique": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+      "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+      "dev": true
+    },
+    "arraybuffer.slice": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
+      "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==",
+      "dev": true
+    },
+    "arrify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "dev": true
+    },
+    "asap": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+    },
+    "asn1": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+      "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
+      "dev": true
+    },
+    "asn1.js": {
+      "version": "4.9.2",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz",
+      "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "inherits": "2.0.3",
+        "minimalistic-assert": "1.0.0"
+      }
+    },
+    "assert": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
+      "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
+      "dev": true,
+      "requires": {
+        "util": "0.10.3"
+      }
+    },
+    "assert-plus": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+      "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+      "dev": true
+    },
+    "assertion-error": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz",
+      "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=",
+      "dev": true
+    },
+    "assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true
+    },
+    "ast-types": {
+      "version": "0.11.3",
+      "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.3.tgz",
+      "integrity": "sha512-XA5o5dsNw8MhyW0Q7MWXJWc4oOzZKbdsEJq45h7c8q/d9DwWZ5F2ugUc1PuMLPGsUnphCt/cNDHu8JeBbxf1qA==",
+      "dev": true,
+      "optional": true
+    },
+    "async": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+      "dev": true
+    },
+    "async-each": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+      "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
+      "dev": true
+    },
+    "async-foreach": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
+      "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
+      "dev": true
+    },
+    "async-limiter": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
+      "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
+      "dev": true
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "atob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz",
+      "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=",
+      "dev": true
+    },
+    "aws-sign2": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+      "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+      "dev": true
+    },
+    "aws4": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+      "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
+      "dev": true
+    },
+    "axios": {
+      "version": "0.15.3",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.15.3.tgz",
+      "integrity": "sha1-LJ1jiy4ZGgjqHWzJiOrda6W9wFM=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "follow-redirects": "1.0.0"
+      },
+      "dependencies": {
+        "follow-redirects": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz",
+          "integrity": "sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "debug": "2.6.9"
+          }
+        }
+      }
+    },
+    "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.3",
+      "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz",
+      "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==",
+      "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.4",
+        "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.4",
+        "source-map": "0.5.7",
+        "trim-right": "1.0.1"
+      }
+    },
+    "babel-helper-builder-react-jsx": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz",
+      "integrity": "sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0",
+        "esutils": "2.0.2"
+      }
+    },
+    "babel-helper-function-name": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
+      "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
+      "dev": true,
+      "requires": {
+        "babel-helper-get-function-arity": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-get-function-arity": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
+      "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-helper-remap-async-to-generator": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
+      "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
+      "dev": true,
+      "requires": {
+        "babel-helper-function-name": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-traverse": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "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-loader": {
+      "version": "7.1.4",
+      "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.4.tgz",
+      "integrity": "sha512-/hbyEvPzBJuGpk9o80R0ZyTej6heEOr59GoEUtn8qFKbnx4cJm9FWES6J/iv644sYgrtVw9JJQkjaLW/bqb5gw==",
+      "dev": true,
+      "requires": {
+        "find-cache-dir": "1.0.0",
+        "loader-utils": "1.1.0",
+        "mkdirp": "0.5.1"
+      },
+      "dependencies": {
+        "loader-utils": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+          "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+          "dev": true,
+          "requires": {
+            "big.js": "3.2.0",
+            "emojis-list": "2.1.0",
+            "json5": "0.5.1"
+          }
+        }
+      }
+    },
+    "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-plugin-jsm-to-commonjs": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-jsm-to-commonjs/-/babel-plugin-jsm-to-commonjs-0.4.0.tgz",
+      "integrity": "sha1-eBgITBlMWsH/yUokv6Dtxzfxi/s=",
+      "dev": true
+    },
+    "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-async-functions": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
+      "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
+      "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",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
+      "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=",
+      "dev": true
+    },
+    "babel-plugin-syntax-object-rest-spread": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
+      "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
+      "dev": true
+    },
+    "babel-plugin-transform-async-to-module-method": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-module-method/-/babel-plugin-transform-async-to-module-method-6.24.1.tgz",
+      "integrity": "sha1-kQmgiYd5S0EcshOFDOk17C8CnNs=",
+      "dev": true,
+      "requires": {
+        "babel-helper-remap-async-to-generator": "6.24.1",
+        "babel-plugin-syntax-async-functions": "6.13.0",
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-es2015-modules-commonjs": {
+      "version": "6.26.2",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz",
+      "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-strict-mode": "6.24.1",
+        "babel-runtime": "6.26.0",
+        "babel-template": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-flow-strip-types": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz",
+      "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-flow": "6.18.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-object-rest-spread": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz",
+      "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-object-rest-spread": "6.13.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-react-display-name": {
+      "version": "6.25.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz",
+      "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-react-jsx": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz",
+      "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=",
+      "dev": true,
+      "requires": {
+        "babel-helper-builder-react-jsx": "6.26.0",
+        "babel-plugin-syntax-jsx": "6.18.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-react-jsx-self": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz",
+      "integrity": "sha1-322AqdomEqEh5t3XVYvL7PBuY24=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-jsx": "6.18.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-react-jsx-source": {
+      "version": "6.22.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz",
+      "integrity": "sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-jsx": "6.18.0",
+        "babel-runtime": "6.26.0"
+      }
+    },
+    "babel-plugin-transform-strict-mode": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
+      "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "babel-types": "6.26.0"
+      }
+    },
+    "babel-polyfill": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
+      "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "core-js": "2.5.5",
+        "regenerator-runtime": "0.10.5"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "2.5.5",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.5.tgz",
+          "integrity": "sha1-sU3ek2xkDAV5prUMq8wTLdYSfjs=",
+          "dev": true
+        },
+        "regenerator-runtime": {
+          "version": "0.10.5",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
+          "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
+          "dev": true
+        }
+      }
+    },
+    "babel-preset-flow": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz",
+      "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-transform-flow-strip-types": "6.22.0"
+      }
+    },
+    "babel-preset-react": {
+      "version": "6.24.1",
+      "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz",
+      "integrity": "sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A=",
+      "dev": true,
+      "requires": {
+        "babel-plugin-syntax-jsx": "6.18.0",
+        "babel-plugin-transform-react-display-name": "6.25.0",
+        "babel-plugin-transform-react-jsx": "6.24.1",
+        "babel-plugin-transform-react-jsx-self": "6.22.0",
+        "babel-plugin-transform-react-jsx-source": "6.22.0",
+        "babel-preset-flow": "6.23.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.3",
+        "babel-runtime": "6.26.0",
+        "core-js": "2.5.5",
+        "home-or-tmp": "2.0.0",
+        "lodash": "4.17.4",
+        "mkdirp": "0.5.1",
+        "source-map-support": "0.4.18"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "2.5.5",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.5.tgz",
+          "integrity": "sha1-sU3ek2xkDAV5prUMq8wTLdYSfjs=",
+          "dev": true
+        }
+      }
+    },
+    "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.1",
+        "regenerator-runtime": "0.11.0"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "2.5.1",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz",
+          "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=",
+          "dev": true
+        }
+      }
+    },
+    "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.4"
+      }
+    },
+    "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.4"
+      }
+    },
+    "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.4",
+        "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
+    },
+    "backo2": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
+      "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=",
+      "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
+    },
+    "base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "requires": {
+        "cache-base": "1.0.1",
+        "class-utils": "0.3.6",
+        "component-emitter": "1.2.1",
+        "define-property": "1.0.0",
+        "isobject": "3.0.1",
+        "mixin-deep": "1.3.1",
+        "pascalcase": "0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "1.0.2"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "1.0.0",
+            "is-data-descriptor": "1.0.0",
+            "kind-of": "6.0.2"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "base64-arraybuffer": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
+      "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=",
+      "dev": true
+    },
+    "base64-js": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
+      "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==",
+      "dev": true
+    },
+    "base64id": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
+      "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=",
+      "dev": true
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+      "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "tweetnacl": "0.14.5"
+      }
+    },
+    "before-after-hook": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.1.0.tgz",
+      "integrity": "sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA==",
+      "dev": true
+    },
+    "better-assert": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
+      "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
+      "dev": true,
+      "requires": {
+        "callsite": "1.0.0"
+      }
+    },
+    "big.js": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
+      "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
+      "dev": true
+    },
+    "binary-extensions": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz",
+      "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=",
+      "dev": true
+    },
+    "bitsyntax": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.0.4.tgz",
+      "integrity": "sha1-6xDMb4K4xJDj6FaY8H6D1G4MuoI=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "buffer-more-ints": "0.0.2"
+      }
+    },
+    "bl": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz",
+      "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "readable-stream": "2.0.6"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "2.0.6",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
+          "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "1.0.7",
+            "string_decoder": "0.10.31",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "blob": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
+      "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=",
+      "dev": true
+    },
+    "block-stream": {
+      "version": "0.0.9",
+      "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
+      "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3"
+      }
+    },
+    "bluebird": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
+      "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
+      "dev": true
+    },
+    "bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "body-parser": {
+      "version": "1.18.2",
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
+      "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
+      "dev": true,
+      "requires": {
+        "bytes": "3.0.0",
+        "content-type": "1.0.4",
+        "debug": "2.6.9",
+        "depd": "1.1.2",
+        "http-errors": "1.6.3",
+        "iconv-lite": "0.4.19",
+        "on-finished": "2.3.0",
+        "qs": "6.5.1",
+        "raw-body": "2.3.2",
+        "type-is": "1.6.16"
+      }
+    },
+    "boolbase": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
+      "dev": true
+    },
+    "boom": {
+      "version": "2.10.1",
+      "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+      "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+      "dev": true,
+      "requires": {
+        "hoek": "2.16.3"
+      }
+    },
+    "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"
+      }
+    },
+    "braces": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+      "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+      "dev": true,
+      "requires": {
+        "expand-range": "1.8.2",
+        "preserve": "0.2.0",
+        "repeat-element": "1.1.2"
+      }
+    },
+    "brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "browser-stdout": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+      "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+      "dev": true
+    },
+    "browserify-aes": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz",
+      "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==",
+      "dev": true,
+      "requires": {
+        "buffer-xor": "1.0.3",
+        "cipher-base": "1.0.4",
+        "create-hash": "1.1.3",
+        "evp_bytestokey": "1.0.3",
+        "inherits": "2.0.3",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "browserify-cipher": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz",
+      "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=",
+      "dev": true,
+      "requires": {
+        "browserify-aes": "1.1.1",
+        "browserify-des": "1.0.0",
+        "evp_bytestokey": "1.0.3"
+      }
+    },
+    "browserify-des": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz",
+      "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=",
+      "dev": true,
+      "requires": {
+        "cipher-base": "1.0.4",
+        "des.js": "1.0.0",
+        "inherits": "2.0.3"
+      }
+    },
+    "browserify-rsa": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+      "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "randombytes": "2.0.6"
+      }
+    },
+    "browserify-sign": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
+      "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "browserify-rsa": "4.0.1",
+        "create-hash": "1.1.3",
+        "create-hmac": "1.1.6",
+        "elliptic": "6.4.0",
+        "inherits": "2.0.3",
+        "parse-asn1": "5.1.0"
+      }
+    },
+    "browserify-zlib": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+      "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+      "dev": true,
+      "requires": {
+        "pako": "1.0.6"
+      }
+    },
+    "btoa-lite": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz",
+      "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=",
+      "dev": true
+    },
+    "buffer-from": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz",
+      "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==",
+      "dev": true
+    },
+    "buffer-more-ints": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz",
+      "integrity": "sha1-JrOIXRD6E9t/wBquOquHAZngEkw=",
+      "dev": true
+    },
+    "buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
+    "buildmail": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/buildmail/-/buildmail-4.0.1.tgz",
+      "integrity": "sha1-h393OLeHKYccmhBeO4N9K+EaenI=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "addressparser": "1.0.1",
+        "libbase64": "0.1.0",
+        "libmime": "3.0.0",
+        "libqp": "1.1.0",
+        "nodemailer-fetch": "1.6.0",
+        "nodemailer-shared": "1.1.0",
+        "punycode": "1.4.1"
+      }
+    },
+    "builtin-modules": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+      "dev": true
+    },
+    "builtin-status-codes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+      "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+      "dev": true
+    },
+    "bytes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+      "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+      "dev": true
+    },
+    "cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "dev": true,
+      "requires": {
+        "collection-visit": "1.0.0",
+        "component-emitter": "1.2.1",
+        "get-value": "2.0.6",
+        "has-value": "1.0.0",
+        "isobject": "3.0.1",
+        "set-value": "2.0.0",
+        "to-object-path": "0.3.0",
+        "union-value": "1.0.0",
+        "unset-value": "1.0.0"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "caller-path": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+      "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
+      "dev": true,
+      "requires": {
+        "callsites": "0.2.0"
+      }
+    },
+    "callsite": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
+      "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=",
+      "dev": true
+    },
+    "callsites": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+      "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
+      "dev": true
+    },
+    "camelcase": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+      "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
+      "dev": true
+    },
+    "camelcase-keys": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+      "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+      "dev": true,
+      "requires": {
+        "camelcase": "2.1.1",
+        "map-obj": "1.0.1"
+      }
+    },
+    "caseless": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
+      "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=",
+      "dev": true
+    },
+    "center-align": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
+      "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
+      "dev": true,
+      "requires": {
+        "align-text": "0.1.4",
+        "lazy-cache": "1.0.4"
+      }
+    },
+    "chai": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz",
+      "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=",
+      "dev": true,
+      "requires": {
+        "assertion-error": "1.0.2",
+        "check-error": "1.0.2",
+        "deep-eql": "3.0.1",
+        "get-func-name": "2.0.0",
+        "pathval": "1.1.0",
+        "type-detect": "4.0.5"
+      }
+    },
+    "chai-json-schema": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/chai-json-schema/-/chai-json-schema-1.5.0.tgz",
+      "integrity": "sha1-aWBxnkD3H9Wzd8koLlyaRnmUdPY=",
+      "dev": true,
+      "requires": {
+        "jsonpointer.js": "0.4.0",
+        "tv4": "1.2.7"
+      }
+    },
+    "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"
+      }
+    },
+    "chardet": {
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
+      "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
+      "dev": true
+    },
+    "check-error": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+      "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
+      "dev": true
+    },
+    "cheerio": {
+      "version": "1.0.0-rc.2",
+      "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.2.tgz",
+      "integrity": "sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=",
+      "dev": true,
+      "requires": {
+        "css-select": "1.2.0",
+        "dom-serializer": "0.1.0",
+        "entities": "1.1.1",
+        "htmlparser2": "3.9.2",
+        "lodash": "4.17.4",
+        "parse5": "3.0.3"
+      }
+    },
+    "chokidar": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
+      "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
+      "dev": true,
+      "requires": {
+        "anymatch": "1.3.2",
+        "async-each": "1.0.1",
+        "fsevents": "1.1.2",
+        "glob-parent": "2.0.0",
+        "inherits": "2.0.3",
+        "is-binary-path": "1.0.1",
+        "is-glob": "2.0.1",
+        "path-is-absolute": "1.0.1",
+        "readdirp": "2.1.0"
+      }
+    },
+    "ci-info": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.2.tgz",
+      "integrity": "sha512-uTGIPNx/nSpBdsF6xnseRXLLtfr9VLqkz8ZqHXr3Y7b6SftyRxBGjwMtJj1OhNbmlc1wZzLNAlAcvyIiE8a6ZA==",
+      "dev": true
+    },
+    "cipher-base": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+      "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "circular-json": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+      "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+      "dev": true
+    },
+    "class-utils": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "3.1.0",
+        "define-property": "0.2.5",
+        "isobject": "3.0.1",
+        "static-extend": "0.1.2"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "cli": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz",
+      "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=",
+      "dev": true,
+      "requires": {
+        "exit": "0.1.2",
+        "glob": "7.1.2"
+      }
+    },
+    "cli-cursor": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+      "dev": true,
+      "requires": {
+        "restore-cursor": "2.0.0"
+      }
+    },
+    "cli-width": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+      "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+      "dev": true
+    },
+    "cliui": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
+      "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
+      "dev": true,
+      "requires": {
+        "center-align": "0.1.3",
+        "right-align": "0.1.3",
+        "wordwrap": "0.0.2"
+      },
+      "dependencies": {
+        "wordwrap": {
+          "version": "0.0.2",
+          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+          "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
+          "dev": true
+        }
+      }
+    },
+    "co": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz",
+      "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=",
+      "dev": true
+    },
+    "co-task": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/co-task/-/co-task-1.0.0.tgz",
+      "integrity": "sha1-dJSwCATsga6kiVVuuGsteurCpRU=",
+      "dev": true,
+      "requires": {
+        "co": "3.1.0"
+      }
+    },
+    "code-point-at": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+      "dev": true
+    },
+    "collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "requires": {
+        "map-visit": "1.0.0",
+        "object-visit": "1.0.1"
+      }
+    },
+    "collections": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/collections/-/collections-0.2.2.tgz",
+      "integrity": "sha1-HyMCay7zb5J+7MkB6ZxfDUj6M04=",
+      "dev": true,
+      "requires": {
+        "weak-map": "1.0.0"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
+      "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
+      "dev": true,
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "colors": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+      "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
+      "dev": true
+    },
+    "combine-lists": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz",
+      "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=",
+      "dev": true,
+      "requires": {
+        "lodash": "4.17.4"
+      }
+    },
+    "combined-stream": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+      "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+      "dev": true,
+      "requires": {
+        "delayed-stream": "1.0.0"
+      }
+    },
+    "commander": {
+      "version": "2.12.2",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
+      "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==",
+      "dev": true
+    },
+    "commondir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "dev": true
+    },
+    "component-bind": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
+      "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=",
+      "dev": true
+    },
+    "component-emitter": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+      "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+      "dev": true
+    },
+    "component-inherit": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
+      "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=",
+      "dev": true
+    },
+    "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
+    },
+    "concat-stream": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
+      "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.3",
+        "typedarray": "0.0.6"
+      }
+    },
+    "connect": {
+      "version": "3.6.6",
+      "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
+      "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "finalhandler": "1.1.0",
+        "parseurl": "1.3.2",
+        "utils-merge": "1.0.1"
+      }
+    },
+    "console-browserify": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+      "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+      "dev": true,
+      "requires": {
+        "date-now": "0.1.4"
+      },
+      "dependencies": {
+        "date-now": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+          "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
+          "dev": true
+        }
+      }
+    },
+    "console-control-strings": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+      "dev": true
+    },
+    "constants-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+      "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
+      "dev": true
+    },
+    "contains-path": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
+      "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
+      "dev": true
+    },
+    "content-type": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+      "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
+    },
+    "cookie": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+      "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
+      "dev": true
+    },
+    "copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true
+    },
+    "core-js": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
+      "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+      "dev": true
+    },
+    "cpx": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz",
+      "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "chokidar": "1.7.0",
+        "duplexer": "0.1.1",
+        "glob": "7.1.2",
+        "glob2base": "0.0.12",
+        "minimatch": "3.0.4",
+        "mkdirp": "0.5.1",
+        "resolve": "1.4.0",
+        "safe-buffer": "5.1.1",
+        "shell-quote": "1.6.1",
+        "subarg": "1.0.0"
+      }
+    },
+    "create-ecdh": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz",
+      "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "elliptic": "6.4.0"
+      }
+    },
+    "create-hash": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
+      "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=",
+      "dev": true,
+      "requires": {
+        "cipher-base": "1.0.4",
+        "inherits": "2.0.3",
+        "ripemd160": "2.0.1",
+        "sha.js": "2.4.10"
+      }
+    },
+    "create-hmac": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz",
+      "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=",
+      "dev": true,
+      "requires": {
+        "cipher-base": "1.0.4",
+        "create-hash": "1.1.3",
+        "inherits": "2.0.3",
+        "ripemd160": "2.0.1",
+        "safe-buffer": "5.1.1",
+        "sha.js": "2.4.10"
+      }
+    },
+    "cross-spawn": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+      "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+      "dev": true,
+      "requires": {
+        "lru-cache": "4.1.1",
+        "shebang-command": "1.2.0",
+        "which": "1.3.0"
+      }
+    },
+    "cryptiles": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+      "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+      "dev": true,
+      "requires": {
+        "boom": "2.10.1"
+      }
+    },
+    "crypto-browserify": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+      "dev": true,
+      "requires": {
+        "browserify-cipher": "1.0.0",
+        "browserify-sign": "4.0.4",
+        "create-ecdh": "4.0.0",
+        "create-hash": "1.1.3",
+        "create-hmac": "1.1.6",
+        "diffie-hellman": "5.0.2",
+        "inherits": "2.0.3",
+        "pbkdf2": "3.0.14",
+        "public-encrypt": "4.0.0",
+        "randombytes": "2.0.6",
+        "randomfill": "1.0.3"
+      }
+    },
+    "css-select": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
+      "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
+      "dev": true,
+      "requires": {
+        "boolbase": "1.0.0",
+        "css-what": "2.1.0",
+        "domutils": "1.5.1",
+        "nth-check": "1.0.1"
+      }
+    },
+    "css-what": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz",
+      "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=",
+      "dev": true
+    },
+    "currently-unhandled": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+      "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+      "dev": true,
+      "requires": {
+        "array-find-index": "1.0.2"
+      }
+    },
+    "custom-event": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
+      "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=",
+      "dev": true
+    },
+    "d": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
+      "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+      "dev": true,
+      "requires": {
+        "es5-ext": "0.10.31"
+      }
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        }
+      }
+    },
+    "data-uri-to-buffer": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz",
+      "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==",
+      "dev": true,
+      "optional": true
+    },
+    "date-format": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz",
+      "integrity": "sha1-YV6CjiM90aubua4JUODOzPpuytg=",
+      "dev": true
+    },
+    "dateformat": {
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
+      "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=",
+      "dev": true,
+      "requires": {
+        "get-stdin": "4.0.1",
+        "meow": "3.7.0"
+      }
+    },
+    "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"
+      }
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true
+    },
+    "decode-uri-component": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "dev": true
+    },
+    "deep-eql": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
+      "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+      "dev": true,
+      "requires": {
+        "type-detect": "4.0.5"
+      }
+    },
+    "deep-is": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+      "dev": true
+    },
+    "define-properties": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
+      "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
+      "dev": true,
+      "requires": {
+        "foreach": "2.0.5",
+        "object-keys": "1.0.11"
+      }
+    },
+    "define-property": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+      "dev": true,
+      "requires": {
+        "is-descriptor": "1.0.2",
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "1.0.0",
+            "is-data-descriptor": "1.0.0",
+            "kind-of": "6.0.2"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "degenerator": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz",
+      "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "ast-types": "0.11.3",
+        "escodegen": "1.8.1",
+        "esprima": "3.1.3"
+      },
+      "dependencies": {
+        "esprima": {
+          "version": "3.1.3",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
+          "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "del": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
+      "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
+      "dev": true,
+      "requires": {
+        "globby": "5.0.0",
+        "is-path-cwd": "1.0.0",
+        "is-path-in-cwd": "1.0.0",
+        "object-assign": "4.1.1",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1",
+        "rimraf": "2.6.2"
+      }
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "dev": true
+    },
+    "delegates": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+      "dev": true
+    },
+    "depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "dev": true
+    },
+    "des.js": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
+      "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "minimalistic-assert": "1.0.0"
+      }
+    },
+    "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"
+      }
+    },
+    "di": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz",
+      "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=",
+      "dev": true
+    },
+    "diff": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+      "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+      "dev": true
+    },
+    "diffie-hellman": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz",
+      "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "miller-rabin": "4.0.1",
+        "randombytes": "2.0.6"
+      }
+    },
+    "discontinuous-range": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz",
+      "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=",
+      "dev": true
+    },
+    "doctrine": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+      "dev": true,
+      "requires": {
+        "esutils": "2.0.2"
+      }
+    },
+    "dom-serialize": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz",
+      "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=",
+      "dev": true,
+      "requires": {
+        "custom-event": "1.0.1",
+        "ent": "2.2.0",
+        "extend": "3.0.1",
+        "void-elements": "2.0.1"
+      }
+    },
+    "dom-serializer": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
+      "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "1.1.3",
+        "entities": "1.1.1"
+      },
+      "dependencies": {
+        "domelementtype": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
+          "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=",
+          "dev": true
+        }
+      }
+    },
+    "domain-browser": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz",
+      "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=",
+      "dev": true
+    },
+    "domelementtype": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
+      "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=",
+      "dev": true
+    },
+    "domhandler": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz",
+      "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "1.3.0"
+      }
+    },
+    "domutils": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
+      "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
+      "dev": true,
+      "requires": {
+        "dom-serializer": "0.1.0",
+        "domelementtype": "1.3.0"
+      }
+    },
+    "double-ended-queue": {
+      "version": "2.1.0-0",
+      "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz",
+      "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=",
+      "dev": true,
+      "optional": true
+    },
+    "duplexer": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+      "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
+      "dev": true
+    },
+    "ecc-jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+      "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "jsbn": "0.1.1"
+      }
+    },
+    "ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+      "dev": true
+    },
+    "elliptic": {
+      "version": "6.4.0",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz",
+      "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "brorand": "1.1.0",
+        "hash.js": "1.1.3",
+        "hmac-drbg": "1.0.1",
+        "inherits": "2.0.3",
+        "minimalistic-assert": "1.0.0",
+        "minimalistic-crypto-utils": "1.0.1"
+      }
+    },
+    "emojis-list": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
+      "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
+      "dev": true
+    },
+    "encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+      "dev": true
+    },
+    "encoding": {
+      "version": "0.1.12",
+      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
+      "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
+      "requires": {
+        "iconv-lite": "0.4.19"
+      }
+    },
+    "engine.io": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz",
+      "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==",
+      "dev": true,
+      "requires": {
+        "accepts": "1.3.5",
+        "base64id": "1.0.0",
+        "cookie": "0.3.1",
+        "debug": "3.1.0",
+        "engine.io-parser": "2.1.2",
+        "uws": "9.14.0",
+        "ws": "3.3.3"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "engine.io-client": {
+      "version": "3.1.6",
+      "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz",
+      "integrity": "sha512-hnuHsFluXnsKOndS4Hv6SvUrgdYx1pk2NqfaDMW+GWdgfU3+/V25Cj7I8a0x92idSpa5PIhJRKxPvp9mnoLsfg==",
+      "dev": true,
+      "requires": {
+        "component-emitter": "1.2.1",
+        "component-inherit": "0.0.3",
+        "debug": "3.1.0",
+        "engine.io-parser": "2.1.2",
+        "has-cors": "1.1.0",
+        "indexof": "0.0.1",
+        "parseqs": "0.0.5",
+        "parseuri": "0.0.5",
+        "ws": "3.3.3",
+        "xmlhttprequest-ssl": "1.5.5",
+        "yeast": "0.1.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "engine.io-parser": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz",
+      "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==",
+      "dev": true,
+      "requires": {
+        "after": "0.8.2",
+        "arraybuffer.slice": "0.0.7",
+        "base64-arraybuffer": "0.1.5",
+        "blob": "0.0.4",
+        "has-binary2": "1.0.2"
+      }
+    },
+    "enhanced-resolve": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz",
+      "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "memory-fs": "0.4.1",
+        "object-assign": "4.1.1",
+        "tapable": "0.2.8"
+      }
+    },
+    "ent": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz",
+      "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=",
+      "dev": true
+    },
+    "entities": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
+      "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=",
+      "dev": true
+    },
+    "enzyme": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.3.0.tgz",
+      "integrity": "sha512-l8csyPyLmtxskTz6pX9W8eDOyH1ckEtDttXk/vlFWCjv00SkjTjtoUrogqp4yEvMyneU9dUJoOLnqFoiHb8IHA==",
+      "dev": true,
+      "requires": {
+        "cheerio": "1.0.0-rc.2",
+        "function.prototype.name": "1.1.0",
+        "has": "1.0.1",
+        "is-boolean-object": "1.0.0",
+        "is-callable": "1.1.3",
+        "is-number-object": "1.0.3",
+        "is-string": "1.0.4",
+        "is-subset": "0.1.1",
+        "lodash": "4.17.4",
+        "object-inspect": "1.5.0",
+        "object-is": "1.0.1",
+        "object.assign": "4.1.0",
+        "object.entries": "1.0.4",
+        "object.values": "1.0.4",
+        "raf": "3.4.0",
+        "rst-selector-parser": "2.2.3"
+      }
+    },
+    "enzyme-adapter-react-16": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.1.1.tgz",
+      "integrity": "sha512-kC8pAtU2Jk3OJ0EG8Y2813dg9Ol0TXi7UNxHzHiWs30Jo/hj7alc//G1YpKUsPP1oKl9X+Lkx+WlGJpPYA+nvw==",
+      "dev": true,
+      "requires": {
+        "enzyme-adapter-utils": "1.3.0",
+        "lodash": "4.17.4",
+        "object.assign": "4.1.0",
+        "object.values": "1.0.4",
+        "prop-types": "15.6.1",
+        "react-reconciler": "0.7.0",
+        "react-test-renderer": "16.3.2"
+      },
+      "dependencies": {
+        "enzyme-adapter-utils": {
+          "version": "1.3.0",
+          "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.3.0.tgz",
+          "integrity": "sha512-vVXSt6uDv230DIv+ebCG66T1Pm36Kv+m74L1TrF4kaE7e1V7Q/LcxO0QRkajk5cA6R3uu9wJf5h13wOTezTbjA==",
+          "dev": true,
+          "requires": {
+            "lodash": "4.17.4",
+            "object.assign": "4.1.0",
+            "prop-types": "15.6.1"
+          }
+        }
+      }
+    },
+    "errno": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.6.tgz",
+      "integrity": "sha512-IsORQDpaaSwcDP4ZZnHxgE85werpo34VYn1Ud3mq+eUsF593faR8oCZNXrROVkpFu2TsbrNhHin0aUrTsQ9vNw==",
+      "dev": true,
+      "requires": {
+        "prr": "1.0.1"
+      }
+    },
+    "error-ex": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
+      "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "0.2.1"
+      }
+    },
+    "es-abstract": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.9.0.tgz",
+      "integrity": "sha512-kk3IJoKo7A3pWJc0OV8yZ/VEX2oSUytfekrJiqoxBlKJMFAJVJVpGdHClCCTdv+Fn2zHfpDHHIelMFhZVfef3Q==",
+      "dev": true,
+      "requires": {
+        "es-to-primitive": "1.1.1",
+        "function-bind": "1.1.1",
+        "has": "1.0.1",
+        "is-callable": "1.1.3",
+        "is-regex": "1.0.4"
+      }
+    },
+    "es-to-primitive": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
+      "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
+      "dev": true,
+      "requires": {
+        "is-callable": "1.1.3",
+        "is-date-object": "1.0.1",
+        "is-symbol": "1.0.1"
+      }
+    },
+    "es5-ext": {
+      "version": "0.10.31",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.31.tgz",
+      "integrity": "sha1-e7k4yVp/G59ygJLcCcQe3MOY7v4=",
+      "dev": true,
+      "requires": {
+        "es6-iterator": "2.0.1",
+        "es6-symbol": "3.1.1"
+      }
+    },
+    "es6-iterator": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
+      "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.31",
+        "es6-symbol": "3.1.1"
+      }
+    },
+    "es6-map": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
+      "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.31",
+        "es6-iterator": "2.0.1",
+        "es6-set": "0.1.5",
+        "es6-symbol": "3.1.1",
+        "event-emitter": "0.3.5"
+      }
+    },
+    "es6-promise": {
+      "version": "4.2.4",
+      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
+      "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==",
+      "dev": true
+    },
+    "es6-promisify": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+      "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
+      "dev": true,
+      "requires": {
+        "es6-promise": "4.2.4"
+      }
+    },
+    "es6-set": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
+      "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.31",
+        "es6-iterator": "2.0.1",
+        "es6-symbol": "3.1.1",
+        "event-emitter": "0.3.5"
+      }
+    },
+    "es6-symbol": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
+      "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.31"
+      }
+    },
+    "es6-weak-map": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
+      "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.31",
+        "es6-iterator": "2.0.1",
+        "es6-symbol": "3.1.1"
+      }
+    },
+    "escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+      "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
+    },
+    "escodegen": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
+      "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
+      "dev": true,
+      "requires": {
+        "esprima": "2.7.3",
+        "estraverse": "1.9.3",
+        "esutils": "2.0.2",
+        "optionator": "0.8.2",
+        "source-map": "0.2.0"
+      },
+      "dependencies": {
+        "esprima": {
+          "version": "2.7.3",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+          "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+          "dev": true
+        },
+        "estraverse": {
+          "version": "1.9.3",
+          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
+          "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
+          "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "amdefine": "1.0.1"
+          }
+        }
+      }
+    },
+    "escope": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
+      "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=",
+      "dev": true,
+      "requires": {
+        "es6-map": "0.1.5",
+        "es6-weak-map": "2.0.2",
+        "esrecurse": "4.2.0",
+        "estraverse": "4.2.0"
+      }
+    },
+    "eslint": {
+      "version": "4.19.1",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
+      "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==",
+      "dev": true,
+      "requires": {
+        "ajv": "5.5.2",
+        "babel-code-frame": "6.26.0",
+        "chalk": "2.4.1",
+        "concat-stream": "1.6.0",
+        "cross-spawn": "5.1.0",
+        "debug": "3.1.0",
+        "doctrine": "2.1.0",
+        "eslint-scope": "3.7.1",
+        "eslint-visitor-keys": "1.0.0",
+        "espree": "3.5.4",
+        "esquery": "1.0.1",
+        "esutils": "2.0.2",
+        "file-entry-cache": "2.0.0",
+        "functional-red-black-tree": "1.0.1",
+        "glob": "7.1.2",
+        "globals": "11.5.0",
+        "ignore": "3.3.5",
+        "imurmurhash": "0.1.4",
+        "inquirer": "3.3.0",
+        "is-resolvable": "1.0.0",
+        "js-yaml": "3.10.0",
+        "json-stable-stringify-without-jsonify": "1.0.1",
+        "levn": "0.3.0",
+        "lodash": "4.17.4",
+        "minimatch": "3.0.4",
+        "mkdirp": "0.5.1",
+        "natural-compare": "1.4.0",
+        "optionator": "0.8.2",
+        "path-is-inside": "1.0.2",
+        "pluralize": "7.0.0",
+        "progress": "2.0.0",
+        "regexpp": "1.1.0",
+        "require-uncached": "1.0.3",
+        "semver": "5.4.1",
+        "strip-ansi": "4.0.0",
+        "strip-json-comments": "2.0.1",
+        "table": "4.0.2",
+        "text-table": "0.2.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "5.5.3",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz",
+          "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==",
+          "dev": true
+        },
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.1"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.4.0"
+          }
+        },
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "espree": {
+          "version": "3.5.4",
+          "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
+          "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
+          "dev": true,
+          "requires": {
+            "acorn": "5.5.3",
+            "acorn-jsx": "3.0.1"
+          }
+        },
+        "globals": {
+          "version": "11.5.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz",
+          "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "eslint-import-resolver-node": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz",
+      "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "resolve": "1.7.1"
+      },
+      "dependencies": {
+        "resolve": {
+          "version": "1.7.1",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz",
+          "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==",
+          "dev": true,
+          "requires": {
+            "path-parse": "1.0.5"
+          }
+        }
+      }
+    },
+    "eslint-module-utils": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz",
+      "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "pkg-dir": "1.0.0"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+          "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+          "dev": true,
+          "requires": {
+            "path-exists": "2.1.0",
+            "pinkie-promise": "2.0.1"
+          }
+        },
+        "path-exists": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+          "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+          "dev": true,
+          "requires": {
+            "pinkie-promise": "2.0.1"
+          }
+        },
+        "pkg-dir": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz",
+          "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=",
+          "dev": true,
+          "requires": {
+            "find-up": "1.1.2"
+          }
+        }
+      }
+    },
+    "eslint-plugin-import": {
+      "version": "2.11.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.11.0.tgz",
+      "integrity": "sha1-Fa7qN6Z0mdhI6OmBgG1GJ7VQOBY=",
+      "dev": true,
+      "requires": {
+        "contains-path": "0.1.0",
+        "debug": "2.6.9",
+        "doctrine": "1.5.0",
+        "eslint-import-resolver-node": "0.3.2",
+        "eslint-module-utils": "2.2.0",
+        "has": "1.0.1",
+        "lodash": "4.17.4",
+        "minimatch": "3.0.4",
+        "read-pkg-up": "2.0.0",
+        "resolve": "1.7.1"
+      },
+      "dependencies": {
+        "doctrine": {
+          "version": "1.5.0",
+          "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+          "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+          "dev": true,
+          "requires": {
+            "esutils": "2.0.2",
+            "isarray": "1.0.0"
+          }
+        },
+        "load-json-file": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+          "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "4.1.11",
+            "parse-json": "2.2.0",
+            "pify": "2.3.0",
+            "strip-bom": "3.0.0"
+          }
+        },
+        "path-type": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+          "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+          "dev": true,
+          "requires": {
+            "pify": "2.3.0"
+          }
+        },
+        "read-pkg": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+          "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+          "dev": true,
+          "requires": {
+            "load-json-file": "2.0.0",
+            "normalize-package-data": "2.4.0",
+            "path-type": "2.0.0"
+          }
+        },
+        "read-pkg-up": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+          "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+          "dev": true,
+          "requires": {
+            "find-up": "2.1.0",
+            "read-pkg": "2.0.0"
+          }
+        },
+        "resolve": {
+          "version": "1.7.1",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz",
+          "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==",
+          "dev": true,
+          "requires": {
+            "path-parse": "1.0.5"
+          }
+        },
+        "strip-bom": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+          "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+          "dev": true
+        }
+      }
+    },
+    "eslint-plugin-json": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-json/-/eslint-plugin-json-1.2.0.tgz",
+      "integrity": "sha1-m6c7sL6Z1QCT6In1uWhGPSow764=",
+      "dev": true,
+      "requires": {
+        "jshint": "2.9.5"
+      }
+    },
+    "eslint-plugin-mozilla": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-mozilla/-/eslint-plugin-mozilla-0.11.0.tgz",
+      "integrity": "sha512-O/02mzydm2KqjGb0gSAz+qJQSwZAmWsKaxRRkqkM1Tv4+/spn2aeYLorZKzcCZb+I27oQHOej151TCPXofix9w==",
+      "dev": true,
+      "requires": {
+        "ini-parser": "0.0.2",
+        "sax": "1.2.4"
+      }
+    },
+    "eslint-plugin-no-unsanitized": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-no-unsanitized/-/eslint-plugin-no-unsanitized-3.0.0.tgz",
+      "integrity": "sha1-FEi1LN14cfF0PCkAEXuwh8/nuAY=",
+      "dev": true
+    },
+    "eslint-plugin-promise": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.7.0.tgz",
+      "integrity": "sha512-2WO+ZFh7vxUKRfR0cOIMrWgYKdR6S1AlOezw6pC52B6oYpd5WFghN+QHxvrRdZMtbo8h3dfUZ2o1rWb0UPbKtg==",
+      "dev": true
+    },
+    "eslint-plugin-react": {
+      "version": "7.7.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.7.0.tgz",
+      "integrity": "sha512-KC7Snr4YsWZD5flu6A5c0AcIZidzW3Exbqp7OT67OaD2AppJtlBr/GuPrW/vaQM/yfZotEvKAdrxrO+v8vwYJA==",
+      "dev": true,
+      "requires": {
+        "doctrine": "2.1.0",
+        "has": "1.0.1",
+        "jsx-ast-utils": "2.0.1",
+        "prop-types": "15.6.1"
+      }
+    },
+    "eslint-scope": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
+      "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
+      "dev": true,
+      "requires": {
+        "esrecurse": "4.2.0",
+        "estraverse": "4.2.0"
+      }
+    },
+    "eslint-visitor-keys": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+      "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
+      "dev": true
+    },
+    "eslint-watch": {
+      "version": "3.1.4",
+      "resolved": "https://registry.npmjs.org/eslint-watch/-/eslint-watch-3.1.4.tgz",
+      "integrity": "sha512-UpEszJuz/FBG3usSJkCy1p4iWMWmXFyMiCBnnJ9l1wXtMpEg6+mjnWM1MbStY5/QhuHEvW4M3AAadjUVv6FrAQ==",
+      "dev": true,
+      "requires": {
+        "babel-polyfill": "6.26.0",
+        "bluebird": "3.5.1",
+        "chalk": "2.4.1",
+        "chokidar": "2.0.3",
+        "debug": "3.1.0",
+        "keypress": "0.2.1",
+        "lodash": "4.17.4",
+        "optionator": "0.8.2",
+        "source-map-support": "0.5.5",
+        "strip-ansi": "4.0.0",
+        "text-table": "0.2.0",
+        "unicons": "0.0.3"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.1"
+          }
+        },
+        "anymatch": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+          "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+          "dev": true,
+          "requires": {
+            "micromatch": "3.1.10",
+            "normalize-path": "2.1.1"
+          }
+        },
+        "arr-diff": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+          "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+          "dev": true
+        },
+        "array-unique": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+          "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+          "dev": true
+        },
+        "braces": {
+          "version": "2.3.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+          "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+          "dev": true,
+          "requires": {
+            "arr-flatten": "1.1.0",
+            "array-unique": "0.3.2",
+            "extend-shallow": "2.0.1",
+            "fill-range": "4.0.0",
+            "isobject": "3.0.1",
+            "repeat-element": "1.1.2",
+            "snapdragon": "0.8.2",
+            "snapdragon-node": "2.1.1",
+            "split-string": "3.1.0",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.4.0"
+          }
+        },
+        "chokidar": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz",
+          "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==",
+          "dev": true,
+          "requires": {
+            "anymatch": "2.0.0",
+            "async-each": "1.0.1",
+            "braces": "2.3.2",
+            "fsevents": "1.1.2",
+            "glob-parent": "3.1.0",
+            "inherits": "2.0.3",
+            "is-binary-path": "1.0.1",
+            "is-glob": "4.0.0",
+            "normalize-path": "2.1.1",
+            "path-is-absolute": "1.0.1",
+            "readdirp": "2.1.0",
+            "upath": "1.0.5"
+          }
+        },
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "expand-brackets": {
+          "version": "2.1.4",
+          "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+          "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+          "dev": true,
+          "requires": {
+            "debug": "2.6.9",
+            "define-property": "0.2.5",
+            "extend-shallow": "2.0.1",
+            "posix-character-classes": "0.1.1",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "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"
+              }
+            },
+            "define-property": {
+              "version": "0.2.5",
+              "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+              "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+              "dev": true,
+              "requires": {
+                "is-descriptor": "0.1.6"
+              }
+            },
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            },
+            "is-accessor-descriptor": {
+              "version": "0.1.6",
+              "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+              "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+              "dev": true,
+              "requires": {
+                "kind-of": "3.2.2"
+              },
+              "dependencies": {
+                "kind-of": {
+                  "version": "3.2.2",
+                  "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+                  "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+                  "dev": true,
+                  "requires": {
+                    "is-buffer": "1.1.5"
+                  }
+                }
+              }
+            },
+            "is-data-descriptor": {
+              "version": "0.1.4",
+              "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+              "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+              "dev": true,
+              "requires": {
+                "kind-of": "3.2.2"
+              },
+              "dependencies": {
+                "kind-of": {
+                  "version": "3.2.2",
+                  "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+                  "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+                  "dev": true,
+                  "requires": {
+                    "is-buffer": "1.1.5"
+                  }
+                }
+              }
+            },
+            "is-descriptor": {
+              "version": "0.1.6",
+              "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+              "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+              "dev": true,
+              "requires": {
+                "is-accessor-descriptor": "0.1.6",
+                "is-data-descriptor": "0.1.4",
+                "kind-of": "5.1.0"
+              }
+            },
+            "kind-of": {
+              "version": "5.1.0",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+              "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+              "dev": true
+            }
+          }
+        },
+        "extglob": {
+          "version": "2.0.4",
+          "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+          "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+          "dev": true,
+          "requires": {
+            "array-unique": "0.3.2",
+            "define-property": "1.0.0",
+            "expand-brackets": "2.1.4",
+            "extend-shallow": "2.0.1",
+            "fragment-cache": "0.2.1",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "define-property": {
+              "version": "1.0.0",
+              "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+              "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+              "dev": true,
+              "requires": {
+                "is-descriptor": "1.0.2"
+              }
+            },
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "fill-range": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+          "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+          "dev": true,
+          "requires": {
+            "extend-shallow": "2.0.1",
+            "is-number": "3.0.0",
+            "repeat-string": "1.6.1",
+            "to-regex-range": "2.1.1"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "glob-parent": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+          "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+          "dev": true,
+          "requires": {
+            "is-glob": "3.1.0",
+            "path-dirname": "1.0.2"
+          },
+          "dependencies": {
+            "is-glob": {
+              "version": "3.1.0",
+              "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+              "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+              "dev": true,
+              "requires": {
+                "is-extglob": "2.1.1"
+              }
+            }
+          }
+        },
+        "has-flag": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "dev": true
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "1.0.0",
+            "is-data-descriptor": "1.0.0",
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-extglob": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+          "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+          "dev": true
+        },
+        "is-glob": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
+          "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "2.1.1"
+          }
+        },
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.5"
+              }
+            }
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        },
+        "micromatch": {
+          "version": "3.1.10",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+          "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+          "dev": true,
+          "requires": {
+            "arr-diff": "4.0.0",
+            "array-unique": "0.3.2",
+            "braces": "2.3.2",
+            "define-property": "2.0.2",
+            "extend-shallow": "3.0.2",
+            "extglob": "2.0.4",
+            "fragment-cache": "0.2.1",
+            "kind-of": "6.0.2",
+            "nanomatch": "1.2.9",
+            "object.pick": "1.3.0",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          }
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
+        "source-map-support": {
+          "version": "0.5.5",
+          "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.5.tgz",
+          "integrity": "sha512-mR7/Nd5l1z6g99010shcXJiNEaf3fEtmLhRB/sBcQVJGodcHCULPp2y4Sfa43Kv2zq7T+Izmfp/WHCR6dYkQCA==",
+          "dev": true,
+          "requires": {
+            "buffer-from": "1.0.0",
+            "source-map": "0.6.1"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "espree": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.1.tgz",
+      "integrity": "sha1-DJiLirRttTEAoZVK5LqZXd0n2H4=",
+      "dev": true,
+      "requires": {
+        "acorn": "5.1.2",
+        "acorn-jsx": "3.0.1"
+      }
+    },
+    "esprima": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
+      "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
+      "dev": true
+    },
+    "esquery": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
+      "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
+      "dev": true,
+      "requires": {
+        "estraverse": "4.2.0"
+      }
+    },
+    "esrecurse": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
+      "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
+      "dev": true,
+      "requires": {
+        "estraverse": "4.2.0",
+        "object-assign": "4.1.1"
+      }
+    },
+    "estraverse": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+      "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+      "dev": true
+    },
+    "esutils": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+      "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+      "dev": true
+    },
+    "event-emitter": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+      "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
+      "dev": true,
+      "requires": {
+        "d": "1.0.0",
+        "es5-ext": "0.10.31"
+      }
+    },
+    "event-stream": {
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
+      "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=",
+      "dev": true,
+      "requires": {
+        "duplexer": "0.1.1",
+        "from": "0.1.7",
+        "map-stream": "0.1.0",
+        "pause-stream": "0.0.11",
+        "split": "0.3.3",
+        "stream-combiner": "0.0.4",
+        "through": "2.3.8"
+      }
+    },
+    "eventemitter3": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz",
+      "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==",
+      "dev": true
+    },
+    "events": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
+      "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
+      "dev": true
+    },
+    "evp_bytestokey": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+      "dev": true,
+      "requires": {
+        "md5.js": "1.3.4",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "execa": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+      "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "5.1.0",
+        "get-stream": "3.0.0",
+        "is-stream": "1.1.0",
+        "npm-run-path": "2.0.2",
+        "p-finally": "1.0.0",
+        "signal-exit": "3.0.2",
+        "strip-eof": "1.0.0"
+      }
+    },
+    "exit": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+      "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+      "dev": true
+    },
+    "exit-hook": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
+      "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=",
+      "dev": true
+    },
+    "expand-braces": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz",
+      "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=",
+      "dev": true,
+      "requires": {
+        "array-slice": "0.2.3",
+        "array-unique": "0.2.1",
+        "braces": "0.1.5"
+      },
+      "dependencies": {
+        "braces": {
+          "version": "0.1.5",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz",
+          "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=",
+          "dev": true,
+          "requires": {
+            "expand-range": "0.1.1"
+          }
+        },
+        "expand-range": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz",
+          "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=",
+          "dev": true,
+          "requires": {
+            "is-number": "0.1.1",
+            "repeat-string": "0.2.2"
+          }
+        },
+        "is-number": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz",
+          "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=",
+          "dev": true
+        },
+        "repeat-string": {
+          "version": "0.2.2",
+          "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz",
+          "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=",
+          "dev": true
+        }
+      }
+    },
+    "expand-brackets": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+      "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+      "dev": true,
+      "requires": {
+        "is-posix-bracket": "0.1.1"
+      }
+    },
+    "expand-range": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+      "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
+      "dev": true,
+      "requires": {
+        "fill-range": "2.2.3"
+      }
+    },
+    "extend": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+      "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+      "dev": true
+    },
+    "extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "requires": {
+        "assign-symbols": "1.0.0",
+        "is-extendable": "1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "2.0.4"
+          }
+        }
+      }
+    },
+    "external-editor": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
+      "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
+      "dev": true,
+      "requires": {
+        "chardet": "0.4.2",
+        "iconv-lite": "0.4.19",
+        "tmp": "0.0.33"
+      }
+    },
+    "extglob": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+      "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "1.0.0"
+      }
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true
+    },
+    "fast-deep-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
+      "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=",
+      "dev": true
+    },
+    "fast-json-stable-stringify": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+      "dev": true
+    },
+    "fast-levenshtein": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+      "dev": true
+    },
+    "fbjs": {
+      "version": "0.8.16",
+      "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz",
+      "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=",
+      "requires": {
+        "core-js": "1.2.7",
+        "isomorphic-fetch": "2.2.1",
+        "loose-envify": "1.3.1",
+        "object-assign": "4.1.1",
+        "promise": "7.3.1",
+        "setimmediate": "1.0.5",
+        "ua-parser-js": "0.7.17"
+      }
+    },
+    "figures": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+      "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "1.0.5"
+      }
+    },
+    "file-entry-cache": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+      "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
+      "dev": true,
+      "requires": {
+        "flat-cache": "1.3.0",
+        "object-assign": "4.1.1"
+      }
+    },
+    "file-uri-to-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+      "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+      "dev": true,
+      "optional": true
+    },
+    "filename-regex": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
+      "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
+      "dev": true
+    },
+    "fill-range": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
+      "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=",
+      "dev": true,
+      "requires": {
+        "is-number": "2.1.0",
+        "isobject": "2.1.0",
+        "randomatic": "1.1.7",
+        "repeat-element": "1.1.2",
+        "repeat-string": "1.6.1"
+      }
+    },
+    "finalhandler": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
+      "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "encodeurl": "1.0.2",
+        "escape-html": "1.0.3",
+        "on-finished": "2.3.0",
+        "parseurl": "1.3.2",
+        "statuses": "1.3.1",
+        "unpipe": "1.0.0"
+      },
+      "dependencies": {
+        "statuses": {
+          "version": "1.3.1",
+          "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+          "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
+          "dev": true
+        }
+      }
+    },
+    "find-cache-dir": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz",
+      "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=",
+      "dev": true,
+      "requires": {
+        "commondir": "1.0.1",
+        "make-dir": "1.2.0",
+        "pkg-dir": "2.0.0"
+      }
+    },
+    "find-index": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz",
+      "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=",
+      "dev": true
+    },
+    "find-up": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+      "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+      "dev": true,
+      "requires": {
+        "locate-path": "2.0.0"
+      }
+    },
+    "flat-cache": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
+      "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
+      "dev": true,
+      "requires": {
+        "circular-json": "0.3.3",
+        "del": "2.2.2",
+        "graceful-fs": "4.1.11",
+        "write": "0.2.1"
+      }
+    },
+    "follow-redirects": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.4.1.tgz",
+      "integrity": "sha512-uxYePVPogtya1ktGnAAXOacnbIuRMB4dkvqeNz2qTtTQsuzSfbDolV+wMMKxAmCx0bLgAKLbBOkjItMbbkR1vg==",
+      "dev": true,
+      "requires": {
+        "debug": "3.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true
+    },
+    "for-own": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+      "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
+      "dev": true,
+      "requires": {
+        "for-in": "1.0.2"
+      }
+    },
+    "foreach": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+      "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
+      "dev": true
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+      "dev": true
+    },
+    "form-data": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+      "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+      "dev": true,
+      "requires": {
+        "asynckit": "0.4.0",
+        "combined-stream": "1.0.5",
+        "mime-types": "2.1.17"
+      }
+    },
+    "fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "requires": {
+        "map-cache": "0.2.2"
+      }
+    },
+    "from": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
+      "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
+      "dev": true
+    },
+    "front-matter": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-2.1.2.tgz",
+      "integrity": "sha1-91mDufL0E75ljJPf172M5AePXNs=",
+      "dev": true,
+      "requires": {
+        "js-yaml": "3.10.0"
+      }
+    },
+    "fs-extra": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz",
+      "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "jsonfile": "3.0.1",
+        "universalify": "0.1.1"
+      },
+      "dependencies": {
+        "jsonfile": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz",
+          "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "4.1.11"
+          }
+        }
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "fsevents": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.2.tgz",
+      "integrity": "sha512-Sn44E5wQW4bTHXvQmvSHwqbuiXtduD6Rrjm2ZtUEGbyrig+nUH3t/QD4M4/ZXViY556TBpRgZkHLDx3JxPwxiw==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "nan": "2.7.0",
+        "node-pre-gyp": "0.6.36"
+      },
+      "dependencies": {
+        "abbrev": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz",
+          "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=",
+          "dev": true,
+          "optional": true
+        },
+        "ajv": {
+          "version": "4.11.8",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+          "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "co": "4.6.0",
+            "json-stable-stringify": "1.0.1"
+          }
+        },
+        "ansi-regex": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+          "dev": true
+        },
+        "aproba": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.1.tgz",
+          "integrity": "sha1-ldNgDwdxCqDpKYxyatXs8urLq6s=",
+          "dev": true,
+          "optional": true
+        },
+        "are-we-there-yet": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
+          "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "delegates": "1.0.0",
+            "readable-stream": "2.2.9"
+          }
+        },
+        "asn1": {
+          "version": "0.2.3",
+          "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+          "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
+          "dev": true,
+          "optional": true
+        },
+        "assert-plus": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+          "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+          "dev": true,
+          "optional": true
+        },
+        "asynckit": {
+          "version": "0.4.0",
+          "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+          "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+          "dev": true,
+          "optional": true
+        },
+        "aws-sign2": {
+          "version": "0.6.0",
+          "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+          "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+          "dev": true,
+          "optional": true
+        },
+        "aws4": {
+          "version": "1.6.0",
+          "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+          "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
+          "dev": true,
+          "optional": true
+        },
+        "balanced-match": {
+          "version": "0.4.2",
+          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+          "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
+          "dev": true
+        },
+        "bcrypt-pbkdf": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+          "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "tweetnacl": "0.14.5"
+          }
+        },
+        "block-stream": {
+          "version": "0.0.9",
+          "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
+          "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+          "dev": true,
+          "requires": {
+            "inherits": "2.0.3"
+          }
+        },
+        "boom": {
+          "version": "2.10.1",
+          "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+          "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+          "dev": true,
+          "requires": {
+            "hoek": "2.16.3"
+          }
+        },
+        "brace-expansion": {
+          "version": "1.1.7",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz",
+          "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=",
+          "dev": true,
+          "requires": {
+            "balanced-match": "0.4.2",
+            "concat-map": "0.0.1"
+          }
+        },
+        "buffer-shims": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
+          "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=",
+          "dev": true
+        },
+        "caseless": {
+          "version": "0.12.0",
+          "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+          "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+          "dev": true,
+          "optional": true
+        },
+        "co": {
+          "version": "4.6.0",
+          "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+          "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+          "dev": true,
+          "optional": true
+        },
+        "code-point-at": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+          "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+          "dev": true
+        },
+        "combined-stream": {
+          "version": "1.0.5",
+          "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+          "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+          "dev": true,
+          "requires": {
+            "delayed-stream": "1.0.0"
+          }
+        },
+        "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
+        },
+        "console-control-strings": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+          "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+          "dev": true
+        },
+        "core-util-is": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+          "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+          "dev": true
+        },
+        "cryptiles": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+          "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "boom": "2.10.1"
+          }
+        },
+        "dashdash": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+          "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "assert-plus": "1.0.0"
+          },
+          "dependencies": {
+            "assert-plus": {
+              "version": "1.0.0",
+              "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+              "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+              "dev": true,
+              "optional": true
+            }
+          }
+        },
+        "debug": {
+          "version": "2.6.8",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+          "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "deep-extend": {
+          "version": "0.4.2",
+          "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
+          "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=",
+          "dev": true,
+          "optional": true
+        },
+        "delayed-stream": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+          "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+          "dev": true
+        },
+        "delegates": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+          "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+          "dev": true,
+          "optional": true
+        },
+        "ecc-jsbn": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+          "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "jsbn": "0.1.1"
+          }
+        },
+        "extend": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+          "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+          "dev": true,
+          "optional": true
+        },
+        "extsprintf": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz",
+          "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=",
+          "dev": true
+        },
+        "forever-agent": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+          "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+          "dev": true,
+          "optional": true
+        },
+        "form-data": {
+          "version": "2.1.4",
+          "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+          "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "asynckit": "0.4.0",
+            "combined-stream": "1.0.5",
+            "mime-types": "2.1.15"
+          }
+        },
+        "fs.realpath": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+          "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+          "dev": true
+        },
+        "fstream": {
+          "version": "1.0.11",
+          "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
+          "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "4.1.11",
+            "inherits": "2.0.3",
+            "mkdirp": "0.5.1",
+            "rimraf": "2.6.1"
+          }
+        },
+        "fstream-ignore": {
+          "version": "1.0.5",
+          "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz",
+          "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "fstream": "1.0.11",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4"
+          }
+        },
+        "gauge": {
+          "version": "2.7.4",
+          "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+          "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "aproba": "1.1.1",
+            "console-control-strings": "1.1.0",
+            "has-unicode": "2.0.1",
+            "object-assign": "4.1.1",
+            "signal-exit": "3.0.2",
+            "string-width": "1.0.2",
+            "strip-ansi": "3.0.1",
+            "wide-align": "1.1.2"
+          }
+        },
+        "getpass": {
+          "version": "0.1.7",
+          "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+          "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "assert-plus": "1.0.0"
+          },
+          "dependencies": {
+            "assert-plus": {
+              "version": "1.0.0",
+              "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+              "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+              "dev": true,
+              "optional": true
+            }
+          }
+        },
+        "glob": {
+          "version": "7.1.2",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+          "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"
+          }
+        },
+        "graceful-fs": {
+          "version": "4.1.11",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+          "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+          "dev": true
+        },
+        "har-schema": {
+          "version": "1.0.5",
+          "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
+          "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=",
+          "dev": true,
+          "optional": true
+        },
+        "har-validator": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
+          "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ajv": "4.11.8",
+            "har-schema": "1.0.5"
+          }
+        },
+        "has-unicode": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+          "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
+          "dev": true,
+          "optional": true
+        },
+        "hawk": {
+          "version": "3.1.3",
+          "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+          "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "boom": "2.10.1",
+            "cryptiles": "2.0.5",
+            "hoek": "2.16.3",
+            "sntp": "1.0.9"
+          }
+        },
+        "hoek": {
+          "version": "2.16.3",
+          "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+          "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+          "dev": true
+        },
+        "http-signature": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+          "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "assert-plus": "0.2.0",
+            "jsprim": "1.4.0",
+            "sshpk": "1.13.0"
+          }
+        },
+        "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
+        },
+        "ini": {
+          "version": "1.3.4",
+          "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
+          "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
+          "dev": true,
+          "optional": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "is-typedarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+          "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+          "dev": true,
+          "optional": true
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "isstream": {
+          "version": "0.1.2",
+          "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+          "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+          "dev": true,
+          "optional": true
+        },
+        "jodid25519": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz",
+          "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "jsbn": "0.1.1"
+          }
+        },
+        "jsbn": {
+          "version": "0.1.1",
+          "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+          "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+          "dev": true,
+          "optional": true
+        },
+        "json-schema": {
+          "version": "0.2.3",
+          "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+          "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+          "dev": true,
+          "optional": true
+        },
+        "json-stable-stringify": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+          "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "jsonify": "0.0.0"
+          }
+        },
+        "json-stringify-safe": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+          "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+          "dev": true,
+          "optional": true
+        },
+        "jsonify": {
+          "version": "0.0.0",
+          "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+          "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+          "dev": true,
+          "optional": true
+        },
+        "jsprim": {
+          "version": "1.4.0",
+          "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz",
+          "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "assert-plus": "1.0.0",
+            "extsprintf": "1.0.2",
+            "json-schema": "0.2.3",
+            "verror": "1.3.6"
+          },
+          "dependencies": {
+            "assert-plus": {
+              "version": "1.0.0",
+              "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+              "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+              "dev": true,
+              "optional": true
+            }
+          }
+        },
+        "mime-db": {
+          "version": "1.27.0",
+          "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz",
+          "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=",
+          "dev": true
+        },
+        "mime-types": {
+          "version": "2.1.15",
+          "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz",
+          "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=",
+          "dev": true,
+          "requires": {
+            "mime-db": "1.27.0"
+          }
+        },
+        "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.7"
+          }
+        },
+        "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"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true,
+          "optional": true
+        },
+        "node-pre-gyp": {
+          "version": "0.6.36",
+          "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz",
+          "integrity": "sha1-22BBEst04NR3VU6bUFsXq936t4Y=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "mkdirp": "0.5.1",
+            "nopt": "4.0.1",
+            "npmlog": "4.1.0",
+            "rc": "1.2.1",
+            "request": "2.81.0",
+            "rimraf": "2.6.1",
+            "semver": "5.3.0",
+            "tar": "2.2.1",
+            "tar-pack": "3.4.0"
+          }
+        },
+        "nopt": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
+          "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "abbrev": "1.1.0",
+            "osenv": "0.1.4"
+          }
+        },
+        "npmlog": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.0.tgz",
+          "integrity": "sha512-ocolIkZYZt8UveuiDS0yAkkIjid1o7lPG8cYm05yNYzBn8ykQtaiPMEGp8fY9tKdDgm8okpdKzkvu1y9hUYugA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "are-we-there-yet": "1.1.4",
+            "console-control-strings": "1.1.0",
+            "gauge": "2.7.4",
+            "set-blocking": "2.0.0"
+          }
+        },
+        "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
+        },
+        "oauth-sign": {
+          "version": "0.8.2",
+          "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+          "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+          "dev": true,
+          "optional": true
+        },
+        "object-assign": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+          "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+          "dev": true,
+          "optional": 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,
+          "optional": 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,
+          "optional": true
+        },
+        "osenv": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz",
+          "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "os-homedir": "1.0.2",
+            "os-tmpdir": "1.0.2"
+          }
+        },
+        "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
+        },
+        "performance-now": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
+          "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=",
+          "dev": true,
+          "optional": true
+        },
+        "process-nextick-args": {
+          "version": "1.0.7",
+          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+          "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+          "dev": true
+        },
+        "punycode": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+          "dev": true,
+          "optional": true
+        },
+        "qs": {
+          "version": "6.4.0",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
+          "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=",
+          "dev": true,
+          "optional": true
+        },
+        "rc": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz",
+          "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "deep-extend": "0.4.2",
+            "ini": "1.3.4",
+            "minimist": "1.2.0",
+            "strip-json-comments": "2.0.1"
+          },
+          "dependencies": {
+            "minimist": {
+              "version": "1.2.0",
+              "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+              "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+              "dev": true,
+              "optional": true
+            }
+          }
+        },
+        "readable-stream": {
+          "version": "2.2.9",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz",
+          "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=",
+          "dev": true,
+          "requires": {
+            "buffer-shims": "1.0.0",
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "1.0.7",
+            "string_decoder": "1.0.1",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "request": {
+          "version": "2.81.0",
+          "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
+          "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "aws-sign2": "0.6.0",
+            "aws4": "1.6.0",
+            "caseless": "0.12.0",
+            "combined-stream": "1.0.5",
+            "extend": "3.0.1",
+            "forever-agent": "0.6.1",
+            "form-data": "2.1.4",
+            "har-validator": "4.2.1",
+            "hawk": "3.1.3",
+            "http-signature": "1.1.1",
+            "is-typedarray": "1.0.0",
+            "isstream": "0.1.2",
+            "json-stringify-safe": "5.0.1",
+            "mime-types": "2.1.15",
+            "oauth-sign": "0.8.2",
+            "performance-now": "0.2.0",
+            "qs": "6.4.0",
+            "safe-buffer": "5.0.1",
+            "stringstream": "0.0.5",
+            "tough-cookie": "2.3.2",
+            "tunnel-agent": "0.6.0",
+            "uuid": "3.0.1"
+          }
+        },
+        "rimraf": {
+          "version": "2.6.1",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
+          "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=",
+          "dev": true,
+          "requires": {
+            "glob": "7.1.2"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz",
+          "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=",
+          "dev": true
+        },
+        "semver": {
+          "version": "5.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+          "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
+          "dev": true,
+          "optional": true
+        },
+        "set-blocking": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+          "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+          "dev": true,
+          "optional": true
+        },
+        "signal-exit": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+          "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+          "dev": true,
+          "optional": true
+        },
+        "sntp": {
+          "version": "1.0.9",
+          "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+          "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "hoek": "2.16.3"
+          }
+        },
+        "sshpk": {
+          "version": "1.13.0",
+          "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.0.tgz",
+          "integrity": "sha1-/yo+T9BEl1Vf7Zezmg/YL6+zozw=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "asn1": "0.2.3",
+            "assert-plus": "1.0.0",
+            "bcrypt-pbkdf": "1.0.1",
+            "dashdash": "1.14.1",
+            "ecc-jsbn": "0.1.1",
+            "getpass": "0.1.7",
+            "jodid25519": "1.0.2",
+            "jsbn": "0.1.1",
+            "tweetnacl": "0.14.5"
+          },
+          "dependencies": {
+            "assert-plus": {
+              "version": "1.0.0",
+              "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+              "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+              "dev": true,
+              "optional": true
+            }
+          }
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "1.1.0",
+            "is-fullwidth-code-point": "1.0.0",
+            "strip-ansi": "3.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz",
+          "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "5.0.1"
+          }
+        },
+        "stringstream": {
+          "version": "0.0.5",
+          "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+          "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
+          "dev": true,
+          "optional": true
+        },
+        "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"
+          }
+        },
+        "strip-json-comments": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+          "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+          "dev": true,
+          "optional": true
+        },
+        "tar": {
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+          "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
+          "dev": true,
+          "requires": {
+            "block-stream": "0.0.9",
+            "fstream": "1.0.11",
+            "inherits": "2.0.3"
+          }
+        },
+        "tar-pack": {
+          "version": "3.4.0",
+          "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.0.tgz",
+          "integrity": "sha1-I74tf2cagzk3bL2wuP4/3r8xeYQ=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "debug": "2.6.8",
+            "fstream": "1.0.11",
+            "fstream-ignore": "1.0.5",
+            "once": "1.4.0",
+            "readable-stream": "2.2.9",
+            "rimraf": "2.6.1",
+            "tar": "2.2.1",
+            "uid-number": "0.0.6"
+          }
+        },
+        "tough-cookie": {
+          "version": "2.3.2",
+          "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz",
+          "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "punycode": "1.4.1"
+          }
+        },
+        "tunnel-agent": {
+          "version": "0.6.0",
+          "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+          "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "safe-buffer": "5.0.1"
+          }
+        },
+        "tweetnacl": {
+          "version": "0.14.5",
+          "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+          "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+          "dev": true,
+          "optional": true
+        },
+        "uid-number": {
+          "version": "0.0.6",
+          "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz",
+          "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=",
+          "dev": true,
+          "optional": true
+        },
+        "util-deprecate": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+          "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+          "dev": true
+        },
+        "uuid": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz",
+          "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=",
+          "dev": true,
+          "optional": true
+        },
+        "verror": {
+          "version": "1.3.6",
+          "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz",
+          "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "extsprintf": "1.0.2"
+          }
+        },
+        "wide-align": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
+          "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "string-width": "1.0.2"
+          }
+        },
+        "wrappy": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+          "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+          "dev": true
+        }
+      }
+    },
+    "fstream": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
+      "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "inherits": "2.0.3",
+        "mkdirp": "0.5.1",
+        "rimraf": "2.6.2"
+      }
+    },
+    "ftp": {
+      "version": "0.3.10",
+      "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz",
+      "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "readable-stream": "1.1.14",
+        "xregexp": "2.0.0"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+          "dev": true,
+          "optional": true
+        },
+        "readable-stream": {
+          "version": "1.1.14",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+          "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "0.0.1",
+            "string_decoder": "0.10.31"
+          }
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "function.prototype.name": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.0.tgz",
+      "integrity": "sha512-Bs0VRrTz4ghD8pTmbJQD1mZ8A/mN0ur/jGz+A6FBxPDUPkm1tNfF6bhTYPA7i7aF4lZJVr+OXTNNrnnIl58Wfg==",
+      "dev": true,
+      "requires": {
+        "define-properties": "1.1.2",
+        "function-bind": "1.1.1",
+        "is-callable": "1.1.3"
+      }
+    },
+    "functional-red-black-tree": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+      "dev": true
+    },
+    "gauge": {
+      "version": "2.7.4",
+      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+      "dev": true,
+      "requires": {
+        "aproba": "1.2.0",
+        "console-control-strings": "1.1.0",
+        "has-unicode": "2.0.1",
+        "object-assign": "4.1.1",
+        "signal-exit": "3.0.2",
+        "string-width": "1.0.2",
+        "strip-ansi": "3.0.1",
+        "wide-align": "1.1.2"
+      },
+      "dependencies": {
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "1.1.0",
+            "is-fullwidth-code-point": "1.0.0",
+            "strip-ansi": "3.0.1"
+          }
+        }
+      }
+    },
+    "gaze": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz",
+      "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=",
+      "dev": true,
+      "requires": {
+        "globule": "1.2.0"
+      }
+    },
+    "generate-function": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
+      "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=",
+      "dev": true
+    },
+    "generate-object-property": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
+      "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
+      "dev": true,
+      "requires": {
+        "is-property": "1.0.2"
+      }
+    },
+    "get-caller-file": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
+      "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=",
+      "dev": true
+    },
+    "get-func-name": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+      "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
+      "dev": true
+    },
+    "get-stdin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+      "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+      "dev": true
+    },
+    "get-stream": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+      "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+      "dev": true
+    },
+    "get-uri": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.1.tgz",
+      "integrity": "sha512-7aelVrYqCLuVjq2kEKRTH8fXPTC0xKTkM+G7UlFkEwCXY3sFbSxvY375JoFowOAYbkaU47SrBvOefUlLZZ+6QA==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "data-uri-to-buffer": "1.2.0",
+        "debug": "2.6.9",
+        "extend": "3.0.1",
+        "file-uri-to-path": "1.0.0",
+        "ftp": "0.3.10",
+        "readable-stream": "2.3.3"
+      }
+    },
+    "get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        }
+      }
+    },
+    "glob": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+      "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+      "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"
+      }
+    },
+    "glob-base": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
+      "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
+      "dev": true,
+      "requires": {
+        "glob-parent": "2.0.0",
+        "is-glob": "2.0.1"
+      }
+    },
+    "glob-parent": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+      "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+      "dev": true,
+      "requires": {
+        "is-glob": "2.0.1"
+      }
+    },
+    "glob2base": {
+      "version": "0.0.12",
+      "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz",
+      "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=",
+      "dev": true,
+      "requires": {
+        "find-index": "0.1.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
+    },
+    "globby": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
+      "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
+      "dev": true,
+      "requires": {
+        "array-union": "1.0.2",
+        "arrify": "1.0.1",
+        "glob": "7.1.2",
+        "object-assign": "4.1.1",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "globule": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz",
+      "integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=",
+      "dev": true,
+      "requires": {
+        "glob": "7.1.2",
+        "lodash": "4.17.4",
+        "minimatch": "3.0.4"
+      }
+    },
+    "gonzales-pe-sl": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/gonzales-pe-sl/-/gonzales-pe-sl-4.2.3.tgz",
+      "integrity": "sha1-aoaLw4BkXxQf7rBCxvl/zHG1n+Y=",
+      "dev": true,
+      "requires": {
+        "minimist": "1.1.3"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.3.tgz",
+          "integrity": "sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=",
+          "dev": true
+        }
+      }
+    },
+    "graceful-fs": {
+      "version": "4.1.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+      "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+      "dev": true
+    },
+    "growl": {
+      "version": "1.10.3",
+      "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz",
+      "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==",
+      "dev": true
+    },
+    "habitat": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/habitat/-/habitat-3.1.2.tgz",
+      "integrity": "sha1-5c/V1zTlEiB8Lbut2AYExx0THeA=",
+      "dev": true,
+      "requires": {
+        "xtend": "2.1.2"
+      },
+      "dependencies": {
+        "object-keys": {
+          "version": "0.4.0",
+          "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+          "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+          "dev": true
+        },
+        "xtend": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+          "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+          "dev": true,
+          "requires": {
+            "object-keys": "0.4.0"
+          }
+        }
+      }
+    },
+    "handlebars": {
+      "version": "4.0.10",
+      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz",
+      "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=",
+      "dev": true,
+      "requires": {
+        "async": "1.5.2",
+        "optimist": "0.6.1",
+        "source-map": "0.4.4",
+        "uglify-js": "2.8.29"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.4.4",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+          "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+          "dev": true,
+          "requires": {
+            "amdefine": "1.0.1"
+          }
+        }
+      }
+    },
+    "har-validator": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
+      "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "commander": "2.12.2",
+        "is-my-json-valid": "2.16.1",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "has": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
+      "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
+      "dev": true,
+      "requires": {
+        "function-bind": "1.1.1"
+      }
+    },
+    "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-binary2": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.2.tgz",
+      "integrity": "sha1-6D26SfC5vk0CbSc2U1DZ8D9Uvpg=",
+      "dev": true,
+      "requires": {
+        "isarray": "2.0.1"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+          "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=",
+          "dev": true
+        }
+      }
+    },
+    "has-cors": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
+      "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=",
+      "dev": true
+    },
+    "has-flag": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+      "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+      "dev": true
+    },
+    "has-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
+      "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
+      "dev": true
+    },
+    "has-unicode": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
+      "dev": true
+    },
+    "has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "requires": {
+        "get-value": "2.0.6",
+        "has-values": "1.0.0",
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "has-values": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+      "dev": true,
+      "requires": {
+        "is-number": "3.0.0",
+        "kind-of": "4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.5"
+              }
+            }
+          }
+        },
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "1.1.5"
+          }
+        }
+      }
+    },
+    "hash-base": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
+      "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3"
+      }
+    },
+    "hash.js": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
+      "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "minimalistic-assert": "1.0.0"
+      }
+    },
+    "hawk": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+      "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+      "dev": true,
+      "requires": {
+        "boom": "2.10.1",
+        "cryptiles": "2.0.5",
+        "hoek": "2.16.3",
+        "sntp": "1.0.9"
+      }
+    },
+    "he": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
+      "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
+      "dev": true
+    },
+    "hipchat-notifier": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/hipchat-notifier/-/hipchat-notifier-1.1.0.tgz",
+      "integrity": "sha1-ttJJdVQ3wZEII2d5nTupoPI7Ix4=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "lodash": "4.17.4",
+        "request": "2.79.0"
+      }
+    },
+    "hmac-drbg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "requires": {
+        "hash.js": "1.1.3",
+        "minimalistic-assert": "1.0.0",
+        "minimalistic-crypto-utils": "1.0.1"
+      }
+    },
+    "hoek": {
+      "version": "2.16.3",
+      "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+      "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+      "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"
+      }
+    },
+    "hosted-git-info": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
+      "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==",
+      "dev": true
+    },
+    "htmlparser2": {
+      "version": "3.9.2",
+      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz",
+      "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=",
+      "dev": true,
+      "requires": {
+        "domelementtype": "1.3.0",
+        "domhandler": "2.4.1",
+        "domutils": "1.5.1",
+        "entities": "1.1.1",
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.3"
+      }
+    },
+    "http-errors": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+      "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
+      "dev": true,
+      "requires": {
+        "depd": "1.1.2",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.1.0",
+        "statuses": "1.5.0"
+      }
+    },
+    "http-proxy": {
+      "version": "1.17.0",
+      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz",
+      "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==",
+      "dev": true,
+      "requires": {
+        "eventemitter3": "3.1.0",
+        "follow-redirects": "1.4.1",
+        "requires-port": "1.0.0"
+      }
+    },
+    "http-proxy-agent": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
+      "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
+      "dev": true,
+      "requires": {
+        "agent-base": "4.2.0",
+        "debug": "3.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "http-signature": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+      "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "0.2.0",
+        "jsprim": "1.4.1",
+        "sshpk": "1.13.1"
+      }
+    },
+    "httpntlm": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.6.1.tgz",
+      "integrity": "sha1-rQFScUOi6Hc8+uapb1hla7UqNLI=",
+      "dev": true,
+      "requires": {
+        "httpreq": "0.4.24",
+        "underscore": "1.7.0"
+      },
+      "dependencies": {
+        "underscore": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz",
+          "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=",
+          "dev": true
+        }
+      }
+    },
+    "httpreq": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.4.24.tgz",
+      "integrity": "sha1-QzX/2CzZaWaKOUZckprGHWOTYn8=",
+      "dev": true
+    },
+    "https-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+      "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
+      "dev": true
+    },
+    "https-proxy-agent": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
+      "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
+      "dev": true,
+      "requires": {
+        "agent-base": "4.2.0",
+        "debug": "3.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "husky": {
+      "version": "0.14.3",
+      "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz",
+      "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==",
+      "dev": true,
+      "requires": {
+        "is-ci": "1.0.10",
+        "normalize-path": "1.0.0",
+        "strip-indent": "2.0.0"
+      },
+      "dependencies": {
+        "normalize-path": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz",
+          "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=",
+          "dev": true
+        },
+        "strip-indent": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
+          "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=",
+          "dev": true
+        }
+      }
+    },
+    "iconv-lite": {
+      "version": "0.4.19",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+      "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
+    },
+    "ieee754": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
+      "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=",
+      "dev": true
+    },
+    "ignore": {
+      "version": "3.3.5",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz",
+      "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==",
+      "dev": true
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "dev": true
+    },
+    "in-publish": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
+      "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=",
+      "dev": true
+    },
+    "indent-string": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+      "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+      "dev": true,
+      "requires": {
+        "repeating": "2.0.1"
+      }
+    },
+    "indexof": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+      "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
+      "dev": true
+    },
+    "inflection": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.10.0.tgz",
+      "integrity": "sha1-W//LEZetPoEFD44X4hZoCH7p6y8=",
+      "dev": true,
+      "optional": true
+    },
+    "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
+    },
+    "ini-parser": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/ini-parser/-/ini-parser-0.0.2.tgz",
+      "integrity": "sha1-+kF4flZ3Y7P/Zdel2alO23QHh+8=",
+      "dev": true
+    },
+    "inquirer": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
+      "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "3.1.0",
+        "chalk": "2.4.1",
+        "cli-cursor": "2.1.0",
+        "cli-width": "2.2.0",
+        "external-editor": "2.2.0",
+        "figures": "2.0.0",
+        "lodash": "4.17.4",
+        "mute-stream": "0.0.7",
+        "run-async": "2.3.0",
+        "rx-lite": "4.0.8",
+        "rx-lite-aggregates": "4.0.8",
+        "string-width": "2.1.1",
+        "strip-ansi": "4.0.0",
+        "through": "2.3.8"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.1"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.4.0"
+          }
+        },
+        "has-flag": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "interpret": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
+      "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=",
+      "dev": true
+    },
+    "intl-format-cache": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/intl-format-cache/-/intl-format-cache-2.1.0.tgz",
+      "integrity": "sha1-BKNp/sv61tpgBbrh8UMzMy3PkxY="
+    },
+    "intl-messageformat": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-2.2.0.tgz",
+      "integrity": "sha1-NFvNRt5jC3aDMwwuUhd/9eq0hPw=",
+      "requires": {
+        "intl-messageformat-parser": "1.4.0"
+      }
+    },
+    "intl-messageformat-parser": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz",
+      "integrity": "sha1-tD1FqXRoytvkQzHXS7Ho3qRPwHU="
+    },
+    "intl-relativeformat": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/intl-relativeformat/-/intl-relativeformat-2.1.0.tgz",
+      "integrity": "sha1-AQ8RBYAiUfQKxH0OPhogE0iiVd8=",
+      "requires": {
+        "intl-messageformat": "2.2.0"
+      }
+    },
+    "invariant": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
+      "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
+      "requires": {
+        "loose-envify": "1.3.1"
+      }
+    },
+    "invert-kv": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+      "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
+      "dev": true
+    },
+    "ip": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/ip/-/ip-1.0.1.tgz",
+      "integrity": "sha1-x+NWzeoiWucbNtcPLnGpK6TkJZA=",
+      "dev": true,
+      "optional": true
+    },
+    "is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "dev": true
+    },
+    "is-binary-path": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+      "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+      "dev": true,
+      "requires": {
+        "binary-extensions": "1.10.0"
+      }
+    },
+    "is-boolean-object": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.0.0.tgz",
+      "integrity": "sha1-mPiygDBoQhmpXzdc+9iM40Bd/5M=",
+      "dev": true
+    },
+    "is-buffer": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
+      "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
+      "dev": true
+    },
+    "is-builtin-module": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+      "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+      "dev": true,
+      "requires": {
+        "builtin-modules": "1.1.1"
+      }
+    },
+    "is-callable": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz",
+      "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=",
+      "dev": true
+    },
+    "is-ci": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz",
+      "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=",
+      "dev": true,
+      "requires": {
+        "ci-info": "1.1.2"
+      }
+    },
+    "is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "is-date-object": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
+      "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
+      "dev": true
+    },
+    "is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "requires": {
+        "is-accessor-descriptor": "0.1.6",
+        "is-data-descriptor": "0.1.4",
+        "kind-of": "5.1.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "is-dotfile": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
+      "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
+      "dev": true
+    },
+    "is-equal-shallow": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
+      "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
+      "dev": true,
+      "requires": {
+        "is-primitive": "2.0.0"
+      }
+    },
+    "is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+      "dev": true
+    },
+    "is-extglob": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+      "dev": true
+    },
+    "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"
+      }
+    },
+    "is-fullwidth-code-point": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+      "dev": true
+    },
+    "is-glob": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "1.0.0"
+      }
+    },
+    "is-my-json-valid": {
+      "version": "2.16.1",
+      "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz",
+      "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==",
+      "dev": true,
+      "requires": {
+        "generate-function": "2.0.0",
+        "generate-object-property": "1.2.0",
+        "jsonpointer": "4.0.1",
+        "xtend": "4.0.1"
+      }
+    },
+    "is-number": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
+      "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "is-number-object": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.3.tgz",
+      "integrity": "sha1-8mWrian0RQNO9q/xWo8AsA9VF5k=",
+      "dev": true
+    },
+    "is-odd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz",
+      "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==",
+      "dev": true,
+      "requires": {
+        "is-number": "4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+          "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+          "dev": true
+        }
+      }
+    },
+    "is-path-cwd": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
+      "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
+      "dev": true
+    },
+    "is-path-in-cwd": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
+      "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
+      "dev": true,
+      "requires": {
+        "is-path-inside": "1.0.0"
+      }
+    },
+    "is-path-inside": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
+      "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=",
+      "dev": true,
+      "requires": {
+        "path-is-inside": "1.0.2"
+      }
+    },
+    "is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dev": true,
+      "requires": {
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "is-posix-bracket": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
+      "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=",
+      "dev": true
+    },
+    "is-primitive": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
+      "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
+      "dev": true
+    },
+    "is-promise": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+      "dev": true
+    },
+    "is-property": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+      "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
+      "dev": true
+    },
+    "is-regex": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+      "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+      "dev": true,
+      "requires": {
+        "has": "1.0.1"
+      }
+    },
+    "is-resolvable": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz",
+      "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=",
+      "dev": true,
+      "requires": {
+        "tryit": "1.0.3"
+      }
+    },
+    "is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+    },
+    "is-string": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.4.tgz",
+      "integrity": "sha1-zDqbaYV9Yh6WNyWiTK7shzuCbmQ=",
+      "dev": true
+    },
+    "is-subset": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz",
+      "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=",
+      "dev": true
+    },
+    "is-symbol": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
+      "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=",
+      "dev": true
+    },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "dev": true
+    },
+    "is-utf8": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+      "dev": true
+    },
+    "is-windows": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+      "dev": true
+    },
+    "isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+      "dev": true
+    },
+    "isbinaryfile": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz",
+      "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=",
+      "dev": true
+    },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "isobject": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+      "dev": true,
+      "requires": {
+        "isarray": "1.0.0"
+      }
+    },
+    "isomorphic-fetch": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
+      "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
+      "requires": {
+        "node-fetch": "1.7.3",
+        "whatwg-fetch": "2.0.3"
+      },
+      "dependencies": {
+        "node-fetch": {
+          "version": "1.7.3",
+          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
+          "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+          "requires": {
+            "encoding": "0.1.12",
+            "is-stream": "1.1.0"
+          }
+        }
+      }
+    },
+    "isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+      "dev": true
+    },
+    "istanbul": {
+      "version": "0.4.5",
+      "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz",
+      "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=",
+      "dev": true,
+      "requires": {
+        "abbrev": "1.0.9",
+        "async": "1.5.2",
+        "escodegen": "1.8.1",
+        "esprima": "2.7.3",
+        "glob": "5.0.15",
+        "handlebars": "4.0.10",
+        "js-yaml": "3.10.0",
+        "mkdirp": "0.5.1",
+        "nopt": "3.0.6",
+        "once": "1.4.0",
+        "resolve": "1.1.7",
+        "supports-color": "3.2.3",
+        "which": "1.3.0",
+        "wordwrap": "1.0.0"
+      },
+      "dependencies": {
+        "esprima": {
+          "version": "2.7.3",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+          "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+          "dev": true
+        },
+        "glob": {
+          "version": "5.0.15",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+          "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+          "dev": true,
+          "requires": {
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.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
+        },
+        "resolve": {
+          "version": "1.1.7",
+          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+          "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "3.2.3",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+          "dev": true,
+          "requires": {
+            "has-flag": "1.0.0"
+          }
+        },
+        "wordwrap": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+          "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+          "dev": true
+        }
+      }
+    },
+    "istanbul-instrumenter-loader": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-0.2.0.tgz",
+      "integrity": "sha1-ZD5OXk6PlGaGOimpd9KDqzcsAZw=",
+      "dev": true,
+      "requires": {
+        "istanbul": "0.4.5",
+        "loader-utils": "0.2.16",
+        "object-assign": "4.1.1"
+      }
+    },
+    "joi-browser": {
+      "version": "13.0.1",
+      "resolved": "https://registry.npmjs.org/joi-browser/-/joi-browser-13.0.1.tgz",
+      "integrity": "sha512-o5rSmqmneWaq/LXt5Rq9moyeE8vW4gGwLL3zRT7iA2wiUgVnrE8EPfNvYEVH0yetGpyzH4LMW/NGb0ChvYk7pQ==",
+      "dev": true
+    },
+    "js-base64": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz",
+      "integrity": "sha512-Y2/+DnfJJXT1/FCwUebUhLWb3QihxiSC42+ctHLGogmW2jPY6LCapMdFZXRvVP2z6qyKW7s6qncE/9gSqZiArw==",
+      "dev": true
+    },
+    "js-tokens": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+      "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
+    },
+    "js-yaml": {
+      "version": "3.10.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
+      "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
+      "dev": true,
+      "requires": {
+        "argparse": "1.0.9",
+        "esprima": "4.0.0"
+      }
+    },
+    "jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+      "dev": true,
+      "optional": true
+    },
+    "jsesc": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+      "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
+      "dev": true
+    },
+    "jshint": {
+      "version": "2.9.5",
+      "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.5.tgz",
+      "integrity": "sha1-HnJSkVzmgbQIJ+4UJIxG006apiw=",
+      "dev": true,
+      "requires": {
+        "cli": "1.0.1",
+        "console-browserify": "1.1.0",
+        "exit": "0.1.2",
+        "htmlparser2": "3.8.3",
+        "lodash": "3.7.0",
+        "minimatch": "3.0.4",
+        "shelljs": "0.3.0",
+        "strip-json-comments": "1.0.4"
+      },
+      "dependencies": {
+        "domhandler": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
+          "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=",
+          "dev": true,
+          "requires": {
+            "domelementtype": "1.3.0"
+          }
+        },
+        "entities": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
+          "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=",
+          "dev": true
+        },
+        "htmlparser2": {
+          "version": "3.8.3",
+          "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
+          "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=",
+          "dev": true,
+          "requires": {
+            "domelementtype": "1.3.0",
+            "domhandler": "2.3.0",
+            "domutils": "1.5.1",
+            "entities": "1.0.0",
+            "readable-stream": "1.1.14"
+          }
+        },
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+          "dev": true
+        },
+        "lodash": {
+          "version": "3.7.0",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz",
+          "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "1.1.14",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+          "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "0.0.1",
+            "string_decoder": "0.10.31"
+          }
+        },
+        "shelljs": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
+          "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=",
+          "dev": true
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+          "dev": true
+        },
+        "strip-json-comments": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
+          "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=",
+          "dev": true
+        }
+      }
+    },
+    "json-loader": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz",
+      "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==",
+      "dev": true
+    },
+    "json-parse-better-errors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz",
+      "integrity": "sha512-xyQpxeWWMKyJps9CuGJYeng6ssI5bpqS9ltQpdVQ90t4ql6NdnxFKh95JcRt2cun/DjMVNrdjniLPuMA69xmCw==",
+      "dev": true
+    },
+    "json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "dev": true
+    },
+    "json-schema-traverse": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+      "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+      "dev": true
+    },
+    "json-stable-stringify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+      "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+      "dev": true,
+      "requires": {
+        "jsonify": "0.0.0"
+      }
+    },
+    "json-stable-stringify-without-jsonify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+      "dev": true
+    },
+    "json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+      "dev": true
+    },
+    "json5": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+      "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+      "dev": true
+    },
+    "jsonfile": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11"
+      }
+    },
+    "jsonify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+      "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+      "dev": true
+    },
+    "jsonpointer": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
+      "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
+      "dev": true
+    },
+    "jsonpointer.js": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/jsonpointer.js/-/jsonpointer.js-0.4.0.tgz",
+      "integrity": "sha1-ACyxI/dnqv3rAZYTLOXE+ZQcyro=",
+      "dev": true
+    },
+    "jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        }
+      }
+    },
+    "jsx-ast-utils": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz",
+      "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=",
+      "dev": true,
+      "requires": {
+        "array-includes": "3.0.3"
+      }
+    },
+    "just-extend": {
+      "version": "1.1.27",
+      "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz",
+      "integrity": "sha512-mJVp13Ix6gFo3SBAy9U/kL+oeZqzlYYYLQBwXVBlVzIsZwBqGREnOro24oC/8s8aox+rJhtZ2DiQof++IrkA+g==",
+      "dev": true
+    },
+    "karma": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/karma/-/karma-2.0.2.tgz",
+      "integrity": "sha1-TS25QChQpmVR+nhLAWT7CCTtjEs=",
+      "dev": true,
+      "requires": {
+        "bluebird": "3.5.1",
+        "body-parser": "1.18.2",
+        "chokidar": "1.7.0",
+        "colors": "1.1.2",
+        "combine-lists": "1.0.1",
+        "connect": "3.6.6",
+        "core-js": "2.5.5",
+        "di": "0.0.1",
+        "dom-serialize": "2.2.1",
+        "expand-braces": "0.1.2",
+        "glob": "7.1.2",
+        "graceful-fs": "4.1.11",
+        "http-proxy": "1.17.0",
+        "isbinaryfile": "3.0.2",
+        "lodash": "4.17.4",
+        "log4js": "2.5.3",
+        "mime": "1.4.1",
+        "minimatch": "3.0.4",
+        "optimist": "0.6.1",
+        "qjobs": "1.2.0",
+        "range-parser": "1.2.0",
+        "rimraf": "2.6.2",
+        "safe-buffer": "5.1.1",
+        "socket.io": "2.0.4",
+        "source-map": "0.6.1",
+        "tmp": "0.0.33",
+        "useragent": "2.2.1"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "2.5.5",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.5.tgz",
+          "integrity": "sha1-sU3ek2xkDAV5prUMq8wTLdYSfjs=",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "karma-chai": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/karma-chai/-/karma-chai-0.1.0.tgz",
+      "integrity": "sha1-vuWtQEAFF4Ea40u5RfdikJEIt5o=",
+      "dev": true
+    },
+    "karma-coverage": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-1.1.1.tgz",
+      "integrity": "sha1-Wv+LOc9plNwi3kyENix2ABtjfPY=",
+      "dev": true,
+      "requires": {
+        "dateformat": "1.0.12",
+        "istanbul": "0.4.5",
+        "lodash": "3.10.1",
+        "minimatch": "3.0.4",
+        "source-map": "0.5.7"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "3.10.1",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+          "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+          "dev": true
+        }
+      }
+    },
+    "karma-firefox-launcher": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.1.0.tgz",
+      "integrity": "sha512-LbZ5/XlIXLeQ3cqnCbYLn+rOVhuMIK9aZwlP6eOLGzWdo1UVp7t6CN3DP4SafiRLjexKwHeKHDm0c38Mtd3VxA==",
+      "dev": true
+    },
+    "karma-mocha": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-1.3.0.tgz",
+      "integrity": "sha1-7qrH/8DiAetjxGdEDStpx883eL8=",
+      "dev": true,
+      "requires": {
+        "minimist": "1.2.0"
+      }
+    },
+    "karma-mocha-reporter": {
+      "version": "2.2.5",
+      "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz",
+      "integrity": "sha1-FRIAlejtgZGG5HoLAS8810GJVWA=",
+      "dev": true,
+      "requires": {
+        "chalk": "2.3.0",
+        "log-symbols": "2.1.0",
+        "strip-ansi": "4.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.1"
+          }
+        },
+        "chalk": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.5.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "karma-sinon": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/karma-sinon/-/karma-sinon-1.0.5.tgz",
+      "integrity": "sha1-TjRD8oMP3s/2JNN0cWPxIX2qKpo=",
+      "dev": true
+    },
+    "karma-sourcemap-loader": {
+      "version": "0.3.7",
+      "resolved": "https://registry.npmjs.org/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz",
+      "integrity": "sha1-kTIsd/jxPUb+0GKwQuEAnUxFBdg=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11"
+      }
+    },
+    "karma-webpack": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-3.0.0.tgz",
+      "integrity": "sha512-Ja1o9LLoqWaJyUNhTKaXjWiEH9y7a9H3mzP8pYB30SBsgoF5KBS/65NeHFd+QPuT9ITrym8xFt8BZeGbcOfujA==",
+      "dev": true,
+      "requires": {
+        "async": "2.6.0",
+        "babel-runtime": "6.26.0",
+        "loader-utils": "1.1.0",
+        "lodash": "4.17.4",
+        "source-map": "0.5.7",
+        "webpack-dev-middleware": "2.0.6"
+      },
+      "dependencies": {
+        "async": {
+          "version": "2.6.0",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
+          "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
+          "dev": true,
+          "requires": {
+            "lodash": "4.17.4"
+          }
+        },
+        "loader-utils": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+          "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+          "dev": true,
+          "requires": {
+            "big.js": "3.2.0",
+            "emojis-list": "2.1.0",
+            "json5": "0.5.1"
+          }
+        }
+      }
+    },
+    "keypress": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz",
+      "integrity": "sha1-HoBFQlABjbrUw/6USX1uZ7YmnHc=",
+      "dev": true
+    },
+    "kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "requires": {
+        "is-buffer": "1.1.5"
+      }
+    },
+    "klaw": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+      "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11"
+      }
+    },
+    "known-css-properties": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.3.0.tgz",
+      "integrity": "sha512-QMQcnKAiQccfQTqtBh/qwquGZ2XK/DXND1jrcN9M8gMMy99Gwla7GQjndVUsEqIaRyP6bsFRuhwRj5poafBGJQ==",
+      "dev": true
+    },
+    "lazy-cache": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
+      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
+      "dev": true
+    },
+    "lcid": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+      "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+      "dev": true,
+      "requires": {
+        "invert-kv": "1.0.0"
+      }
+    },
+    "levn": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+      "dev": true,
+      "requires": {
+        "prelude-ls": "1.1.2",
+        "type-check": "0.3.2"
+      }
+    },
+    "libbase64": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz",
+      "integrity": "sha1-YjUag5VjrF/1vSbxL2Dpgwu3UeY=",
+      "dev": true
+    },
+    "libmime": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/libmime/-/libmime-3.0.0.tgz",
+      "integrity": "sha1-UaGp50SOy9Ms2lRCFnW7IbwJPaY=",
+      "dev": true,
+      "requires": {
+        "iconv-lite": "0.4.15",
+        "libbase64": "0.1.0",
+        "libqp": "1.1.0"
+      },
+      "dependencies": {
+        "iconv-lite": {
+          "version": "0.4.15",
+          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz",
+          "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=",
+          "dev": true
+        }
+      }
+    },
+    "libqp": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz",
+      "integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=",
+      "dev": true
+    },
+    "load-json-file": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+      "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "parse-json": "2.2.0",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1",
+        "strip-bom": "2.0.0"
+      }
+    },
+    "loader-runner": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz",
+      "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=",
+      "dev": true
+    },
+    "loader-utils": {
+      "version": "0.2.16",
+      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.16.tgz",
+      "integrity": "sha1-8IYyBm7YKCg13/iN+1JwR2Wt7m0=",
+      "dev": true,
+      "requires": {
+        "big.js": "3.2.0",
+        "emojis-list": "2.1.0",
+        "json5": "0.5.1",
+        "object-assign": "4.1.1"
+      }
+    },
+    "locate-path": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+      "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+      "dev": true,
+      "requires": {
+        "p-locate": "2.0.0",
+        "path-exists": "3.0.0"
+      }
+    },
+    "lodash": {
+      "version": "4.17.4",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
+      "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
+    },
+    "lodash-es": {
+      "version": "4.17.4",
+      "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.4.tgz",
+      "integrity": "sha1-3MHXVS4VCgZABzupyzHXDwMpUOc="
+    },
+    "lodash.assign": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
+      "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
+      "dev": true
+    },
+    "lodash.capitalize": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz",
+      "integrity": "sha1-+CbJtOKoUR2E46yinbBeGk87cqk=",
+      "dev": true
+    },
+    "lodash.clonedeep": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+      "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
+      "dev": true
+    },
+    "lodash.flattendeep": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
+      "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
+      "dev": true
+    },
+    "lodash.get": {
+      "version": "4.4.2",
+      "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+      "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
+      "dev": true
+    },
+    "lodash.kebabcase": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
+      "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=",
+      "dev": true
+    },
+    "lodash.mergewith": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz",
+      "integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU=",
+      "dev": true
+    },
+    "log-symbols": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.1.0.tgz",
+      "integrity": "sha512-zLeLrzMA1A2vRF1e/0Mo+LNINzi6jzBylHj5WqvQ/WK/5WCZt8si9SyN4p9llr/HRYvVR1AoXHRHl4WTHyQAzQ==",
+      "dev": true,
+      "requires": {
+        "chalk": "2.3.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.1"
+          }
+        },
+        "chalk": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.5.0"
+          }
+        },
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "log4js": {
+      "version": "2.5.3",
+      "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.5.3.tgz",
+      "integrity": "sha512-YL/qpTxYtK0iWWbuKCrevDZz5lh+OjyHHD+mICqpjnYGKdNRBvPeh/1uYjkKUemT1CSO4wwLOwphWMpKAnD9kw==",
+      "dev": true,
+      "requires": {
+        "amqplib": "0.5.2",
+        "axios": "0.15.3",
+        "circular-json": "0.5.3",
+        "date-format": "1.2.0",
+        "debug": "3.1.0",
+        "hipchat-notifier": "1.1.0",
+        "loggly": "1.1.1",
+        "mailgun-js": "0.7.15",
+        "nodemailer": "2.7.2",
+        "redis": "2.8.0",
+        "semver": "5.4.1",
+        "slack-node": "0.2.0",
+        "streamroller": "0.7.0"
+      },
+      "dependencies": {
+        "circular-json": {
+          "version": "0.5.3",
+          "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.3.tgz",
+          "integrity": "sha512-YlxLOimeIoQGHnMe3kbf8qIV2Bj7uXLbljMPRguNT49GmSAzooNfS9EJ91rSJKbLBOOzM5agvtx0WyechZN/Hw==",
+          "dev": true
+        },
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "loggly": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/loggly/-/loggly-1.1.1.tgz",
+      "integrity": "sha1-Cg/B0/o6XsRP3HuJe+uipGlc6+4=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "json-stringify-safe": "5.0.1",
+        "request": "2.75.0",
+        "timespan": "2.3.0"
+      },
+      "dependencies": {
+        "form-data": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.0.0.tgz",
+          "integrity": "sha1-bwrrrcxdoWwT4ezBETfYX5uIOyU=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "asynckit": "0.4.0",
+            "combined-stream": "1.0.5",
+            "mime-types": "2.1.17"
+          }
+        },
+        "qs": {
+          "version": "6.2.3",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz",
+          "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=",
+          "dev": true,
+          "optional": true
+        },
+        "request": {
+          "version": "2.75.0",
+          "resolved": "https://registry.npmjs.org/request/-/request-2.75.0.tgz",
+          "integrity": "sha1-0rgmiihtoT6qXQGt9dGMyQ9lfZM=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "aws-sign2": "0.6.0",
+            "aws4": "1.6.0",
+            "bl": "1.1.2",
+            "caseless": "0.11.0",
+            "combined-stream": "1.0.5",
+            "extend": "3.0.1",
+            "forever-agent": "0.6.1",
+            "form-data": "2.0.0",
+            "har-validator": "2.0.6",
+            "hawk": "3.1.3",
+            "http-signature": "1.1.1",
+            "is-typedarray": "1.0.0",
+            "isstream": "0.1.2",
+            "json-stringify-safe": "5.0.1",
+            "mime-types": "2.1.17",
+            "node-uuid": "1.4.8",
+            "oauth-sign": "0.8.2",
+            "qs": "6.2.3",
+            "stringstream": "0.0.5",
+            "tough-cookie": "2.3.3",
+            "tunnel-agent": "0.4.3"
+          }
+        }
+      }
+    },
+    "loglevelnext": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.5.tgz",
+      "integrity": "sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==",
+      "dev": true,
+      "requires": {
+        "es6-symbol": "3.1.1",
+        "object.assign": "4.1.0"
+      }
+    },
+    "lolex": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.3.2.tgz",
+      "integrity": "sha512-A5pN2tkFj7H0dGIAM6MFvHKMJcPnjZsOMvR7ujCjfgW5TbV6H9vb1PgxLtHvjqNZTHsUolz+6/WEO0N1xNx2ng==",
+      "dev": true
+    },
+    "longest": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+      "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
+      "dev": true
+    },
+    "loose-envify": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
+      "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
+      "requires": {
+        "js-tokens": "3.0.2"
+      }
+    },
+    "loud-rejection": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+      "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+      "dev": true,
+      "requires": {
+        "currently-unhandled": "0.4.1",
+        "signal-exit": "3.0.2"
+      }
+    },
+    "lru-cache": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
+      "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
+      "dev": true,
+      "requires": {
+        "pseudomap": "1.0.2",
+        "yallist": "2.1.2"
+      }
+    },
+    "mailcomposer": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-4.0.1.tgz",
+      "integrity": "sha1-DhxEsqB890DuF9wUm6AJ8Zyt/rQ=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "buildmail": "4.0.1",
+        "libmime": "3.0.0"
+      }
+    },
+    "mailgun-js": {
+      "version": "0.7.15",
+      "resolved": "https://registry.npmjs.org/mailgun-js/-/mailgun-js-0.7.15.tgz",
+      "integrity": "sha1-7jZqINrGTDwVwD1sGz4O15UlKrs=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "async": "2.1.5",
+        "debug": "2.2.0",
+        "form-data": "2.1.4",
+        "inflection": "1.10.0",
+        "is-stream": "1.1.0",
+        "path-proxy": "1.0.0",
+        "proxy-agent": "2.0.0",
+        "q": "1.4.1",
+        "tsscmp": "1.0.5"
+      },
+      "dependencies": {
+        "async": {
+          "version": "2.1.5",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.1.5.tgz",
+          "integrity": "sha1-5YfGhYCZSsZ/xW/4bTrFa9voELw=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "lodash": "4.17.4"
+          }
+        },
+        "debug": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+          "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ms": "0.7.1"
+          }
+        },
+        "ms": {
+          "version": "0.7.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
+          "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
+          "dev": true,
+          "optional": true
+        },
+        "q": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz",
+          "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "make-dir": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz",
+      "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==",
+      "dev": true,
+      "requires": {
+        "pify": "3.0.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        }
+      }
+    },
+    "map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true
+    },
+    "map-obj": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+      "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+      "dev": true
+    },
+    "map-stream": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
+      "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=",
+      "dev": true
+    },
+    "map-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+      "dev": true,
+      "requires": {
+        "object-visit": "1.0.1"
+      }
+    },
+    "md5.js": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
+      "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
+      "dev": true,
+      "requires": {
+        "hash-base": "3.0.4",
+        "inherits": "2.0.3"
+      },
+      "dependencies": {
+        "hash-base": {
+          "version": "3.0.4",
+          "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
+          "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+          "dev": true,
+          "requires": {
+            "inherits": "2.0.3",
+            "safe-buffer": "5.1.1"
+          }
+        }
+      }
+    },
+    "media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+      "dev": true
+    },
+    "mem": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz",
+      "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=",
+      "dev": true,
+      "requires": {
+        "mimic-fn": "1.2.0"
+      }
+    },
+    "memory-fs": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
+      "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
+      "dev": true,
+      "requires": {
+        "errno": "0.1.6",
+        "readable-stream": "2.3.3"
+      }
+    },
+    "memorystream": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
+      "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=",
+      "dev": true
+    },
+    "meow": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+      "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+      "dev": true,
+      "requires": {
+        "camelcase-keys": "2.1.0",
+        "decamelize": "1.2.0",
+        "loud-rejection": "1.6.0",
+        "map-obj": "1.0.1",
+        "minimist": "1.2.0",
+        "normalize-package-data": "2.4.0",
+        "object-assign": "4.1.1",
+        "read-pkg-up": "1.0.1",
+        "redent": "1.0.0",
+        "trim-newlines": "1.0.0"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "merge": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz",
+      "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=",
+      "dev": true
+    },
+    "micromatch": {
+      "version": "2.3.11",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+      "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+      "dev": true,
+      "requires": {
+        "arr-diff": "2.0.0",
+        "array-unique": "0.2.1",
+        "braces": "1.8.5",
+        "expand-brackets": "0.1.5",
+        "extglob": "0.3.2",
+        "filename-regex": "2.0.1",
+        "is-extglob": "1.0.0",
+        "is-glob": "2.0.1",
+        "kind-of": "3.2.2",
+        "normalize-path": "2.1.1",
+        "object.omit": "2.0.1",
+        "parse-glob": "3.0.4",
+        "regex-cache": "0.4.4"
+      }
+    },
+    "miller-rabin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "brorand": "1.1.0"
+      }
+    },
+    "mime": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+      "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
+      "dev": true
+    },
+    "mime-db": {
+      "version": "1.30.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
+      "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=",
+      "dev": true
+    },
+    "mime-types": {
+      "version": "2.1.17",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
+      "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
+      "dev": true,
+      "requires": {
+        "mime-db": "1.30.0"
+      }
+    },
+    "mimeparse": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/mimeparse/-/mimeparse-0.1.4.tgz",
+      "integrity": "sha1-2vsCdSNw/SJgk64xUsJxrwGsJUo=",
+      "dev": true
+    },
+    "mimic-fn": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+      "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+      "dev": true
+    },
+    "minimalistic-assert": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
+      "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=",
+      "dev": true
+    },
+    "minimalistic-crypto-utils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+      "dev": true
+    },
+    "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": "1.2.0",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+      "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+      "dev": true
+    },
+    "mixin-deep": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
+      "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+      "dev": true,
+      "requires": {
+        "for-in": "1.0.2",
+        "is-extendable": "1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "2.0.4"
+          }
+        }
+      }
+    },
+    "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"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "0.0.8",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+          "dev": true
+        }
+      }
+    },
+    "mocha": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.1.1.tgz",
+      "integrity": "sha512-kKKs/H1KrMMQIEsWNxGmb4/BGsmj0dkeyotEvbrAuQ01FcWRLssUNXCEUZk6SZtyJBi6EE7SL0zDDtItw1rGhw==",
+      "dev": true,
+      "requires": {
+        "browser-stdout": "1.3.1",
+        "commander": "2.11.0",
+        "debug": "3.1.0",
+        "diff": "3.5.0",
+        "escape-string-regexp": "1.0.5",
+        "glob": "7.1.2",
+        "growl": "1.10.3",
+        "he": "1.1.1",
+        "minimatch": "3.0.4",
+        "mkdirp": "0.5.1",
+        "supports-color": "4.4.0"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.11.0",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
+          "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
+          "dev": true
+        },
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "4.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
+          "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "mock-raf": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/mock-raf/-/mock-raf-1.0.0.tgz",
+      "integrity": "sha1-oogUUXiJPiBAsjDyGC/uIEnxbyU=",
+      "dev": true,
+      "requires": {
+        "object-assign": "3.0.0"
+      },
+      "dependencies": {
+        "object-assign": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz",
+          "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=",
+          "dev": true
+        }
+      }
+    },
+    "ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "mute-stream": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+      "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+      "dev": true
+    },
+    "nan": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.7.0.tgz",
+      "integrity": "sha1-2Vv3IeyHfgjbJ27T/G63j5CDrUY=",
+      "dev": true
+    },
+    "nanomatch": {
+      "version": "1.2.9",
+      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
+      "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==",
+      "dev": true,
+      "requires": {
+        "arr-diff": "4.0.0",
+        "array-unique": "0.3.2",
+        "define-property": "2.0.2",
+        "extend-shallow": "3.0.2",
+        "fragment-cache": "0.2.1",
+        "is-odd": "2.0.0",
+        "is-windows": "1.0.2",
+        "kind-of": "6.0.2",
+        "object.pick": "1.3.0",
+        "regex-not": "1.0.2",
+        "snapdragon": "0.8.2",
+        "to-regex": "3.0.2"
+      },
+      "dependencies": {
+        "arr-diff": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+          "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+          "dev": true
+        },
+        "array-unique": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+          "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "natural-compare": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+      "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+      "dev": true
+    },
+    "nearley": {
+      "version": "2.11.0",
+      "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.11.0.tgz",
+      "integrity": "sha512-clqqhEuP0ZCJQ85Xv2I/4o2Gs/fvSR6fCg5ZHVE2c8evWyNk2G++ih4JOO3lMb/k/09x6ihQ2nzKUlB/APCWjg==",
+      "dev": true,
+      "requires": {
+        "nomnom": "1.6.2",
+        "railroad-diagrams": "1.0.0",
+        "randexp": "0.4.6"
+      }
+    },
+    "negotiator": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+      "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
+      "dev": true
+    },
+    "netmask": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz",
+      "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=",
+      "dev": true,
+      "optional": true
+    },
+    "nise": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/nise/-/nise-1.3.3.tgz",
+      "integrity": "sha512-v1J/FLUB9PfGqZLGDBhQqODkbLotP0WtLo9R4EJY2PPu5f5Xg4o0rA8FDlmrjFSv9vBBKcfnOSpfYYuu5RTHqg==",
+      "dev": true,
+      "requires": {
+        "@sinonjs/formatio": "2.0.0",
+        "just-extend": "1.1.27",
+        "lolex": "2.3.2",
+        "path-to-regexp": "1.7.0",
+        "text-encoding": "0.6.4"
+      }
+    },
+    "node-fetch": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
+      "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=",
+      "dev": true
+    },
+    "node-gyp": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz",
+      "integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=",
+      "dev": true,
+      "requires": {
+        "fstream": "1.0.11",
+        "glob": "7.1.2",
+        "graceful-fs": "4.1.11",
+        "minimatch": "3.0.4",
+        "mkdirp": "0.5.1",
+        "nopt": "3.0.6",
+        "npmlog": "4.1.2",
+        "osenv": "0.1.4",
+        "request": "2.79.0",
+        "rimraf": "2.6.2",
+        "semver": "5.3.0",
+        "tar": "2.2.1",
+        "which": "1.3.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+          "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
+          "dev": true
+        }
+      }
+    },
+    "node-libs-browser": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz",
+      "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==",
+      "dev": true,
+      "requires": {
+        "assert": "1.4.1",
+        "browserify-zlib": "0.2.0",
+        "buffer": "4.9.1",
+        "console-browserify": "1.1.0",
+        "constants-browserify": "1.0.0",
+        "crypto-browserify": "3.12.0",
+        "domain-browser": "1.1.7",
+        "events": "1.1.1",
+        "https-browserify": "1.0.0",
+        "os-browserify": "0.3.0",
+        "path-browserify": "0.0.0",
+        "process": "0.11.10",
+        "punycode": "1.4.1",
+        "querystring-es3": "0.2.1",
+        "readable-stream": "2.3.3",
+        "stream-browserify": "2.0.1",
+        "stream-http": "2.8.0",
+        "string_decoder": "1.0.3",
+        "timers-browserify": "2.0.6",
+        "tty-browserify": "0.0.0",
+        "url": "0.11.0",
+        "util": "0.10.3",
+        "vm-browserify": "0.0.4"
+      },
+      "dependencies": {
+        "buffer": {
+          "version": "4.9.1",
+          "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
+          "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
+          "dev": true,
+          "requires": {
+            "base64-js": "1.2.1",
+            "ieee754": "1.1.8",
+            "isarray": "1.0.0"
+          }
+        },
+        "timers-browserify": {
+          "version": "2.0.6",
+          "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.6.tgz",
+          "integrity": "sha512-HQ3nbYRAowdVd0ckGFvmJPPCOH/CHleFN/Y0YQCX1DVaB7t+KFvisuyN09fuP8Jtp1CpfSh8O8bMkHbdbPe6Pw==",
+          "dev": true,
+          "requires": {
+            "setimmediate": "1.0.5"
+          }
+        },
+        "tty-browserify": {
+          "version": "0.0.0",
+          "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+          "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
+          "dev": true
+        }
+      }
+    },
+    "node-sass": {
+      "version": "4.7.2",
+      "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.7.2.tgz",
+      "integrity": "sha512-CaV+wLqZ7//Jdom5aUFCpGNoECd7BbNhjuwdsX/LkXBrHl8eb1Wjw4HvWqcFvhr5KuNgAk8i/myf/MQ1YYeroA==",
+      "dev": true,
+      "requires": {
+        "async-foreach": "0.1.3",
+        "chalk": "1.1.3",
+        "cross-spawn": "3.0.1",
+        "gaze": "1.1.2",
+        "get-stdin": "4.0.1",
+        "glob": "7.1.2",
+        "in-publish": "2.0.0",
+        "lodash.assign": "4.2.0",
+        "lodash.clonedeep": "4.5.0",
+        "lodash.mergewith": "4.6.0",
+        "meow": "3.7.0",
+        "mkdirp": "0.5.1",
+        "nan": "2.7.0",
+        "node-gyp": "3.6.2",
+        "npmlog": "4.1.2",
+        "request": "2.79.0",
+        "sass-graph": "2.2.4",
+        "stdout-stream": "1.4.0",
+        "true-case-path": "1.0.2"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
+          "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
+          "dev": true,
+          "requires": {
+            "lru-cache": "4.1.1",
+            "which": "1.3.0"
+          }
+        }
+      }
+    },
+    "node-uuid": {
+      "version": "1.4.8",
+      "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
+      "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=",
+      "dev": true,
+      "optional": true
+    },
+    "nodemailer": {
+      "version": "2.7.2",
+      "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-2.7.2.tgz",
+      "integrity": "sha1-8kLmSa7q45tsftdA73sGHEBNMPk=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "libmime": "3.0.0",
+        "mailcomposer": "4.0.1",
+        "nodemailer-direct-transport": "3.3.2",
+        "nodemailer-shared": "1.1.0",
+        "nodemailer-smtp-pool": "2.8.2",
+        "nodemailer-smtp-transport": "2.7.2",
+        "socks": "1.1.9"
+      },
+      "dependencies": {
+        "ip": {
+          "version": "1.1.5",
+          "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+          "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
+          "dev": true,
+          "optional": true
+        },
+        "socks": {
+          "version": "1.1.9",
+          "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.9.tgz",
+          "integrity": "sha1-Yo1+TQSRJDVEWsC25Fk3bLPm1pE=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ip": "1.1.5",
+            "smart-buffer": "1.1.15"
+          }
+        }
+      }
+    },
+    "nodemailer-direct-transport": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/nodemailer-direct-transport/-/nodemailer-direct-transport-3.3.2.tgz",
+      "integrity": "sha1-6W+vuQNYVglH5WkBfZfmBzilCoY=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "nodemailer-shared": "1.1.0",
+        "smtp-connection": "2.12.0"
+      }
+    },
+    "nodemailer-fetch": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz",
+      "integrity": "sha1-ecSQihwPXzdbc/6IjamCj23JY6Q=",
+      "dev": true
+    },
+    "nodemailer-shared": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz",
+      "integrity": "sha1-z1mU4v0mjQD1zw+nZ6CBae2wfsA=",
+      "dev": true,
+      "requires": {
+        "nodemailer-fetch": "1.6.0"
+      }
+    },
+    "nodemailer-smtp-pool": {
+      "version": "2.8.2",
+      "resolved": "https://registry.npmjs.org/nodemailer-smtp-pool/-/nodemailer-smtp-pool-2.8.2.tgz",
+      "integrity": "sha1-LrlNbPhXgLG0clzoU7nL1ejajHI=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "nodemailer-shared": "1.1.0",
+        "nodemailer-wellknown": "0.1.10",
+        "smtp-connection": "2.12.0"
+      }
+    },
+    "nodemailer-smtp-transport": {
+      "version": "2.7.2",
+      "resolved": "https://registry.npmjs.org/nodemailer-smtp-transport/-/nodemailer-smtp-transport-2.7.2.tgz",
+      "integrity": "sha1-A9ccdjFPFKx9vHvwM6am0W1n+3c=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "nodemailer-shared": "1.1.0",
+        "nodemailer-wellknown": "0.1.10",
+        "smtp-connection": "2.12.0"
+      }
+    },
+    "nodemailer-wellknown": {
+      "version": "0.1.10",
+      "resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.10.tgz",
+      "integrity": "sha1-WG24EB2zDLRDjrVGc3pBqtDPE9U=",
+      "dev": true
+    },
+    "nomnom": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.6.2.tgz",
+      "integrity": "sha1-hKZqJgF0QI/Ft3oY+IjszET7aXE=",
+      "dev": true,
+      "requires": {
+        "colors": "0.5.1",
+        "underscore": "1.4.4"
+      },
+      "dependencies": {
+        "colors": {
+          "version": "0.5.1",
+          "resolved": "https://registry.npmjs.org/colors/-/colors-0.5.1.tgz",
+          "integrity": "sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q=",
+          "dev": true
+        }
+      }
+    },
+    "nopt": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+      "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+      "dev": true,
+      "requires": {
+        "abbrev": "1.0.9"
+      }
+    },
+    "normalize-package-data": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+      "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
+      "dev": true,
+      "requires": {
+        "hosted-git-info": "2.5.0",
+        "is-builtin-module": "1.0.0",
+        "semver": "5.4.1",
+        "validate-npm-package-license": "3.0.1"
+      }
+    },
+    "normalize-path": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+      "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+      "dev": true,
+      "requires": {
+        "remove-trailing-separator": "1.1.0"
+      }
+    },
+    "npm-run-all": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.2.tgz",
+      "integrity": "sha512-Z2aRlajMK4SQ8u19ZA75NZZu7wupfCNQWdYosIi8S6FgBdGf/8Y6Hgyjdc8zU2cYmIRVCx1nM80tJPkdEd+UYg==",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "3.2.0",
+        "chalk": "2.3.0",
+        "cross-spawn": "5.1.0",
+        "memorystream": "0.3.1",
+        "minimatch": "3.0.4",
+        "ps-tree": "1.1.0",
+        "read-pkg": "3.0.0",
+        "shell-quote": "1.6.1",
+        "string.prototype.padend": "3.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.1"
+          }
+        },
+        "chalk": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.5.0"
+          }
+        },
+        "load-json-file": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+          "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "4.1.11",
+            "parse-json": "4.0.0",
+            "pify": "3.0.0",
+            "strip-bom": "3.0.0"
+          }
+        },
+        "parse-json": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+          "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+          "dev": true,
+          "requires": {
+            "error-ex": "1.3.1",
+            "json-parse-better-errors": "1.0.1"
+          }
+        },
+        "path-type": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+          "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+          "dev": true,
+          "requires": {
+            "pify": "3.0.0"
+          }
+        },
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        },
+        "read-pkg": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+          "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+          "dev": true,
+          "requires": {
+            "load-json-file": "4.0.0",
+            "normalize-package-data": "2.4.0",
+            "path-type": "3.0.0"
+          }
+        },
+        "strip-bom": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+          "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "npm-run-path": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+      "dev": true,
+      "requires": {
+        "path-key": "2.0.1"
+      }
+    },
+    "npmlog": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+      "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+      "dev": true,
+      "requires": {
+        "are-we-there-yet": "1.1.4",
+        "console-control-strings": "1.1.0",
+        "gauge": "2.7.4",
+        "set-blocking": "2.0.0"
+      }
+    },
+    "nth-check": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
+      "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=",
+      "dev": true,
+      "requires": {
+        "boolbase": "1.0.0"
+      }
+    },
+    "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
+    },
+    "oauth-sign": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+      "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+      "dev": true
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+    },
+    "object-component": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
+      "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=",
+      "dev": true
+    },
+    "object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "requires": {
+        "copy-descriptor": "0.1.1",
+        "define-property": "0.2.5",
+        "kind-of": "3.2.2"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        }
+      }
+    },
+    "object-inspect": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.5.0.tgz",
+      "integrity": "sha512-UmOFbHbwvv+XHj7BerrhVq+knjceBdkvU5AriwLMvhv2qi+e7DJzxfBeFpILEjVzCp+xA+W/pIf06RGPWlZNfw==",
+      "dev": true
+    },
+    "object-is": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz",
+      "integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=",
+      "dev": true
+    },
+    "object-keys": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
+      "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=",
+      "dev": true
+    },
+    "object-visit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "dev": true,
+      "requires": {
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "object.assign": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+      "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+      "dev": true,
+      "requires": {
+        "define-properties": "1.1.2",
+        "function-bind": "1.1.1",
+        "has-symbols": "1.0.0",
+        "object-keys": "1.0.11"
+      }
+    },
+    "object.entries": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.0.4.tgz",
+      "integrity": "sha1-G/mk3SKI9bM/Opk9JXZh8F0WGl8=",
+      "dev": true,
+      "requires": {
+        "define-properties": "1.1.2",
+        "es-abstract": "1.9.0",
+        "function-bind": "1.1.1",
+        "has": "1.0.1"
+      }
+    },
+    "object.omit": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
+      "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
+      "dev": true,
+      "requires": {
+        "for-own": "0.1.5",
+        "is-extendable": "0.1.1"
+      }
+    },
+    "object.pick": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+      "dev": true,
+      "requires": {
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "object.values": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.0.4.tgz",
+      "integrity": "sha1-5STaCbT2b/Bd9FdUbscqyZ8TBpo=",
+      "dev": true,
+      "requires": {
+        "define-properties": "1.1.2",
+        "es-abstract": "1.9.0",
+        "function-bind": "1.1.1",
+        "has": "1.0.1"
+      }
+    },
+    "on-finished": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+      "dev": true,
+      "requires": {
+        "ee-first": "1.1.1"
+      }
+    },
+    "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"
+      }
+    },
+    "onetime": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+      "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+      "dev": true,
+      "requires": {
+        "mimic-fn": "1.2.0"
+      }
+    },
+    "optimist": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+      "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+      "dev": true,
+      "requires": {
+        "minimist": "0.0.10",
+        "wordwrap": "0.0.3"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "0.0.10",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+          "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
+          "dev": true
+        }
+      }
+    },
+    "optionator": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+      "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+      "dev": true,
+      "requires": {
+        "deep-is": "0.1.3",
+        "fast-levenshtein": "2.0.6",
+        "levn": "0.3.0",
+        "prelude-ls": "1.1.2",
+        "type-check": "0.3.2",
+        "wordwrap": "1.0.0"
+      },
+      "dependencies": {
+        "wordwrap": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+          "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+          "dev": true
+        }
+      }
+    },
+    "os-browserify": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+      "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
+      "dev": true
+    },
+    "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-locale": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+      "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+      "dev": true,
+      "requires": {
+        "lcid": "1.0.0"
+      }
+    },
+    "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
+    },
+    "osenv": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz",
+      "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=",
+      "dev": true,
+      "requires": {
+        "os-homedir": "1.0.2",
+        "os-tmpdir": "1.0.2"
+      }
+    },
+    "p-finally": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+      "dev": true
+    },
+    "p-limit": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz",
+      "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=",
+      "dev": true
+    },
+    "p-locate": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+      "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+      "dev": true,
+      "requires": {
+        "p-limit": "1.1.0"
+      }
+    },
+    "pac-proxy-agent": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-1.1.0.tgz",
+      "integrity": "sha512-QBELCWyLYPgE2Gj+4wUEiMscHrQ8nRPBzYItQNOHWavwBt25ohZHQC4qnd5IszdVVrFbLsQ+dPkm6eqdjJAmwQ==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "agent-base": "2.1.1",
+        "debug": "2.6.9",
+        "extend": "3.0.1",
+        "get-uri": "2.0.1",
+        "http-proxy-agent": "1.0.0",
+        "https-proxy-agent": "1.0.0",
+        "pac-resolver": "2.0.0",
+        "raw-body": "2.3.2",
+        "socks-proxy-agent": "2.1.1"
+      },
+      "dependencies": {
+        "agent-base": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz",
+          "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=",
+          "dev": true,
+          "requires": {
+            "extend": "3.0.1",
+            "semver": "5.0.3"
+          }
+        },
+        "http-proxy-agent": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-1.0.0.tgz",
+          "integrity": "sha1-zBzjjkU7+YSg93AtLdWcc9CBKEo=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "agent-base": "2.1.1",
+            "debug": "2.6.9",
+            "extend": "3.0.1"
+          }
+        },
+        "https-proxy-agent": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
+          "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "agent-base": "2.1.1",
+            "debug": "2.6.9",
+            "extend": "3.0.1"
+          }
+        },
+        "semver": {
+          "version": "5.0.3",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz",
+          "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=",
+          "dev": true
+        }
+      }
+    },
+    "pac-resolver": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-2.0.0.tgz",
+      "integrity": "sha1-mbiNLxk/ve78HJpSnB8yYKtSd80=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "co": "3.0.6",
+        "degenerator": "1.0.4",
+        "ip": "1.0.1",
+        "netmask": "1.0.6",
+        "thunkify": "2.1.2"
+      },
+      "dependencies": {
+        "co": {
+          "version": "3.0.6",
+          "resolved": "https://registry.npmjs.org/co/-/co-3.0.6.tgz",
+          "integrity": "sha1-FEXyJsXrlWE45oyawwFn6n0ua9o=",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "pako": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
+      "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==",
+      "dev": true
+    },
+    "parse-asn1": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz",
+      "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=",
+      "dev": true,
+      "requires": {
+        "asn1.js": "4.9.2",
+        "browserify-aes": "1.1.1",
+        "create-hash": "1.1.3",
+        "evp_bytestokey": "1.0.3",
+        "pbkdf2": "3.0.14"
+      }
+    },
+    "parse-glob": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
+      "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
+      "dev": true,
+      "requires": {
+        "glob-base": "0.3.0",
+        "is-dotfile": "1.0.3",
+        "is-extglob": "1.0.0",
+        "is-glob": "2.0.1"
+      }
+    },
+    "parse-json": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+      "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+      "dev": true,
+      "requires": {
+        "error-ex": "1.3.1"
+      }
+    },
+    "parse5": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
+      "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
+      "dev": true,
+      "requires": {
+        "@types/node": "9.4.1"
+      }
+    },
+    "parseqs": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
+      "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
+      "dev": true,
+      "requires": {
+        "better-assert": "1.0.2"
+      }
+    },
+    "parseuri": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
+      "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
+      "dev": true,
+      "requires": {
+        "better-assert": "1.0.2"
+      }
+    },
+    "parseurl": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+      "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
+      "dev": true
+    },
+    "pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "dev": true
+    },
+    "path-browserify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
+      "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=",
+      "dev": true
+    },
+    "path-dirname": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+      "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+      "dev": true
+    },
+    "path-exists": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+      "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
+    },
+    "path-is-inside": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+      "dev": true
+    },
+    "path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true
+    },
+    "path-parse": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
+      "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
+      "dev": true
+    },
+    "path-proxy": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/path-proxy/-/path-proxy-1.0.0.tgz",
+      "integrity": "sha1-GOijaFn8nS8aU7SN7hOFQ8Ag3l4=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "inflection": "1.3.8"
+      },
+      "dependencies": {
+        "inflection": {
+          "version": "1.3.8",
+          "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.3.8.tgz",
+          "integrity": "sha1-y9Fg2p91sUw8xjV41POWeEvzAU4=",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "path-to-regexp": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
+      "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
+      "dev": true,
+      "requires": {
+        "isarray": "0.0.1"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+          "dev": true
+        }
+      }
+    },
+    "path-type": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+      "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "pathval": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
+      "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
+      "dev": true
+    },
+    "pause-stream": {
+      "version": "0.0.11",
+      "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+      "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
+      "dev": true,
+      "requires": {
+        "through": "2.3.8"
+      }
+    },
+    "pbkdf2": {
+      "version": "3.0.14",
+      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz",
+      "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==",
+      "dev": true,
+      "requires": {
+        "create-hash": "1.1.3",
+        "create-hmac": "1.1.6",
+        "ripemd160": "2.0.1",
+        "safe-buffer": "5.1.1",
+        "sha.js": "2.4.10"
+      }
+    },
+    "performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+      "dev": true
+    },
+    "pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "dev": true
+    },
+    "pinkie": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+      "dev": true
+    },
+    "pinkie-promise": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+      "dev": true,
+      "requires": {
+        "pinkie": "2.0.4"
+      }
+    },
+    "pkg-dir": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
+      "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
+      "dev": true,
+      "requires": {
+        "find-up": "2.1.0"
+      }
+    },
+    "pluralize": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
+      "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
+      "dev": true
+    },
+    "pontoon-to-json": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/pontoon-to-json/-/pontoon-to-json-2.0.0.tgz",
+      "integrity": "sha1-jsNeNblxEWzTT3Okc9ZJcYfNgbY=",
+      "dev": true,
+      "requires": {
+        "habitat": "3.1.2",
+        "minimist": "1.2.0",
+        "properties-parser": "0.3.1",
+        "q-io": "1.13.4"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "posix-character-classes": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+      "dev": true
+    },
+    "prelude-ls": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+      "dev": true
+    },
+    "preserve": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
+      "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
+      "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
+    },
+    "process": {
+      "version": "0.11.10",
+      "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+      "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+      "dev": true
+    },
+    "process-nextick-args": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+      "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+      "dev": true
+    },
+    "progress": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
+      "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
+      "dev": true
+    },
+    "promise": {
+      "version": "7.3.1",
+      "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+      "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+      "requires": {
+        "asap": "2.0.6"
+      }
+    },
+    "prop-types": {
+      "version": "15.6.1",
+      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz",
+      "integrity": "sha512-4ec7bY1Y66LymSUOH/zARVYObB23AT2h8cf6e/O6ZALB/N0sqZFEx7rq6EYPX2MkOdKORuooI/H5k9TlR4q7kQ==",
+      "requires": {
+        "fbjs": "0.8.16",
+        "loose-envify": "1.3.1",
+        "object-assign": "4.1.1"
+      }
+    },
+    "properties-parser": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/properties-parser/-/properties-parser-0.3.1.tgz",
+      "integrity": "sha1-ExbpU5/7/ZOEXjabIRAiq9R4dxo=",
+      "dev": true,
+      "requires": {
+        "string.prototype.codepointat": "0.2.0"
+      }
+    },
+    "proxy-agent": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-2.0.0.tgz",
+      "integrity": "sha1-V+tTR6qAXXTsaByyVknbo5yTNJk=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "agent-base": "2.1.1",
+        "debug": "2.6.9",
+        "extend": "3.0.1",
+        "http-proxy-agent": "1.0.0",
+        "https-proxy-agent": "1.0.0",
+        "lru-cache": "2.6.5",
+        "pac-proxy-agent": "1.1.0",
+        "socks-proxy-agent": "2.1.1"
+      },
+      "dependencies": {
+        "agent-base": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz",
+          "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=",
+          "dev": true,
+          "requires": {
+            "extend": "3.0.1",
+            "semver": "5.0.3"
+          }
+        },
+        "http-proxy-agent": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-1.0.0.tgz",
+          "integrity": "sha1-zBzjjkU7+YSg93AtLdWcc9CBKEo=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "agent-base": "2.1.1",
+            "debug": "2.6.9",
+            "extend": "3.0.1"
+          }
+        },
+        "https-proxy-agent": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
+          "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "agent-base": "2.1.1",
+            "debug": "2.6.9",
+            "extend": "3.0.1"
+          }
+        },
+        "lru-cache": {
+          "version": "2.6.5",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz",
+          "integrity": "sha1-5W1jVBSO3o13B7WNFDIg/QjfD9U=",
+          "dev": true,
+          "optional": true
+        },
+        "semver": {
+          "version": "5.0.3",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz",
+          "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=",
+          "dev": true
+        }
+      }
+    },
+    "prr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+      "dev": true
+    },
+    "ps-tree": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz",
+      "integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=",
+      "dev": true,
+      "requires": {
+        "event-stream": "3.3.4"
+      }
+    },
+    "pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+      "dev": true
+    },
+    "public-encrypt": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz",
+      "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=",
+      "dev": true,
+      "requires": {
+        "bn.js": "4.11.8",
+        "browserify-rsa": "4.0.1",
+        "create-hash": "1.1.3",
+        "parse-asn1": "5.1.0",
+        "randombytes": "2.0.6"
+      }
+    },
+    "punycode": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+      "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+      "dev": true
+    },
+    "q": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz",
+      "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=",
+      "dev": true
+    },
+    "q-io": {
+      "version": "1.13.4",
+      "resolved": "https://registry.npmjs.org/q-io/-/q-io-1.13.4.tgz",
+      "integrity": "sha1-qWoKBOomraP3+kMut0LUhscs/y0=",
+      "dev": true,
+      "requires": {
+        "collections": "0.2.2",
+        "mime": "1.4.1",
+        "mimeparse": "0.1.4",
+        "q": "1.5.0",
+        "qs": "6.5.1",
+        "url2": "0.0.0"
+      }
+    },
+    "qjobs": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz",
+      "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==",
+      "dev": true
+    },
+    "qs": {
+      "version": "6.5.1",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+      "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
+      "dev": true
+    },
+    "querystring": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+      "dev": true
+    },
+    "querystring-es3": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+      "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
+      "dev": true
+    },
+    "raf": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.0.tgz",
+      "integrity": "sha512-pDP/NMRAXoTfrhCfyfSEwJAKLaxBU9eApMeBPB1TkDouZmvPerIClV8lTAd+uF8ZiTaVl69e1FCxQrAd/VTjGw==",
+      "dev": true,
+      "requires": {
+        "performance-now": "2.1.0"
+      }
+    },
+    "railroad-diagrams": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
+      "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=",
+      "dev": true
+    },
+    "randexp": {
+      "version": "0.4.6",
+      "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz",
+      "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==",
+      "dev": true,
+      "requires": {
+        "discontinuous-range": "1.0.0",
+        "ret": "0.1.15"
+      }
+    },
+    "randomatic": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
+      "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==",
+      "dev": true,
+      "requires": {
+        "is-number": "3.0.0",
+        "kind-of": "4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.5"
+              }
+            }
+          }
+        },
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "1.1.5"
+          }
+        }
+      }
+    },
+    "randombytes": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz",
+      "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "randomfill": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz",
+      "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==",
+      "dev": true,
+      "requires": {
+        "randombytes": "2.0.6",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "range-parser": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+      "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
+      "dev": true
+    },
+    "raw-body": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
+      "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
+      "dev": true,
+      "requires": {
+        "bytes": "3.0.0",
+        "http-errors": "1.6.2",
+        "iconv-lite": "0.4.19",
+        "unpipe": "1.0.0"
+      },
+      "dependencies": {
+        "depd": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+          "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=",
+          "dev": true
+        },
+        "http-errors": {
+          "version": "1.6.2",
+          "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+          "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
+          "dev": true,
+          "requires": {
+            "depd": "1.1.1",
+            "inherits": "2.0.3",
+            "setprototypeof": "1.0.3",
+            "statuses": "1.5.0"
+          }
+        },
+        "setprototypeof": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+          "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=",
+          "dev": true
+        }
+      }
+    },
+    "react": {
+      "version": "16.2.0",
+      "resolved": "https://registry.npmjs.org/react/-/react-16.2.0.tgz",
+      "integrity": "sha512-ZmIomM7EE1DvPEnSFAHZn9Vs9zJl5A9H7el0EGTE6ZbW9FKe/14IYAlPbC8iH25YarEQxZL+E8VW7Mi7kfQrDQ==",
+      "requires": {
+        "fbjs": "0.8.16",
+        "loose-envify": "1.3.1",
+        "object-assign": "4.1.1",
+        "prop-types": "15.6.1"
+      }
+    },
+    "react-dom": {
+      "version": "16.2.0",
+      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.2.0.tgz",
+      "integrity": "sha512-zpGAdwHVn9K0091d+hr+R0qrjoJ84cIBFL2uU60KvWBPfZ7LPSrfqviTxGHWN0sjPZb2hxWzMexwrvJdKePvjg==",
+      "requires": {
+        "fbjs": "0.8.16",
+        "loose-envify": "1.3.1",
+        "object-assign": "4.1.1",
+        "prop-types": "15.6.1"
+      }
+    },
+    "react-intl": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-2.4.0.tgz",
+      "integrity": "sha1-ZsFNyd+ac7L7v71gIXJugKYT6xU=",
+      "requires": {
+        "intl-format-cache": "2.1.0",
+        "intl-messageformat": "2.2.0",
+        "intl-relativeformat": "2.1.0",
+        "invariant": "2.2.2"
+      }
+    },
+    "react-is": {
+      "version": "16.3.2",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.3.2.tgz",
+      "integrity": "sha512-ybEM7YOr4yBgFd6w8dJqwxegqZGJNBZl6U27HnGKuTZmDvVrD5quWOK/wAnMywiZzW+Qsk+l4X2c70+thp/A8Q==",
+      "dev": true
+    },
+    "react-reconciler": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.7.0.tgz",
+      "integrity": "sha512-50JwZ3yNyMS8fchN+jjWEJOH3Oze7UmhxeoJLn2j6f3NjpfCRbcmih83XTWmzqtar/ivd5f7tvQhvvhism2fgg==",
+      "dev": true,
+      "requires": {
+        "fbjs": "0.8.16",
+        "loose-envify": "1.3.1",
+        "object-assign": "4.1.1",
+        "prop-types": "15.6.1"
+      }
+    },
+    "react-redux": {
+      "version": "5.0.6",
+      "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.6.tgz",
+      "integrity": "sha512-8taaaGu+J7PMJQDJrk/xiWEYQmdo3mkXw6wPr3K3LxvXis3Fymiq7c13S+Tpls/AyNUAsoONkU81AP0RA6y6Vw==",
+      "requires": {
+        "hoist-non-react-statics": "2.3.1",
+        "invariant": "2.2.2",
+        "lodash": "4.17.4",
+        "lodash-es": "4.17.4",
+        "loose-envify": "1.3.1",
+        "prop-types": "15.6.1"
+      },
+      "dependencies": {
+        "hoist-non-react-statics": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz",
+          "integrity": "sha1-ND24TGAYxlB3iJgkATWhQg7iLOA="
+        }
+      }
+    },
+    "react-test-renderer": {
+      "version": "16.3.2",
+      "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.3.2.tgz",
+      "integrity": "sha512-lL8WHIpCTMdSe+CRkt0rfMxBkJFyhVrpdQ54BaJRIrXf9aVmbeHbRA8GFRpTvohPN5tPzMabmrzW2PUfWCfWwQ==",
+      "dev": true,
+      "requires": {
+        "fbjs": "0.8.16",
+        "object-assign": "4.1.1",
+        "prop-types": "15.6.1",
+        "react-is": "16.3.2"
+      }
+    },
+    "read-pkg": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+      "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+      "dev": true,
+      "requires": {
+        "load-json-file": "1.1.0",
+        "normalize-package-data": "2.4.0",
+        "path-type": "1.1.0"
+      }
+    },
+    "read-pkg-up": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+      "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+      "dev": true,
+      "requires": {
+        "find-up": "1.1.2",
+        "read-pkg": "1.1.0"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+          "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+          "dev": true,
+          "requires": {
+            "path-exists": "2.1.0",
+            "pinkie-promise": "2.0.1"
+          }
+        },
+        "path-exists": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+          "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+          "dev": true,
+          "requires": {
+            "pinkie-promise": "2.0.1"
+          }
+        }
+      }
+    },
+    "readable-stream": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+      "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+      "dev": true,
+      "requires": {
+        "core-util-is": "1.0.2",
+        "inherits": "2.0.3",
+        "isarray": "1.0.0",
+        "process-nextick-args": "1.0.7",
+        "safe-buffer": "5.1.1",
+        "string_decoder": "1.0.3",
+        "util-deprecate": "1.0.2"
+      }
+    },
+    "readdirp": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
+      "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "minimatch": "3.0.4",
+        "readable-stream": "2.3.3",
+        "set-immediate-shim": "1.0.1"
+      }
+    },
+    "readline2": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz",
+      "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=",
+      "dev": true,
+      "requires": {
+        "code-point-at": "1.1.0",
+        "is-fullwidth-code-point": "1.0.0",
+        "mute-stream": "0.0.5"
+      },
+      "dependencies": {
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "mute-stream": {
+          "version": "0.0.5",
+          "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
+          "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=",
+          "dev": true
+        }
+      }
+    },
+    "rechoir": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+      "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+      "dev": true,
+      "requires": {
+        "resolve": "1.4.0"
+      }
+    },
+    "redent": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+      "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+      "dev": true,
+      "requires": {
+        "indent-string": "2.1.0",
+        "strip-indent": "1.0.1"
+      }
+    },
+    "redis": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz",
+      "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "double-ended-queue": "2.1.0-0",
+        "redis-commands": "1.3.5",
+        "redis-parser": "2.6.0"
+      }
+    },
+    "redis-commands": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.5.tgz",
+      "integrity": "sha512-foGF8u6MXGFF++1TZVC6icGXuMYPftKXt1FBT2vrfU9ZATNtZJ8duRC5d1lEfE8hyVe3jhelHGB91oB7I6qLsA==",
+      "dev": true,
+      "optional": true
+    },
+    "redis-parser": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz",
+      "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=",
+      "dev": true,
+      "optional": true
+    },
+    "redux": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/redux/-/redux-3.6.0.tgz",
+      "integrity": "sha1-iHwrPQub2G7KK+cFccJ2VMGeGI0=",
+      "requires": {
+        "lodash": "4.17.4",
+        "lodash-es": "4.17.4",
+        "loose-envify": "1.3.1",
+        "symbol-observable": "1.0.4"
+      }
+    },
+    "regenerator-runtime": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz",
+      "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==",
+      "dev": true
+    },
+    "regex-cache": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
+      "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
+      "dev": true,
+      "requires": {
+        "is-equal-shallow": "0.1.3"
+      }
+    },
+    "regex-not": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "3.0.2",
+        "safe-regex": "1.1.0"
+      }
+    },
+    "regexpp": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz",
+      "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==",
+      "dev": true
+    },
+    "remove-trailing-separator": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+      "dev": true
+    },
+    "repeat-element": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
+      "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
+      "dev": true
+    },
+    "repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+      "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"
+      }
+    },
+    "request": {
+      "version": "2.79.0",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz",
+      "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=",
+      "dev": true,
+      "requires": {
+        "aws-sign2": "0.6.0",
+        "aws4": "1.6.0",
+        "caseless": "0.11.0",
+        "combined-stream": "1.0.5",
+        "extend": "3.0.1",
+        "forever-agent": "0.6.1",
+        "form-data": "2.1.4",
+        "har-validator": "2.0.6",
+        "hawk": "3.1.3",
+        "http-signature": "1.1.1",
+        "is-typedarray": "1.0.0",
+        "isstream": "0.1.2",
+        "json-stringify-safe": "5.0.1",
+        "mime-types": "2.1.17",
+        "oauth-sign": "0.8.2",
+        "qs": "6.3.2",
+        "stringstream": "0.0.5",
+        "tough-cookie": "2.3.3",
+        "tunnel-agent": "0.4.3",
+        "uuid": "3.1.0"
+      },
+      "dependencies": {
+        "qs": {
+          "version": "6.3.2",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
+          "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=",
+          "dev": true
+        },
+        "uuid": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
+          "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==",
+          "dev": true
+        }
+      }
+    },
+    "requestretry": {
+      "version": "1.13.0",
+      "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.13.0.tgz",
+      "integrity": "sha512-Lmh9qMvnQXADGAQxsXHP4rbgO6pffCfuR8XUBdP9aitJcLQJxhp7YZK4xAVYXnPJ5E52mwrfiKQtKonPL8xsmg==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "extend": "3.0.1",
+        "lodash": "4.17.4",
+        "request": "2.79.0",
+        "when": "3.7.8"
+      }
+    },
+    "require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "dev": true
+    },
+    "require-main-filename": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+      "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
+      "dev": true
+    },
+    "require-uncached": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+      "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
+      "dev": true,
+      "requires": {
+        "caller-path": "0.1.0",
+        "resolve-from": "1.0.1"
+      }
+    },
+    "requires-port": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+      "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
+      "dev": true
+    },
+    "resolve": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz",
+      "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==",
+      "dev": true,
+      "requires": {
+        "path-parse": "1.0.5"
+      }
+    },
+    "resolve-from": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
+      "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
+      "dev": true
+    },
+    "resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "restore-cursor": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+      "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+      "dev": true,
+      "requires": {
+        "onetime": "2.0.1",
+        "signal-exit": "3.0.2"
+      }
+    },
+    "ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true
+    },
+    "right-align": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
+      "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
+      "dev": true,
+      "requires": {
+        "align-text": "0.1.4"
+      }
+    },
+    "rimraf": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+      "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+      "dev": true,
+      "requires": {
+        "glob": "7.1.2"
+      }
+    },
+    "ripemd160": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
+      "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=",
+      "dev": true,
+      "requires": {
+        "hash-base": "2.0.2",
+        "inherits": "2.0.3"
+      }
+    },
+    "rst-selector-parser": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz",
+      "integrity": "sha1-gbIw6i/MYGbInjRy3nlChdmwPZE=",
+      "dev": true,
+      "requires": {
+        "lodash.flattendeep": "4.4.0",
+        "nearley": "2.11.0"
+      }
+    },
+    "run-async": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
+      "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+      "dev": true,
+      "requires": {
+        "is-promise": "2.1.0"
+      }
+    },
+    "rx-lite": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
+      "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
+      "dev": true
+    },
+    "rx-lite-aggregates": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
+      "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
+      "dev": true,
+      "requires": {
+        "rx-lite": "4.0.8"
+      }
+    },
+    "safe-buffer": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+      "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
+      "dev": true
+    },
+    "safe-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "dev": true,
+      "requires": {
+        "ret": "0.1.15"
+      }
+    },
+    "samsam": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz",
+      "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==",
+      "dev": true
+    },
+    "sass-graph": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
+      "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
+      "dev": true,
+      "requires": {
+        "glob": "7.1.2",
+        "lodash": "4.17.4",
+        "scss-tokenizer": "0.2.3",
+        "yargs": "7.1.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+          "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+          "dev": true
+        },
+        "cliui": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+          "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+          "dev": true,
+          "requires": {
+            "string-width": "1.0.2",
+            "strip-ansi": "3.0.1",
+            "wrap-ansi": "2.1.0"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "1.1.0",
+            "is-fullwidth-code-point": "1.0.0",
+            "strip-ansi": "3.0.1"
+          }
+        },
+        "yargs": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
+          "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
+          "dev": true,
+          "requires": {
+            "camelcase": "3.0.0",
+            "cliui": "3.2.0",
+            "decamelize": "1.2.0",
+            "get-caller-file": "1.0.2",
+            "os-locale": "1.4.0",
+            "read-pkg-up": "1.0.1",
+            "require-directory": "2.1.1",
+            "require-main-filename": "1.0.1",
+            "set-blocking": "2.0.0",
+            "string-width": "1.0.2",
+            "which-module": "1.0.0",
+            "y18n": "3.2.1",
+            "yargs-parser": "5.0.0"
+          }
+        }
+      }
+    },
+    "sass-lint": {
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/sass-lint/-/sass-lint-1.12.1.tgz",
+      "integrity": "sha1-Yw9pwhaqIGuCMvsqqQe98zNrbYM=",
+      "dev": true,
+      "requires": {
+        "commander": "2.12.2",
+        "eslint": "2.13.1",
+        "front-matter": "2.1.2",
+        "fs-extra": "3.0.1",
+        "glob": "7.1.2",
+        "globule": "1.2.0",
+        "gonzales-pe-sl": "4.2.3",
+        "js-yaml": "3.10.0",
+        "known-css-properties": "0.3.0",
+        "lodash.capitalize": "4.2.1",
+        "lodash.kebabcase": "4.1.1",
+        "merge": "1.2.0",
+        "path-is-absolute": "1.0.1",
+        "util": "0.10.3"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "4.11.8",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+          "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
+          "dev": true,
+          "requires": {
+            "co": "4.6.0",
+            "json-stable-stringify": "1.0.1"
+          }
+        },
+        "ajv-keywords": {
+          "version": "1.5.1",
+          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz",
+          "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=",
+          "dev": true
+        },
+        "ansi-escapes": {
+          "version": "1.4.0",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
+          "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
+          "dev": true
+        },
+        "cli-cursor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
+          "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
+          "dev": true,
+          "requires": {
+            "restore-cursor": "1.0.1"
+          }
+        },
+        "co": {
+          "version": "4.6.0",
+          "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+          "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+          "dev": true
+        },
+        "doctrine": {
+          "version": "1.5.0",
+          "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+          "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+          "dev": true,
+          "requires": {
+            "esutils": "2.0.2",
+            "isarray": "1.0.0"
+          }
+        },
+        "eslint": {
+          "version": "2.13.1",
+          "resolved": "https://registry.npmjs.org/eslint/-/eslint-2.13.1.tgz",
+          "integrity": "sha1-5MyPoPAJ+4KaquI4VaKTYL4fbBE=",
+          "dev": true,
+          "requires": {
+            "chalk": "1.1.3",
+            "concat-stream": "1.6.0",
+            "debug": "2.6.9",
+            "doctrine": "1.5.0",
+            "es6-map": "0.1.5",
+            "escope": "3.6.0",
+            "espree": "3.5.1",
+            "estraverse": "4.2.0",
+            "esutils": "2.0.2",
+            "file-entry-cache": "1.3.1",
+            "glob": "7.1.2",
+            "globals": "9.18.0",
+            "ignore": "3.3.5",
+            "imurmurhash": "0.1.4",
+            "inquirer": "0.12.0",
+            "is-my-json-valid": "2.16.1",
+            "is-resolvable": "1.0.0",
+            "js-yaml": "3.10.0",
+            "json-stable-stringify": "1.0.1",
+            "levn": "0.3.0",
+            "lodash": "4.17.4",
+            "mkdirp": "0.5.1",
+            "optionator": "0.8.2",
+            "path-is-absolute": "1.0.1",
+            "path-is-inside": "1.0.2",
+            "pluralize": "1.2.1",
+            "progress": "1.1.8",
+            "require-uncached": "1.0.3",
+            "shelljs": "0.6.1",
+            "strip-json-comments": "1.0.4",
+            "table": "3.8.3",
+            "text-table": "0.2.0",
+            "user-home": "2.0.0"
+          }
+        },
+        "figures": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+          "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
+          "dev": true,
+          "requires": {
+            "escape-string-regexp": "1.0.5",
+            "object-assign": "4.1.1"
+          }
+        },
+        "file-entry-cache": {
+          "version": "1.3.1",
+          "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-1.3.1.tgz",
+          "integrity": "sha1-RMYepgeuS+nBQC9B9EJwy/4zT/g=",
+          "dev": true,
+          "requires": {
+            "flat-cache": "1.3.0",
+            "object-assign": "4.1.1"
+          }
+        },
+        "inquirer": {
+          "version": "0.12.0",
+          "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
+          "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=",
+          "dev": true,
+          "requires": {
+            "ansi-escapes": "1.4.0",
+            "ansi-regex": "2.1.1",
+            "chalk": "1.1.3",
+            "cli-cursor": "1.0.2",
+            "cli-width": "2.2.0",
+            "figures": "1.7.0",
+            "lodash": "4.17.4",
+            "readline2": "1.0.1",
+            "run-async": "0.1.0",
+            "rx-lite": "3.1.2",
+            "string-width": "1.0.2",
+            "strip-ansi": "3.0.1",
+            "through": "2.3.8"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "onetime": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+          "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
+          "dev": true
+        },
+        "pluralize": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz",
+          "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=",
+          "dev": true
+        },
+        "progress": {
+          "version": "1.1.8",
+          "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+          "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
+          "dev": true
+        },
+        "restore-cursor": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
+          "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
+          "dev": true,
+          "requires": {
+            "exit-hook": "1.1.1",
+            "onetime": "1.1.0"
+          }
+        },
+        "run-async": {
+          "version": "0.1.0",
+          "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
+          "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=",
+          "dev": true,
+          "requires": {
+            "once": "1.4.0"
+          }
+        },
+        "rx-lite": {
+          "version": "3.1.2",
+          "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
+          "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=",
+          "dev": true
+        },
+        "shelljs": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.6.1.tgz",
+          "integrity": "sha1-7GIRvtGSBEIIj+D3Cyg3Iy7SyKg=",
+          "dev": true
+        },
+        "slice-ansi": {
+          "version": "0.0.4",
+          "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
+          "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "1.1.0",
+            "is-fullwidth-code-point": "1.0.0",
+            "strip-ansi": "3.0.1"
+          }
+        },
+        "strip-json-comments": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
+          "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=",
+          "dev": true
+        },
+        "table": {
+          "version": "3.8.3",
+          "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz",
+          "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=",
+          "dev": true,
+          "requires": {
+            "ajv": "4.11.8",
+            "ajv-keywords": "1.5.1",
+            "chalk": "1.1.3",
+            "lodash": "4.17.4",
+            "slice-ansi": "0.0.4",
+            "string-width": "2.1.1"
+          },
+          "dependencies": {
+            "ansi-regex": {
+              "version": "3.0.0",
+              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+              "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+              "dev": true
+            },
+            "is-fullwidth-code-point": {
+              "version": "2.0.0",
+              "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+              "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+              "dev": true
+            },
+            "string-width": {
+              "version": "2.1.1",
+              "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+              "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+              "dev": true,
+              "requires": {
+                "is-fullwidth-code-point": "2.0.0",
+                "strip-ansi": "4.0.0"
+              }
+            },
+            "strip-ansi": {
+              "version": "4.0.0",
+              "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+              "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+              "dev": true,
+              "requires": {
+                "ansi-regex": "3.0.0"
+              }
+            }
+          }
+        }
+      }
+    },
+    "sax": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+      "dev": true
+    },
+    "scss-tokenizer": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
+      "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
+      "dev": true,
+      "requires": {
+        "js-base64": "2.3.2",
+        "source-map": "0.4.4"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.4.4",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+          "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+          "dev": true,
+          "requires": {
+            "amdefine": "1.0.1"
+          }
+        }
+      }
+    },
+    "semver": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
+      "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
+      "dev": true
+    },
+    "set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+      "dev": true
+    },
+    "set-immediate-shim": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+      "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
+      "dev": true
+    },
+    "set-value": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+      "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "2.0.1",
+        "is-extendable": "0.1.1",
+        "is-plain-object": "2.0.4",
+        "split-string": "3.1.0"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "0.1.1"
+          }
+        }
+      }
+    },
+    "setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
+    },
+    "setprototypeof": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+      "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+      "dev": true
+    },
+    "sha.js": {
+      "version": "2.4.10",
+      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.10.tgz",
+      "integrity": "sha512-vnwmrFDlOExK4Nm16J2KMWHLrp14lBrjxMxBJpu++EnsuBmpiYaM/MEs46Vxxm/4FvdP5yTwuCTO9it5FSjrqA==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "dev": true,
+      "requires": {
+        "shebang-regex": "1.0.0"
+      }
+    },
+    "shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "dev": true
+    },
+    "shell-quote": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz",
+      "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=",
+      "dev": true,
+      "requires": {
+        "array-filter": "0.0.1",
+        "array-map": "0.0.0",
+        "array-reduce": "0.0.0",
+        "jsonify": "0.0.0"
+      }
+    },
+    "shelljs": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.1.tgz",
+      "integrity": "sha512-YA/iYtZpzFe5HyWVGrb02FjPxc4EMCfpoU/Phg9fQoyMC72u9598OUBrsU8IrtwAKG0tO8IYaqbaLIw+k3IRGA==",
+      "dev": true,
+      "requires": {
+        "glob": "7.1.2",
+        "interpret": "1.1.0",
+        "rechoir": "0.6.2"
+      }
+    },
+    "signal-exit": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+      "dev": true
+    },
+    "simple-git": {
+      "version": "1.92.0",
+      "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.92.0.tgz",
+      "integrity": "sha1-YGFGjrfRnwFBB4/HQuYkV+kQ9Uc=",
+      "dev": true,
+      "requires": {
+        "debug": "3.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "sinon": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz",
+      "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==",
+      "dev": true,
+      "requires": {
+        "@sinonjs/formatio": "2.0.0",
+        "diff": "3.5.0",
+        "lodash.get": "4.4.2",
+        "lolex": "2.3.2",
+        "nise": "1.3.3",
+        "supports-color": "5.4.0",
+        "type-detect": "4.0.5"
+      },
+      "dependencies": {
+        "has-flag": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "slack-node": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/slack-node/-/slack-node-0.2.0.tgz",
+      "integrity": "sha1-3kuN3aqLeT9h29KTgQT9q/N9+jA=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "requestretry": "1.13.0"
+      }
+    },
+    "slash": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+      "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+      "dev": true
+    },
+    "slice-ansi": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
+      "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
+      "dev": true,
+      "requires": {
+        "is-fullwidth-code-point": "2.0.0"
+      }
+    },
+    "smart-buffer": {
+      "version": "1.1.15",
+      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz",
+      "integrity": "sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY=",
+      "dev": true
+    },
+    "smtp-connection": {
+      "version": "2.12.0",
+      "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.12.0.tgz",
+      "integrity": "sha1-1275EnyyPCJZ7bHoNJwujV4tdME=",
+      "dev": true,
+      "requires": {
+        "httpntlm": "1.6.1",
+        "nodemailer-shared": "1.1.0"
+      }
+    },
+    "snapdragon": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+      "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+      "dev": true,
+      "requires": {
+        "base": "0.11.2",
+        "debug": "2.6.9",
+        "define-property": "0.2.5",
+        "extend-shallow": "2.0.1",
+        "map-cache": "0.2.2",
+        "source-map": "0.5.7",
+        "source-map-resolve": "0.5.1",
+        "use": "3.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "0.1.1"
+          }
+        }
+      }
+    },
+    "snapdragon-node": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+      "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+      "dev": true,
+      "requires": {
+        "define-property": "1.0.0",
+        "isobject": "3.0.1",
+        "snapdragon-util": "3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "1.0.2"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "1.0.0",
+            "is-data-descriptor": "1.0.0",
+            "kind-of": "6.0.2"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "snapdragon-util": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "sntp": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+      "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+      "dev": true,
+      "requires": {
+        "hoek": "2.16.3"
+      }
+    },
+    "socket.io": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.4.tgz",
+      "integrity": "sha1-waRZDO/4fs8TxyZS8Eb3FrKeYBQ=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "engine.io": "3.1.5",
+        "socket.io-adapter": "1.1.1",
+        "socket.io-client": "2.0.4",
+        "socket.io-parser": "3.1.3"
+      }
+    },
+    "socket.io-adapter": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz",
+      "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=",
+      "dev": true
+    },
+    "socket.io-client": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.4.tgz",
+      "integrity": "sha1-CRilUkBtxeVAs4Dc2Xr8SmQzL44=",
+      "dev": true,
+      "requires": {
+        "backo2": "1.0.2",
+        "base64-arraybuffer": "0.1.5",
+        "component-bind": "1.0.0",
+        "component-emitter": "1.2.1",
+        "debug": "2.6.9",
+        "engine.io-client": "3.1.6",
+        "has-cors": "1.1.0",
+        "indexof": "0.0.1",
+        "object-component": "0.0.3",
+        "parseqs": "0.0.5",
+        "parseuri": "0.0.5",
+        "socket.io-parser": "3.1.3",
+        "to-array": "0.1.4"
+      }
+    },
+    "socket.io-parser": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz",
+      "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==",
+      "dev": true,
+      "requires": {
+        "component-emitter": "1.2.1",
+        "debug": "3.1.0",
+        "has-binary2": "1.0.2",
+        "isarray": "2.0.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "isarray": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+          "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=",
+          "dev": true
+        }
+      }
+    },
+    "socks": {
+      "version": "1.1.10",
+      "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.10.tgz",
+      "integrity": "sha1-W4t/x8jzQcU+0FbpKbe/Tei6e1o=",
+      "dev": true,
+      "requires": {
+        "ip": "1.1.5",
+        "smart-buffer": "1.1.15"
+      },
+      "dependencies": {
+        "ip": {
+          "version": "1.1.5",
+          "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+          "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
+          "dev": true
+        }
+      }
+    },
+    "socks-proxy-agent": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-2.1.1.tgz",
+      "integrity": "sha512-sFtmYqdUK5dAMh85H0LEVFUCO7OhJJe1/z2x/Z6mxp3s7/QPf1RkZmpZy+BpuU0bEjcV9npqKjq9Y3kwFUjnxw==",
+      "dev": true,
+      "requires": {
+        "agent-base": "2.1.1",
+        "extend": "3.0.1",
+        "socks": "1.1.10"
+      },
+      "dependencies": {
+        "agent-base": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz",
+          "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=",
+          "dev": true,
+          "requires": {
+            "extend": "3.0.1",
+            "semver": "5.0.3"
+          }
+        },
+        "semver": {
+          "version": "5.0.3",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz",
+          "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=",
+          "dev": true
+        }
+      }
+    },
+    "source-list-map": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz",
+      "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==",
+      "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-resolve": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz",
+      "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==",
+      "dev": true,
+      "requires": {
+        "atob": "2.1.1",
+        "decode-uri-component": "0.2.0",
+        "resolve-url": "0.2.1",
+        "source-map-url": "0.4.0",
+        "urix": "0.1.0"
+      }
+    },
+    "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"
+      }
+    },
+    "source-map-url": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+      "dev": true
+    },
+    "spdx-correct": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
+      "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
+      "dev": true,
+      "requires": {
+        "spdx-license-ids": "1.2.2"
+      }
+    },
+    "spdx-expression-parse": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
+      "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=",
+      "dev": true
+    },
+    "spdx-license-ids": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
+      "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=",
+      "dev": true
+    },
+    "split": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
+      "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=",
+      "dev": true,
+      "requires": {
+        "through": "2.3.8"
+      }
+    },
+    "split-string": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "3.0.2"
+      }
+    },
+    "sprintf-js": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "dev": true
+    },
+    "sshpk": {
+      "version": "1.13.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
+      "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
+      "dev": true,
+      "requires": {
+        "asn1": "0.2.3",
+        "assert-plus": "1.0.0",
+        "bcrypt-pbkdf": "1.0.1",
+        "dashdash": "1.14.1",
+        "ecc-jsbn": "0.1.1",
+        "getpass": "0.1.7",
+        "jsbn": "0.1.1",
+        "tweetnacl": "0.14.5"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        }
+      }
+    },
+    "static-extend": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+      "dev": true,
+      "requires": {
+        "define-property": "0.2.5",
+        "object-copy": "0.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        }
+      }
+    },
+    "statuses": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+      "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+      "dev": true
+    },
+    "stdout-stream": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz",
+      "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "2.3.3"
+      }
+    },
+    "stream-browserify": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
+      "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.3"
+      }
+    },
+    "stream-combiner": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
+      "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=",
+      "dev": true,
+      "requires": {
+        "duplexer": "0.1.1"
+      }
+    },
+    "stream-http": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.0.tgz",
+      "integrity": "sha512-sZOFxI/5xw058XIRHl4dU3dZ+TTOIGJR78Dvo0oEAejIt4ou27k+3ne1zYmCV+v7UucbxIFQuOgnkTVHh8YPnw==",
+      "dev": true,
+      "requires": {
+        "builtin-status-codes": "3.0.0",
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.3",
+        "to-arraybuffer": "1.0.1",
+        "xtend": "4.0.1"
+      }
+    },
+    "streamroller": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz",
+      "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==",
+      "dev": true,
+      "requires": {
+        "date-format": "1.2.0",
+        "debug": "3.1.0",
+        "mkdirp": "0.5.1",
+        "readable-stream": "2.3.3"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "string-width": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+      "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+      "dev": true,
+      "requires": {
+        "is-fullwidth-code-point": "2.0.0",
+        "strip-ansi": "4.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        }
+      }
+    },
+    "string.prototype.codepointat": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.0.tgz",
+      "integrity": "sha1-aybpvTr8qnvjtCabUm3huCAArHg=",
+      "dev": true
+    },
+    "string.prototype.padend": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz",
+      "integrity": "sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA=",
+      "dev": true,
+      "requires": {
+        "define-properties": "1.1.2",
+        "es-abstract": "1.9.0",
+        "function-bind": "1.1.1"
+      }
+    },
+    "string_decoder": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+      "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "stringstream": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+      "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
+      "dev": true
+    },
+    "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"
+      }
+    },
+    "strip-bom": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+      "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+      "dev": true,
+      "requires": {
+        "is-utf8": "0.2.1"
+      }
+    },
+    "strip-eof": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+      "dev": true
+    },
+    "strip-indent": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+      "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+      "dev": true,
+      "requires": {
+        "get-stdin": "4.0.1"
+      }
+    },
+    "strip-json-comments": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+      "dev": true
+    },
+    "subarg": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz",
+      "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=",
+      "dev": true,
+      "requires": {
+        "minimist": "1.2.0"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "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
+    },
+    "symbol-observable": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz",
+      "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0="
+    },
+    "table": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
+      "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
+      "dev": true,
+      "requires": {
+        "ajv": "5.5.2",
+        "ajv-keywords": "2.1.1",
+        "chalk": "2.4.1",
+        "lodash": "4.17.4",
+        "slice-ansi": "1.0.0",
+        "string-width": "2.1.1"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.1"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.4.0"
+          }
+        },
+        "has-flag": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "tapable": {
+      "version": "0.2.8",
+      "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz",
+      "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=",
+      "dev": true
+    },
+    "tar": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+      "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
+      "dev": true,
+      "requires": {
+        "block-stream": "0.0.9",
+        "fstream": "1.0.11",
+        "inherits": "2.0.3"
+      }
+    },
+    "text-encoding": {
+      "version": "0.6.4",
+      "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz",
+      "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=",
+      "dev": true
+    },
+    "text-table": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+      "dev": true
+    },
+    "through": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "dev": true
+    },
+    "thunkify": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz",
+      "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=",
+      "dev": true,
+      "optional": true
+    },
+    "timespan": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz",
+      "integrity": "sha1-SQLOBAvRPYRcj1myfp1ZutbzmSk=",
+      "dev": true,
+      "optional": true
+    },
+    "tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
+      "requires": {
+        "os-tmpdir": "1.0.2"
+      }
+    },
+    "to-array": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
+      "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=",
+      "dev": true
+    },
+    "to-arraybuffer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
+      "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
+      "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
+    },
+    "to-object-path": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "to-regex": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "dev": true,
+      "requires": {
+        "define-property": "2.0.2",
+        "extend-shallow": "3.0.2",
+        "regex-not": "1.0.2",
+        "safe-regex": "1.1.0"
+      }
+    },
+    "to-regex-range": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+      "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+      "dev": true,
+      "requires": {
+        "is-number": "3.0.0",
+        "repeat-string": "1.6.1"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          }
+        }
+      }
+    },
+    "tough-cookie": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
+      "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
+      "dev": true,
+      "requires": {
+        "punycode": "1.4.1"
+      }
+    },
+    "trim-newlines": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+      "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
+      "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
+    },
+    "true-case-path": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz",
+      "integrity": "sha1-fskRMJJHZsf1c74wIMNPj9/QDWI=",
+      "dev": true,
+      "requires": {
+        "glob": "6.0.4"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "6.0.4",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
+          "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
+          "dev": true,
+          "requires": {
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        }
+      }
+    },
+    "tryit": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
+      "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=",
+      "dev": true
+    },
+    "tsscmp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.5.tgz",
+      "integrity": "sha1-fcSjOvcVgatDN9qR2FylQn69mpc=",
+      "dev": true,
+      "optional": true
+    },
+    "tunnel-agent": {
+      "version": "0.4.3",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
+      "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
+      "dev": true
+    },
+    "tv4": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.2.7.tgz",
+      "integrity": "sha1-vSk4mvxzreSa5fSBQrXVRL9o0SA=",
+      "dev": true
+    },
+    "tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true,
+      "optional": true
+    },
+    "type-check": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+      "dev": true,
+      "requires": {
+        "prelude-ls": "1.1.2"
+      }
+    },
+    "type-detect": {
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.5.tgz",
+      "integrity": "sha512-N9IvkQslUGYGC24RkJk1ba99foK6TkwC2FHAEBlQFBP0RxQZS8ZpJuAZcwiY/w9ZJHFQb1aOXBI60OdxhTrwEQ==",
+      "dev": true
+    },
+    "type-is": {
+      "version": "1.6.16",
+      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
+      "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
+      "dev": true,
+      "requires": {
+        "media-typer": "0.3.0",
+        "mime-types": "2.1.18"
+      },
+      "dependencies": {
+        "mime-db": {
+          "version": "1.33.0",
+          "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
+          "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
+          "dev": true
+        },
+        "mime-types": {
+          "version": "2.1.18",
+          "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
+          "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
+          "dev": true,
+          "requires": {
+            "mime-db": "1.33.0"
+          }
+        }
+      }
+    },
+    "typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "ua-parser-js": {
+      "version": "0.7.17",
+      "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz",
+      "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g=="
+    },
+    "uglify-js": {
+      "version": "2.8.29",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
+      "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
+      "dev": true,
+      "requires": {
+        "source-map": "0.5.7",
+        "uglify-to-browserify": "1.0.2",
+        "yargs": "3.10.0"
+      }
+    },
+    "uglify-to-browserify": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+      "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+      "dev": true,
+      "optional": true
+    },
+    "uglifyjs-webpack-plugin": {
+      "version": "0.4.6",
+      "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz",
+      "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=",
+      "dev": true,
+      "requires": {
+        "source-map": "0.5.7",
+        "uglify-js": "2.8.29",
+        "webpack-sources": "1.1.0"
+      }
+    },
+    "ultron": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
+      "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
+      "dev": true
+    },
+    "underscore": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz",
+      "integrity": "sha1-YaajIBBiKvoHljvzJSA88SI51gQ=",
+      "dev": true
+    },
+    "unicons": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/unicons/-/unicons-0.0.3.tgz",
+      "integrity": "sha1-bmp6Gm6uuwHKPYsSrZaHJ56rpSQ=",
+      "dev": true
+    },
+    "union-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
+      "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+      "dev": true,
+      "requires": {
+        "arr-union": "3.1.0",
+        "get-value": "2.0.6",
+        "is-extendable": "0.1.1",
+        "set-value": "0.4.3"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "0.1.1"
+          }
+        },
+        "set-value": {
+          "version": "0.4.3",
+          "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+          "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+          "dev": true,
+          "requires": {
+            "extend-shallow": "2.0.1",
+            "is-extendable": "0.1.1",
+            "is-plain-object": "2.0.4",
+            "to-object-path": "0.3.0"
+          }
+        }
+      }
+    },
+    "universalify": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
+      "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=",
+      "dev": true
+    },
+    "unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+      "dev": true
+    },
+    "unset-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "dev": true,
+      "requires": {
+        "has-value": "0.3.1",
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "has-value": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+          "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+          "dev": true,
+          "requires": {
+            "get-value": "2.0.6",
+            "has-values": "0.1.4",
+            "isobject": "2.1.0"
+          },
+          "dependencies": {
+            "isobject": {
+              "version": "2.1.0",
+              "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+              "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+              "dev": true,
+              "requires": {
+                "isarray": "1.0.0"
+              }
+            }
+          }
+        },
+        "has-values": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+          "dev": true
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "upath": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.5.tgz",
+      "integrity": "sha512-qbKn90aDQ0YEwvXoLqj0oiuUYroLX2lVHZ+b+xwjozFasAOC4GneDq5+OaIG5Zj+jFmbz/uO+f7a9qxjktJQww==",
+      "dev": true
+    },
+    "urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "url": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+      "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+      "dev": true,
+      "requires": {
+        "punycode": "1.3.2",
+        "querystring": "0.2.0"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+          "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+          "dev": true
+        }
+      }
+    },
+    "url-join": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz",
+      "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=",
+      "dev": true
+    },
+    "url-template": {
+      "version": "2.0.8",
+      "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
+      "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=",
+      "dev": true
+    },
+    "url2": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/url2/-/url2-0.0.0.tgz",
+      "integrity": "sha1-Tqq9HVw6yQ1iq0SFyZhCKGWgSxo=",
+      "dev": true
+    },
+    "use": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz",
+      "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==",
+      "dev": true,
+      "requires": {
+        "kind-of": "6.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "user-home": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
+      "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=",
+      "dev": true,
+      "requires": {
+        "os-homedir": "1.0.2"
+      }
+    },
+    "useragent": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.2.1.tgz",
+      "integrity": "sha1-z1k+9PLRdYdei7ZY6pLhik/QbY4=",
+      "dev": true,
+      "requires": {
+        "lru-cache": "2.2.4",
+        "tmp": "0.0.33"
+      },
+      "dependencies": {
+        "lru-cache": {
+          "version": "2.2.4",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.2.4.tgz",
+          "integrity": "sha1-bGWGGb7PFAMdDQtZSxYELOTcBj0=",
+          "dev": true
+        }
+      }
+    },
+    "util": {
+      "version": "0.10.3",
+      "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+      "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.1"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+          "dev": true
+        }
+      }
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "dev": true
+    },
+    "utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+      "dev": true
+    },
+    "uws": {
+      "version": "9.14.0",
+      "resolved": "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz",
+      "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==",
+      "dev": true,
+      "optional": true
+    },
+    "validate-npm-package-license": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
+      "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
+      "dev": true,
+      "requires": {
+        "spdx-correct": "1.0.2",
+        "spdx-expression-parse": "1.0.4"
+      }
+    },
+    "verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "1.3.0"
+      },
+      "dependencies": {
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        }
+      }
+    },
+    "vm-browserify": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
+      "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
+      "dev": true,
+      "requires": {
+        "indexof": "0.0.1"
+      }
+    },
+    "void-elements": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
+      "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
+      "dev": true
+    },
+    "watchpack": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz",
+      "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=",
+      "dev": true,
+      "requires": {
+        "async": "2.6.0",
+        "chokidar": "1.7.0",
+        "graceful-fs": "4.1.11"
+      },
+      "dependencies": {
+        "async": {
+          "version": "2.6.0",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
+          "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
+          "dev": true,
+          "requires": {
+            "lodash": "4.17.4"
+          }
+        }
+      }
+    },
+    "weak-map": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.0.tgz",
+      "integrity": "sha1-tm5Wqd8L0lp2u/G1FNsSkIBhSjc=",
+      "dev": true
+    },
+    "webpack": {
+      "version": "3.10.0",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.10.0.tgz",
+      "integrity": "sha512-fxxKXoicjdXNUMY7LIdY89tkJJJ0m1Oo8PQutZ5rLgWbV5QVKI15Cn7+/IHnRTd3vfKfiwBx6SBqlorAuNA8LA==",
+      "dev": true,
+      "requires": {
+        "acorn": "5.1.2",
+        "acorn-dynamic-import": "2.0.2",
+        "ajv": "5.5.2",
+        "ajv-keywords": "2.1.1",
+        "async": "2.6.0",
+        "enhanced-resolve": "3.4.1",
+        "escope": "3.6.0",
+        "interpret": "1.1.0",
+        "json-loader": "0.5.7",
+        "json5": "0.5.1",
+        "loader-runner": "2.3.0",
+        "loader-utils": "1.1.0",
+        "memory-fs": "0.4.1",
+        "mkdirp": "0.5.1",
+        "node-libs-browser": "2.1.0",
+        "source-map": "0.5.7",
+        "supports-color": "4.5.0",
+        "tapable": "0.2.8",
+        "uglifyjs-webpack-plugin": "0.4.6",
+        "watchpack": "1.4.0",
+        "webpack-sources": "1.1.0",
+        "yargs": "8.0.2"
+      },
+      "dependencies": {
+        "async": {
+          "version": "2.6.0",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
+          "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
+          "dev": true,
+          "requires": {
+            "lodash": "4.17.4"
+          }
+        },
+        "camelcase": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+          "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+          "dev": true
+        },
+        "cliui": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+          "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+          "dev": true,
+          "requires": {
+            "string-width": "1.0.2",
+            "strip-ansi": "3.0.1",
+            "wrap-ansi": "2.1.0"
+          },
+          "dependencies": {
+            "string-width": {
+              "version": "1.0.2",
+              "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+              "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+              "dev": true,
+              "requires": {
+                "code-point-at": "1.1.0",
+                "is-fullwidth-code-point": "1.0.0",
+                "strip-ansi": "3.0.1"
+              }
+            }
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "load-json-file": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+          "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "4.1.11",
+            "parse-json": "2.2.0",
+            "pify": "2.3.0",
+            "strip-bom": "3.0.0"
+          }
+        },
+        "loader-utils": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+          "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+          "dev": true,
+          "requires": {
+            "big.js": "3.2.0",
+            "emojis-list": "2.1.0",
+            "json5": "0.5.1"
+          }
+        },
+        "os-locale": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
+          "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
+          "dev": true,
+          "requires": {
+            "execa": "0.7.0",
+            "lcid": "1.0.0",
+            "mem": "1.1.0"
+          }
+        },
+        "path-type": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+          "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+          "dev": true,
+          "requires": {
+            "pify": "2.3.0"
+          }
+        },
+        "read-pkg": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+          "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+          "dev": true,
+          "requires": {
+            "load-json-file": "2.0.0",
+            "normalize-package-data": "2.4.0",
+            "path-type": "2.0.0"
+          }
+        },
+        "read-pkg-up": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+          "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+          "dev": true,
+          "requires": {
+            "find-up": "2.1.0",
+            "read-pkg": "2.0.0"
+          }
+        },
+        "strip-bom": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+          "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        },
+        "which-module": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+          "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+          "dev": true
+        },
+        "yargs": {
+          "version": "8.0.2",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz",
+          "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=",
+          "dev": true,
+          "requires": {
+            "camelcase": "4.1.0",
+            "cliui": "3.2.0",
+            "decamelize": "1.2.0",
+            "get-caller-file": "1.0.2",
+            "os-locale": "2.1.0",
+            "read-pkg-up": "2.0.0",
+            "require-directory": "2.1.1",
+            "require-main-filename": "1.0.1",
+            "set-blocking": "2.0.0",
+            "string-width": "2.1.1",
+            "which-module": "2.0.0",
+            "y18n": "3.2.1",
+            "yargs-parser": "7.0.0"
+          }
+        },
+        "yargs-parser": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz",
+          "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
+          "dev": true,
+          "requires": {
+            "camelcase": "4.1.0"
+          }
+        }
+      }
+    },
+    "webpack-dev-middleware": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-2.0.6.tgz",
+      "integrity": "sha512-tj5LLD9r4tDuRIDa5Mu9lnY2qBBehAITv6A9irqXhw/HQquZgTx3BCd57zYbU2gMDnncA49ufK2qVQSbaKJwOw==",
+      "dev": true,
+      "requires": {
+        "loud-rejection": "1.6.0",
+        "memory-fs": "0.4.1",
+        "mime": "2.3.1",
+        "path-is-absolute": "1.0.1",
+        "range-parser": "1.2.0",
+        "url-join": "2.0.5",
+        "webpack-log": "1.2.0"
+      },
+      "dependencies": {
+        "mime": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
+          "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==",
+          "dev": true
+        }
+      }
+    },
+    "webpack-log": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz",
+      "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==",
+      "dev": true,
+      "requires": {
+        "chalk": "2.4.1",
+        "log-symbols": "2.1.0",
+        "loglevelnext": "1.0.5",
+        "uuid": "3.2.1"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.1"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.4.0"
+          }
+        },
+        "has-flag": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        },
+        "uuid": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
+          "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==",
+          "dev": true
+        }
+      }
+    },
+    "webpack-sources": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz",
+      "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==",
+      "dev": true,
+      "requires": {
+        "source-list-map": "2.0.0",
+        "source-map": "0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "whatwg-fetch": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz",
+      "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ="
+    },
+    "when": {
+      "version": "3.7.8",
+      "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz",
+      "integrity": "sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I=",
+      "dev": true,
+      "optional": true
+    },
+    "which": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
+      "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
+      "dev": true,
+      "requires": {
+        "isexe": "2.0.0"
+      }
+    },
+    "which-module": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+      "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
+      "dev": true
+    },
+    "wide-align": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
+      "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
+      "dev": true,
+      "requires": {
+        "string-width": "1.0.2"
+      },
+      "dependencies": {
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "1.1.0",
+            "is-fullwidth-code-point": "1.0.0",
+            "strip-ansi": "3.0.1"
+          }
+        }
+      }
+    },
+    "window-size": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
+      "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
+      "dev": true
+    },
+    "wordwrap": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+      "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+      "dev": true
+    },
+    "wrap-ansi": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+      "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+      "dev": true,
+      "requires": {
+        "string-width": "1.0.2",
+        "strip-ansi": "3.0.1"
+      },
+      "dependencies": {
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "1.1.0",
+            "is-fullwidth-code-point": "1.0.0",
+            "strip-ansi": "3.0.1"
+          }
+        }
+      }
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "dev": true
+    },
+    "write": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+      "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+      "dev": true,
+      "requires": {
+        "mkdirp": "0.5.1"
+      }
+    },
+    "ws": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
+      "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
+      "dev": true,
+      "requires": {
+        "async-limiter": "1.0.0",
+        "safe-buffer": "5.1.1",
+        "ultron": "1.1.1"
+      }
+    },
+    "xmlhttprequest-ssl": {
+      "version": "1.5.5",
+      "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
+      "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=",
+      "dev": true
+    },
+    "xregexp": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz",
+      "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=",
+      "dev": true,
+      "optional": true
+    },
+    "xtend": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+      "dev": true
+    },
+    "y18n": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+      "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
+      "dev": true
+    },
+    "yallist": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+      "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+      "dev": true
+    },
+    "yamljs": {
+      "version": "0.2.10",
+      "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.2.10.tgz",
+      "integrity": "sha1-SBzHwlynOvWfWR8MluPOVsdXpA8=",
+      "dev": true,
+      "requires": {
+        "argparse": "1.0.9",
+        "glob": "7.1.2"
+      }
+    },
+    "yamscripts": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/yamscripts/-/yamscripts-0.0.3.tgz",
+      "integrity": "sha1-GcH29/KcbCc0R7ou7/+6vDefSFQ=",
+      "dev": true,
+      "requires": {
+        "colors": "1.1.2",
+        "commander": "2.11.0",
+        "fs-extra": "0.26.7",
+        "inquirer": "0.11.4",
+        "minimist": "1.2.0",
+        "yamljs": "0.2.10"
+      },
+      "dependencies": {
+        "ansi-escapes": {
+          "version": "1.4.0",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
+          "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
+          "dev": true
+        },
+        "cli-cursor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
+          "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
+          "dev": true,
+          "requires": {
+            "restore-cursor": "1.0.1"
+          }
+        },
+        "cli-width": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.1.1.tgz",
+          "integrity": "sha1-pNKT72frt7iNSk1CwMzwDE0eNm0=",
+          "dev": true
+        },
+        "commander": {
+          "version": "2.11.0",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
+          "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
+          "dev": true
+        },
+        "figures": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+          "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
+          "dev": true,
+          "requires": {
+            "escape-string-regexp": "1.0.5",
+            "object-assign": "4.1.1"
+          }
+        },
+        "fs-extra": {
+          "version": "0.26.7",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz",
+          "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "4.1.11",
+            "jsonfile": "2.4.0",
+            "klaw": "1.3.1",
+            "path-is-absolute": "1.0.1",
+            "rimraf": "2.6.2"
+          }
+        },
+        "inquirer": {
+          "version": "0.11.4",
+          "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.11.4.tgz",
+          "integrity": "sha1-geM3ToNhvq/y2XAWIG01nQsy+k0=",
+          "dev": true,
+          "requires": {
+            "ansi-escapes": "1.4.0",
+            "ansi-regex": "2.1.1",
+            "chalk": "1.1.3",
+            "cli-cursor": "1.0.2",
+            "cli-width": "1.1.1",
+            "figures": "1.7.0",
+            "lodash": "3.10.1",
+            "readline2": "1.0.1",
+            "run-async": "0.1.0",
+            "rx-lite": "3.1.2",
+            "string-width": "1.0.2",
+            "strip-ansi": "3.0.1",
+            "through": "2.3.8"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "lodash": {
+          "version": "3.10.1",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+          "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+          "dev": true
+        },
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        },
+        "onetime": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+          "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
+          "dev": true
+        },
+        "restore-cursor": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
+          "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
+          "dev": true,
+          "requires": {
+            "exit-hook": "1.1.1",
+            "onetime": "1.1.0"
+          }
+        },
+        "run-async": {
+          "version": "0.1.0",
+          "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
+          "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=",
+          "dev": true,
+          "requires": {
+            "once": "1.4.0"
+          }
+        },
+        "rx-lite": {
+          "version": "3.1.2",
+          "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
+          "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "1.1.0",
+            "is-fullwidth-code-point": "1.0.0",
+            "strip-ansi": "3.0.1"
+          }
+        }
+      }
+    },
+    "yargs": {
+      "version": "3.10.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
+      "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
+      "dev": true,
+      "requires": {
+        "camelcase": "1.2.1",
+        "cliui": "2.1.0",
+        "decamelize": "1.2.0",
+        "window-size": "0.1.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+          "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
+          "dev": true
+        }
+      }
+    },
+    "yargs-parser": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
+      "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
+      "dev": true,
+      "requires": {
+        "camelcase": "3.0.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+          "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+          "dev": true
+        }
+      }
+    },
+    "yeast": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
+      "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=",
+      "dev": true
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/package.json
@@ -0,0 +1,132 @@
+{
+  "name": "activity-streams",
+  "description": "A rich visual history feed and a reimagined home page make it easier than ever to find exactly what you're looking for in Firefox.\n\nLearn more about this Test Pilot experiment at https://testpilot.firefox.com/.",
+  "version": "1.14.3",
+  "author": "Mozilla (https://mozilla.org/)",
+  "bugs": {
+    "url": "https://github.com/mozilla/activity-stream/issues"
+  },
+  "dependencies": {
+    "prop-types": "15.6.1",
+    "react": "16.2.0",
+    "react-dom": "16.2.0",
+    "react-intl": "2.4.0",
+    "react-redux": "5.0.6",
+    "redux": "3.6.0"
+  },
+  "devDependencies": {
+    "@octokit/rest": "15.3.0",
+    "babel-core": "6.26.3",
+    "babel-loader": "7.1.4",
+    "babel-plugin-jsm-to-commonjs": "0.4.0",
+    "babel-plugin-jsm-to-esmodules": "0.4.0",
+    "babel-plugin-transform-async-to-module-method": "6.24.1",
+    "babel-plugin-transform-es2015-modules-commonjs": "6.26.2",
+    "babel-plugin-transform-object-rest-spread": "6.26.0",
+    "babel-preset-react": "6.24.1",
+    "chai": "4.1.2",
+    "chai-json-schema": "1.5.0",
+    "co-task": "1.0.0",
+    "cpx": "1.5.0",
+    "enzyme": "3.3.0",
+    "enzyme-adapter-react-16": "1.1.1",
+    "eslint": "4.19.1",
+    "eslint-plugin-import": "2.11.0",
+    "eslint-plugin-json": "1.2.0",
+    "eslint-plugin-mozilla": "0.11.0",
+    "eslint-plugin-no-unsanitized": "3.0.0",
+    "eslint-plugin-promise": "3.7.0",
+    "eslint-plugin-react": "7.7.0",
+    "eslint-watch": "3.1.4",
+    "husky": "0.14.3",
+    "istanbul-instrumenter-loader": "0.2.0",
+    "joi-browser": "13.0.1",
+    "karma": "2.0.2",
+    "karma-chai": "0.1.0",
+    "karma-coverage": "1.1.1",
+    "karma-firefox-launcher": "1.1.0",
+    "karma-mocha": "1.3.0",
+    "karma-mocha-reporter": "2.2.5",
+    "karma-sinon": "1.0.5",
+    "karma-sourcemap-loader": "0.3.7",
+    "karma-webpack": "3.0.0",
+    "loader-utils": "0.2.16",
+    "minimist": "1.2.0",
+    "mocha": "5.1.1",
+    "mock-raf": "1.0.0",
+    "node-fetch": "2.1.2",
+    "node-sass": "4.7.2",
+    "npm-run-all": "4.1.2",
+    "pontoon-to-json": "2.0.0",
+    "react-test-renderer": "16.3.2",
+    "rimraf": "2.6.2",
+    "sass-lint": "1.12.1",
+    "shelljs": "0.8.1",
+    "simple-git": "1.92.0",
+    "sinon": "4.5.0",
+    "webpack": "3.10.0",
+    "yamscripts": "0.0.3"
+  },
+  "engines": {
+    "firefox": ">=45.0 <=*",
+    "//": "when changing node versions, also edit .travis.yml and .nvmrc",
+    "node": "7.*"
+  },
+  "homepage": "https://github.com/mozilla/activity-stream",
+  "keywords": [
+    "mozilla",
+    "firefox",
+    "activity-stream"
+  ],
+  "license": "MPL-2.0",
+  "main": "bootstrap.js",
+  "repository": "mozilla/activity-stream",
+  "config": {
+    "mc_dir": "../mozilla-central"
+  },
+  "scripts": {
+    "mochitest": "(cd $npm_package_config_mc_dir && ./mach mochitest browser/extensions/activity-stream/test/functional/mochitest )",
+    "mochitest-debug": "(cd $npm_package_config_mc_dir && ./mach mochitest --jsdebugger browser/extensions/activity-stream/test/functional/mochitest)",
+    "bundle": "npm-run-all bundle:*",
+    "bundle:locales": "pontoon-to-json --src locales --dest data",
+    "bundle:webpack": "webpack --config webpack.system-addon.config.js --display-optimization-bailout",
+    "bundle:css": "node-sass --source-map true --source-map-contents content-src/styles -o css",
+    "bundle:html": "rimraf prerendered && webpack --config webpack.prerender.config.js && node ./bin/render-activity-stream-html.js",
+    "buildmc": "npm-run-all buildmc:*",
+    "prebuildmc": "rimraf $npm_package_config_mc_dir/browser/extensions/activity-stream/",
+    "buildmc:bundle": "npm run  bundle",
+    "buildmc:copy": "rsync --exclude-from .mcignore -a . $npm_package_config_mc_dir/browser/extensions/activity-stream/",
+    "buildmc:version": "node ./bin/update-version.js $npm_package_config_mc_dir/browser/extensions/activity-stream",
+    "buildmc:stringsExport": "cp locales/en-US/strings.properties $npm_package_config_mc_dir/browser/locales/en-US/chrome/browser/activity-stream/newtab.properties",
+    "buildmc:copyPingCentre": "cpx \"ping-centre/PingCentre.jsm\" $npm_package_config_mc_dir/browser/modules",
+    "startmc": "npm-run-all --parallel startmc:*",
+    "prestartmc": "npm run buildmc",
+    "startmc:copy": "cpx \"{{,.}*,!(node_modules)/**/{,.}*}\" $npm_package_config_mc_dir/browser/extensions/activity-stream/ -w",
+    "startmc:copyPingCentre": "npm run buildmc:copyPingCentre -- -w",
+    "startmc:webpack": "npm run bundle:webpack -- -w",
+    "startmc:css": "npm run bundle:css && npm run bundle:css -- -w",
+    "importmc": "rsync --exclude-from .mcignore -a $npm_package_config_mc_dir/browser/extensions/activity-stream/ .",
+    "testmc": "npm-run-all testmc:*",
+    "testmc:lint": "npm run lint",
+    "testmc:build": "npm run bundle:webpack && npm run bundle:locales",
+    "testmc:unit": "karma start karma.mc.config.js || (cat logs/coverage/text.txt && exit 2)",
+    "posttestmc": "cat logs/coverage/text-summary.txt",
+    "tddmc": "karma start karma.mc.config.js --tdd",
+    "debugcoverage": "open logs/coverage/report-html/index.html",
+    "lint": "npm-run-all lint:*",
+    "lint:eslint": "esw --ext=.js,.jsm,.json,.jsx .",
+    "lint:sasslint": "sass-lint -v -q",
+    "strings-import": "node ./bin/strings-import.js",
+    "test": "npm run testmc",
+    "tdd": "npm run tddmc",
+    "prepush": "npm run lint && npm run yamscripts",
+    "help": "yamscripts help",
+    "yamscripts": "yamscripts compile",
+    "__": "# NOTE: THESE SCRIPTS ARE COMPILED!!! EDIT yamscripts.yml instead!!!"
+  },
+  "title": "Activity Stream",
+  "permissions": {
+    "multiprocess": true,
+    "private-browsing": true
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/components/Base.test.jsx
@@ -0,0 +1,76 @@
+import {_Base as Base, BaseContent} from "content-src/components/Base/Base";
+import {ErrorBoundary} from "content-src/components/ErrorBoundary/ErrorBoundary";
+import React from "react";
+import {Search} from "content-src/components/Search/Search";
+import {shallow} from "enzyme";
+import {StartupOverlay} from "content-src/components/StartupOverlay/StartupOverlay";
+
+describe("<Base>", () => {
+  let DEFAULT_PROPS = {store: {getState: () => {}}, App: {initialized: true}, Prefs: {values: {}}, Theme: {className: ""}, dispatch: () => {}};
+
+  it("should render Base component", () => {
+    const wrapper = shallow(<Base {...DEFAULT_PROPS} />);
+    assert.ok(wrapper.exists());
+  });
+
+  it("should render the BaseContent component, passing through all props", () => {
+    const wrapper = shallow(<Base {...DEFAULT_PROPS} />);
+
+    assert.deepEqual(wrapper.find(BaseContent).props(), DEFAULT_PROPS);
+  });
+
+  it("should fire NEW_TAB_REHYDRATED event", () => {
+    const dispatch = sinon.spy();
+    shallow(<Base {...Object.assign({}, DEFAULT_PROPS, {dispatch})} />);
+    assert.calledOnce(dispatch);
+    const [action] = dispatch.firstCall.args;
+    assert.equal("NEW_TAB_REHYDRATED", action.type);
+  });
+
+  it("should render an ErrorBoundary with class base-content-fallback", () => {
+    const wrapper = shallow(<Base {...DEFAULT_PROPS} />);
+
+    assert.equal(
+      wrapper.find(ErrorBoundary).first().prop("className"), "base-content-fallback");
+  });
+
+  it("should change body className on updateTheme", () => {
+    const wrapper = shallow(<Base {...DEFAULT_PROPS} />);
+    assert.equal(document.querySelectorAll("body.some-theme").length, 0);
+    wrapper.instance().updateTheme({className: "some-theme"});
+    assert.equal(document.querySelectorAll("body.some-theme").length, 1);
+    wrapper.instance().updateTheme({className: ""});
+    assert.equal(document.querySelectorAll("body.some-theme").length, 0);
+  });
+});
+
+describe("<BaseContent>", () => {
+  let DEFAULT_PROPS = {store: {getState: () => {}}, App: {initialized: true}, Prefs: {values: {}}, Theme: {className: ""}, dispatch: () => {}};
+
+  it("should render an ErrorBoundary with a Search child", () => {
+    const searchEnabledProps =
+      Object.assign({}, DEFAULT_PROPS, {Prefs: {values: {showSearch: true}}});
+
+    const wrapper = shallow(<BaseContent {...searchEnabledProps} />);
+
+    assert.isTrue(wrapper.find(Search).parent().is(ErrorBoundary));
+  });
+
+  it("should render a StartupOverlay when on about:welcome (props are sent as true)", () => {
+    const isFirstrunProps =
+      Object.assign({}, DEFAULT_PROPS, {isFirstrun: true});
+
+    const wrapper = shallow(<BaseContent {...isFirstrunProps} />);
+
+    assert.ok(wrapper.find(StartupOverlay).exists());
+  });
+
+  it("should not render a StartupOverlay when not on about:welcome (props are sent as false)", () => {
+    const notFirstrunProps =
+      Object.assign({}, DEFAULT_PROPS, {isFirstrun: false});
+
+    const wrapper = shallow(<BaseContent {...notFirstrunProps} />);
+
+    assert.ok(!wrapper.find(StartupOverlay).exists());
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/components/Card.test.jsx
@@ -0,0 +1,398 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {_Card as Card, PlaceholderCard} from "content-src/components/Card/Card";
+import {combineReducers, createStore} from "redux";
+import {GlobalOverrider, mountWithIntl} from "test/unit/utils";
+import {INITIAL_STATE, reducers} from "common/Reducers.jsm";
+import {cardContextTypes} from "content-src/components/Card/types";
+import {LinkMenu} from "content-src/components/LinkMenu/LinkMenu";
+import {Provider} from "react-redux";
+import React from "react";
+import {shallow} from "enzyme";
+
+let DEFAULT_PROPS = {
+  dispatch: sinon.stub(),
+  index: 0,
+  link: {
+    hostname: "foo",
+    title: "A title for foo",
+    url: "http://www.foo.com",
+    type: "history",
+    description: "A description for foo",
+    image: "http://www.foo.com/img.png",
+    guid: 1
+  },
+  eventSource: "TOP_STORIES",
+  shouldSendImpressionStats: true,
+  contextMenuOptions: ["Separator"]
+};
+
+let DEFAULT_BLOB_IMAGE = {
+  path: "/testpath",
+  data: new Blob([0])
+};
+
+function mountCardWithProps(props) {
+  const store = createStore(combineReducers(reducers), INITIAL_STATE);
+  return mountWithIntl(<Provider store={store}><Card {...props} /></Provider>);
+}
+
+describe("<Card>", () => {
+  let globals;
+  let sandbox;
+  let wrapper;
+  beforeEach(() => {
+    globals = new GlobalOverrider();
+    sandbox = sinon.sandbox.create();
+    wrapper = mountCardWithProps(DEFAULT_PROPS);
+  });
+  afterEach(() => {
+    DEFAULT_PROPS.dispatch.reset();
+    sandbox.restore();
+    globals.restore();
+  });
+  it("should render a Card component", () => assert.ok(wrapper.exists()));
+  it("should add the right url", () => {
+    assert.propertyVal(wrapper.find("a").props(), "href", DEFAULT_PROPS.link.url);
+
+    // test that pocket cards get a special open_url href
+    const pocketLink = Object.assign({}, DEFAULT_PROPS.link, {open_url: "getpocket.com/foo", type: "pocket"});
+    wrapper = mountWithIntl(<Card {...Object.assign({}, DEFAULT_PROPS, {link: pocketLink})} />);
+    assert.propertyVal(wrapper.find("a").props(), "href", pocketLink.open_url);
+  });
+  it("should display a title", () => assert.equal(wrapper.find(".card-title").text(), DEFAULT_PROPS.link.title));
+  it("should display a description", () => (
+    assert.equal(wrapper.find(".card-description").text(), DEFAULT_PROPS.link.description)
+  ));
+  it("should display a host name", () => assert.equal(wrapper.find(".card-host-name").text(), "foo"));
+  it("should have a link menu button", () => assert.ok(wrapper.find(".context-menu-button").exists()));
+  it("should render a link menu when button is clicked", () => {
+    const button = wrapper.find(".context-menu-button");
+    assert.equal(wrapper.find(LinkMenu).length, 0);
+    button.simulate("click", {preventDefault: () => {}});
+    assert.equal(wrapper.find(LinkMenu).length, 1);
+  });
+  it("should pass dispatch, source, onUpdate, site, options, and index to LinkMenu", () => {
+    wrapper.find(".context-menu-button").simulate("click", {preventDefault: () => {}});
+    const {dispatch, source, onUpdate, site, options, index} = wrapper.find(LinkMenu).props();
+    assert.equal(dispatch, DEFAULT_PROPS.dispatch);
+    assert.equal(source, DEFAULT_PROPS.eventSource);
+    assert.ok(onUpdate);
+    assert.equal(site, DEFAULT_PROPS.link);
+    assert.equal(options, DEFAULT_PROPS.contextMenuOptions);
+    assert.equal(index, DEFAULT_PROPS.index);
+  });
+  it("should pass through the correct menu options to LinkMenu if overridden by individual card", () => {
+    const link = Object.assign({}, DEFAULT_PROPS.link);
+    link.contextMenuOptions = ["CheckBookmark"];
+
+    wrapper = mountCardWithProps(Object.assign({}, DEFAULT_PROPS, {link}));
+    wrapper.find(".context-menu-button").simulate("click", {preventDefault: () => {}});
+    const {options} = wrapper.find(LinkMenu).props();
+    assert.equal(options, link.contextMenuOptions);
+  });
+  it("should have a context based on type", () => {
+    wrapper = shallow(<Card {...DEFAULT_PROPS} />);
+    const context = wrapper.find(".card-context");
+    const {icon, intlID} = cardContextTypes[DEFAULT_PROPS.link.type];
+    assert.isTrue(context.childAt(0).hasClass(`icon-${icon}`));
+    assert.isTrue(context.childAt(1).hasClass("card-context-label"));
+    assert.equal(context.childAt(1).props().children.props.id, intlID);
+  });
+  it("should support setting custom context", () => {
+    const linkWithCustomContext = {
+      type: "history",
+      context: "Custom",
+      icon: "icon-url"
+    };
+
+    wrapper = shallow(<Card {...Object.assign({}, DEFAULT_PROPS, {link: linkWithCustomContext})} />);
+    const context = wrapper.find(".card-context");
+    const {icon} = cardContextTypes[DEFAULT_PROPS.link.type];
+    assert.isFalse(context.childAt(0).hasClass(`icon-${icon}`));
+    assert.equal(context.childAt(0).props().style.backgroundImage, "url('icon-url')");
+
+    assert.isTrue(context.childAt(1).hasClass("card-context-label"));
+    assert.equal(context.childAt(1).text(), linkWithCustomContext.context);
+  });
+  it("should have .active class, on card-outer if context menu is open", () => {
+    const button = wrapper.find(".context-menu-button");
+    assert.isFalse(wrapper.find(".card-outer").hasClass("active"));
+    button.simulate("click", {preventDefault: () => {}});
+    assert.isTrue(wrapper.find(".card-outer").hasClass("active"));
+  });
+  it("should send SHOW_DOWNLOAD_FILE if we clicked on a download", () => {
+    const downloadLink = {
+      type: "download",
+      url: "download.mov"
+    };
+    wrapper = mountCardWithProps(Object.assign({}, DEFAULT_PROPS, {link: downloadLink}));
+    const card = wrapper.find(".card");
+    card.simulate("click", {preventDefault: () => {}});
+    assert.calledThrice(DEFAULT_PROPS.dispatch);
+
+    assert.equal(DEFAULT_PROPS.dispatch.firstCall.args[0].type, at.SHOW_DOWNLOAD_FILE);
+    assert.deepEqual(DEFAULT_PROPS.dispatch.firstCall.args[0].data, downloadLink);
+  });
+  it("should send OPEN_LINK if we clicked on anything other than a download", () => {
+    const nonDownloadLink = {
+      type: "history",
+      url: "download.mov"
+    };
+    wrapper = mountCardWithProps(Object.assign({}, DEFAULT_PROPS, {link: nonDownloadLink}));
+    const card = wrapper.find(".card");
+    const event = {altKey: "1", button: "2", ctrlKey: "3", metaKey: "4", shiftKey: "5"};
+    card.simulate("click", Object.assign({}, event, {preventDefault: () => {}}));
+    assert.calledThrice(DEFAULT_PROPS.dispatch);
+
+    assert.equal(DEFAULT_PROPS.dispatch.firstCall.args[0].type, at.OPEN_LINK);
+  });
+  describe("card image display", () => {
+    const DEFAULT_BLOB_URL = "blob:testBlobUrl";
+    let url;
+    beforeEach(() => {
+      url = {createObjectURL: sandbox.stub().returns(DEFAULT_BLOB_URL), revokeObjectURL: sandbox.spy()};
+      globals.set("URL", url);
+    });
+    afterEach(() => {
+      sandbox.restore();
+    });
+    it("should display a regular image correctly and not call revokeObjectURL when unmounted", () => {
+      wrapper = shallow(<Card {...DEFAULT_PROPS} />);
+
+      assert.isUndefined(wrapper.state("cardImage").path);
+      assert.equal(wrapper.state("cardImage").url, DEFAULT_PROPS.link.image);
+      assert.equal(wrapper.find(".card-preview-image").props().style.backgroundImage, `url(${wrapper.state("cardImage").url})`);
+
+      wrapper.unmount();
+      assert.notCalled(url.revokeObjectURL);
+    });
+    it("should display a blob image correctly and revoke blob url when unmounted", () => {
+      const link = Object.assign({}, DEFAULT_PROPS.link, {image: DEFAULT_BLOB_IMAGE});
+      wrapper = shallow(<Card {...DEFAULT_PROPS} link={link} />);
+
+      assert.equal(wrapper.state("cardImage").path, DEFAULT_BLOB_IMAGE.path);
+      assert.equal(wrapper.state("cardImage").url, DEFAULT_BLOB_URL);
+      assert.equal(wrapper.find(".card-preview-image").props().style.backgroundImage, `url(${wrapper.state("cardImage").url})`);
+
+      wrapper.unmount();
+      assert.calledOnce(url.revokeObjectURL);
+    });
+    it("should not show an image if there isn't one and not call revokeObjectURL when unmounted", () => {
+      const link = Object.assign({}, DEFAULT_PROPS.link);
+      delete link.image;
+
+      wrapper = shallow(<Card {...DEFAULT_PROPS} link={link} />);
+
+      assert.isNull(wrapper.state("cardImage"));
+      assert.lengthOf(wrapper.find(".card-preview-image"), 0);
+
+      wrapper.unmount();
+      assert.notCalled(url.revokeObjectURL);
+    });
+    it("should remove current card image if new image is not present", () => {
+      wrapper = shallow(<Card {...DEFAULT_PROPS} />);
+
+      const otherLink = Object.assign({}, DEFAULT_PROPS.link);
+      delete otherLink.image;
+      wrapper.setProps(Object.assign({}, DEFAULT_PROPS, {link: otherLink}));
+
+      assert.isNull(wrapper.state("cardImage"));
+    });
+    it("should not create or revoke urls if normal image is already in state", () => {
+      wrapper = shallow(<Card {...DEFAULT_PROPS} />);
+
+      wrapper.setProps(DEFAULT_PROPS);
+
+      assert.notCalled(url.createObjectURL);
+      assert.notCalled(url.revokeObjectURL);
+    });
+    it("should not create or revoke more urls if blob image is already in state", () => {
+      const link = Object.assign({}, DEFAULT_PROPS.link, {image: DEFAULT_BLOB_IMAGE});
+      wrapper = shallow(<Card {...DEFAULT_PROPS} link={link} />);
+
+      assert.calledOnce(url.createObjectURL);
+      assert.notCalled(url.revokeObjectURL);
+
+      wrapper.setProps(Object.assign({}, DEFAULT_PROPS, {link}));
+
+      assert.calledOnce(url.createObjectURL);
+      assert.notCalled(url.revokeObjectURL);
+    });
+    it("should create blob urls for new blobs and revoke existing ones", () => {
+      const link = Object.assign({}, DEFAULT_PROPS.link, {image: DEFAULT_BLOB_IMAGE});
+      wrapper = shallow(<Card {...DEFAULT_PROPS} link={link} />);
+
+      assert.calledOnce(url.createObjectURL);
+      assert.notCalled(url.revokeObjectURL);
+
+      const otherLink = Object.assign({}, DEFAULT_PROPS.link, {image: {path: "/newpath", data: new Blob([0])}});
+      wrapper.setProps(Object.assign({}, DEFAULT_PROPS, {link: otherLink}));
+
+      assert.calledTwice(url.createObjectURL);
+      assert.calledOnce(url.revokeObjectURL);
+    });
+    it("should not call createObjectURL and revokeObjectURL for normal images", () => {
+      wrapper = shallow(<Card {...DEFAULT_PROPS} />);
+
+      assert.notCalled(url.createObjectURL);
+      assert.notCalled(url.revokeObjectURL);
+
+      const otherLink = Object.assign({}, DEFAULT_PROPS.link, {image: "https://other/image"});
+      wrapper.setProps(Object.assign({}, DEFAULT_PROPS, {link: otherLink}));
+
+      assert.notCalled(url.createObjectURL);
+      assert.notCalled(url.revokeObjectURL);
+    });
+  });
+  describe("static isImageInState", () => {
+    it("should return true if both image and cardImage are not present", () => {
+      assert.isTrue(Card.isImageInState({cardImage: null}, null));
+    });
+    it("should return false if image is present and cardImage is not present", () => {
+      assert.isFalse(Card.isImageInState({cardImage: null}, {}));
+    });
+    it("should return false if image is not present and cardImage is present", () => {
+      assert.isFalse(Card.isImageInState({cardImage: {}}, null));
+    });
+    it("should return true if both image and cardImage are equal blobs", () => {
+      const blob = new Blob([0]);
+      assert.isTrue(Card.isImageInState({cardImage: {path: "/hello", data: blob}}, {path: "/hello", data: blob}));
+    });
+    it("should return false if both image and cardImage are different blobs", () => {
+      assert.isFalse(Card.isImageInState({cardImage: {path: "/different", data: new Blob([0])}}, {path: "/hello", data: new Blob([0])}));
+    });
+    it("should return true if both image and cardImage are equal images", () => {
+      assert.isTrue(Card.isImageInState({cardImage: {url: "test url"}}, "test url"));
+    });
+    it("should return false if both image and cardImage are different images", () => {
+      assert.isFalse(Card.isImageInState({cardImage: {url: "test url 1"}}, "test url 2"));
+    });
+  });
+  describe("image loading", () => {
+    let link;
+    let triggerImage = {};
+    let uniqueLink = 0;
+    beforeEach(() => {
+      global.Image.prototype = {
+        addEventListener(event, callback) {
+          triggerImage[event] = () => Promise.resolve(callback());
+        }
+      };
+
+      link = Object.assign({}, DEFAULT_PROPS.link);
+      link.image += uniqueLink++;
+      wrapper = shallow(<Card {...DEFAULT_PROPS} link={link} />);
+    });
+    it("should have a loaded preview image when the image is loaded", () => {
+      assert.isFalse(wrapper.find(".card-preview-image").hasClass("loaded"));
+
+      wrapper.setState({imageLoaded: true});
+
+      assert.isTrue(wrapper.find(".card-preview-image").hasClass("loaded"));
+    });
+    it("should start not loaded", () => {
+      assert.isFalse(wrapper.state("imageLoaded"));
+    });
+    it("should be loaded after load", async () => {
+      await triggerImage.load();
+
+      assert.isTrue(wrapper.state("imageLoaded"));
+    });
+    it("should be not be loaded after error ", async () => {
+      await triggerImage.error();
+
+      assert.isFalse(wrapper.state("imageLoaded"));
+    });
+    it("should be not be loaded if image changes", async () => {
+      await triggerImage.load();
+      const otherLink = Object.assign({}, link, {image: "https://other/image"});
+
+      wrapper.setProps(Object.assign({}, DEFAULT_PROPS, {link: otherLink}));
+
+      assert.isFalse(wrapper.state("imageLoaded"));
+    });
+  });
+  describe("placeholder=true", () => {
+    beforeEach(() => {
+      wrapper = mountWithIntl(<Card placeholder={true} />);
+    });
+    it("should render when placeholder=true", () => {
+      assert.ok(wrapper.exists());
+    });
+    it("should add a placeholder class to the outer element", () => {
+      assert.isTrue(wrapper.find(".card-outer").hasClass("placeholder"));
+    });
+    it("should not have a context menu button or LinkMenu", () => {
+      assert.isFalse(wrapper.find(".context-menu-button").exists(), "context menu button");
+      assert.isFalse(wrapper.find(LinkMenu).exists(), "LinkMenu");
+    });
+    it("should not call onLinkClick when the link is clicked", () => {
+      const spy = sinon.spy(wrapper.instance(), "onLinkClick");
+      const card = wrapper.find(".card");
+      card.simulate("click");
+      assert.notCalled(spy);
+    });
+  });
+  describe("#trackClick", () => {
+    it("should call dispatch when the link is clicked with the right data", () => {
+      const card = wrapper.find(".card");
+      const event = {altKey: "1", button: "2", ctrlKey: "3", metaKey: "4", shiftKey: "5"};
+      card.simulate("click", Object.assign({}, event, {preventDefault: () => {}}));
+      assert.calledThrice(DEFAULT_PROPS.dispatch);
+
+      // first dispatch call is the AlsoToMain message which will open a link in a window, and send some event data
+      assert.equal(DEFAULT_PROPS.dispatch.firstCall.args[0].type, at.OPEN_LINK);
+      assert.deepEqual(DEFAULT_PROPS.dispatch.firstCall.args[0].data.event, event);
+
+      // second dispatch call is a UserEvent action for telemetry
+      assert.isUserEventAction(DEFAULT_PROPS.dispatch.secondCall.args[0]);
+      assert.calledWith(DEFAULT_PROPS.dispatch.secondCall, ac.UserEvent({
+        event: "CLICK",
+        source: DEFAULT_PROPS.eventSource,
+        action_position: DEFAULT_PROPS.index
+      }));
+
+      // third dispatch call is to send impression stats
+      assert.calledWith(DEFAULT_PROPS.dispatch.thirdCall, ac.ImpressionStats({
+        source: DEFAULT_PROPS.eventSource,
+        click: 0,
+        tiles: [{id: DEFAULT_PROPS.link.guid, pos: DEFAULT_PROPS.index}]
+      }));
+    });
+    it("should provide card_type to telemetry info if type is not history", () => {
+      const link = Object.assign({}, DEFAULT_PROPS.link);
+      link.type = "bookmark";
+      wrapper = mountWithIntl(<Card {...Object.assign({}, DEFAULT_PROPS, {link})} />);
+      const card = wrapper.find(".card");
+      const event = {altKey: "1", button: "2", ctrlKey: "3", metaKey: "4", shiftKey: "5"};
+
+      card.simulate("click", Object.assign({}, event, {preventDefault: () => {}}));
+
+      assert.isUserEventAction(DEFAULT_PROPS.dispatch.secondCall.args[0]);
+      assert.calledWith(DEFAULT_PROPS.dispatch.secondCall, ac.UserEvent({
+        event: "CLICK",
+        source: DEFAULT_PROPS.eventSource,
+        action_position: DEFAULT_PROPS.index,
+        value: {card_type: link.type}
+      }));
+    });
+    it("should notify Web Extensions with WEBEXT_CLICK if props.isWebExtension is true", () => {
+      wrapper = mountCardWithProps(Object.assign({}, DEFAULT_PROPS, {isWebExtension: true, eventSource: "MyExtension", index: 3}));
+      const card = wrapper.find(".card");
+      const event = {preventDefault() {}};
+      card.simulate("click", event);
+      assert.calledWith(DEFAULT_PROPS.dispatch, ac.WebExtEvent(at.WEBEXT_CLICK, {
+        source: "MyExtension",
+        url: DEFAULT_PROPS.link.url,
+        action_position: 3
+      }));
+    });
+  });
+});
+
+describe("<PlaceholderCard />", () => {
+  it("should render a Card with placeholder=true", () => {
+    const wrapper = mountWithIntl(<Provider store={createStore(combineReducers(reducers), INITIAL_STATE)}><PlaceholderCard /></Provider>);
+    assert.isTrue(wrapper.find(Card).props().placeholder);
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/components/CollapsibleSection.test.jsx
@@ -0,0 +1,186 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {_CollapsibleSection as CollapsibleSection, Disclaimer} from "content-src/components/CollapsibleSection/CollapsibleSection";
+import {mountWithIntl, shallowWithIntl} from "test/unit/utils";
+import {ErrorBoundary} from "content-src/components/ErrorBoundary/ErrorBoundary";
+import React from "react";
+
+const DEFAULT_PROPS = {
+  id: "cool",
+  className: "cool-section",
+  title: "Cool Section",
+  prefName: "collapseSection",
+  disclaimer: {text: {id: "section_disclaimer_topstories_linktext"}, link: {id: "menu_action_remove_bookmark"}, button: {id: "search_button"}},
+  collapsed: false,
+  document: {
+    addEventListener: () => {},
+    removeEventListener: () => {},
+    visibilityState: "visible"
+  },
+  dispatch: () => {}
+};
+
+describe("CollapsibleSection", () => {
+  let wrapper;
+
+  function setup(props = {}) {
+    const customProps = Object.assign({}, DEFAULT_PROPS, props);
+    wrapper = mountWithIntl(<CollapsibleSection {...customProps}>foo</CollapsibleSection>);
+  }
+
+  beforeEach(() => setup());
+
+  it("should render the component", () => {
+    assert.ok(wrapper.exists());
+  });
+
+  it("should render an ErrorBoundary with class section-body-fallback", () => {
+    assert.equal(
+      wrapper.find(ErrorBoundary).first().prop("className"),
+      "section-body-fallback");
+  });
+
+  it("should have collapsed class if 'prefName' pref is true", () => {
+    setup({collapsed: true});
+    assert.ok(wrapper.find(".collapsible-section").first().hasClass("collapsed"));
+  });
+
+  it("should render disclaimer if not acknowledged", () => {
+    setup({Prefs: {values: {"section.cool.showDisclaimer": true}}});
+    assert.lengthOf(wrapper.find(".section-disclaimer"), 1);
+  });
+
+  it("should not render disclaimer if acknowledged", () => {
+    setup({Prefs: {values: {"section.cool.showDisclaimer": false}}});
+    assert.lengthOf(wrapper.find(".section-disclaimer"), 0);
+  });
+
+  it("should fire a pref change event when section title is clicked", done => {
+    function dispatch(a) {
+      if (a.type === at.UPDATE_SECTION_PREFS) {
+        assert.equal(a.data.id, DEFAULT_PROPS.id);
+        assert.equal(a.data.value.collapsed, true);
+        done();
+      }
+    }
+    setup({dispatch});
+    wrapper.find(".click-target").simulate("click");
+  });
+
+  it("should not fire a pref change when section title is clicked if sectionBody is falsy", () => {
+    const dispatch = sinon.spy();
+    setup({dispatch});
+    delete wrapper.find(CollapsibleSection).instance().sectionBody;
+
+    wrapper.find(".click-target").simulate("click");
+
+    assert.notCalled(dispatch);
+  });
+
+  it("should enable animations if the tab is visible", () => {
+    wrapper.instance().enableOrDisableAnimation();
+    assert.ok(wrapper.instance().state.enableAnimation);
+  });
+
+  it("should disable animations if the tab is in the background", () => {
+    const doc = Object.assign({}, DEFAULT_PROPS.document, {visibilityState: "hidden"});
+    setup({document: doc});
+    wrapper.instance().enableOrDisableAnimation();
+    assert.isFalse(wrapper.instance().state.enableAnimation);
+  });
+
+  describe("without collapsible pref", () => {
+    let dispatch;
+    beforeEach(() => {
+      dispatch = sinon.stub();
+      setup({collapsed: undefined, dispatch});
+    });
+    it("should render the section uncollapsed", () => {
+      assert.isFalse(wrapper.find(".collapsible-section").first().hasClass("collapsed"));
+    });
+
+    it("should not render the arrow if no collapsible pref exists for the section", () => {
+      assert.lengthOf(wrapper.find(".click-target .collapsible-arrow"), 0);
+    });
+
+    it("should not trigger a dispatch when the section title is clicked ", () => {
+      wrapper.find(".click-target").simulate("click");
+
+      assert.notCalled(dispatch);
+    });
+  });
+
+  describe("icon", () => {
+    it("should use the icon prop value as the url if it starts with `moz-extension://`", () => {
+      const icon = "moz-extension://some/extension/path";
+      setup({icon});
+      const props = wrapper.find(".icon").first().props();
+      assert.equal(props.style.backgroundImage, `url('${icon}')`);
+    });
+    it("should use set the icon-* class if a string that doesn't start with `moz-extension://` is provided", () => {
+      setup({icon: "cool"});
+      assert.ok(wrapper.find(".icon").first().hasClass("icon-cool"));
+    });
+    it("should use the icon `webextension` if no other is provided", () => {
+      setup({icon: undefined});
+      assert.ok(wrapper.find(".icon").first().hasClass("icon-webextension"));
+    });
+  });
+
+  describe("maxHeight", () => {
+    const maxHeight = "123px";
+    const setState = state => wrapper.setState(Object.assign({maxHeight}, state || {}));
+    const checkHeight = val => assert.equal(wrapper.find(".section-body").instance().style.maxHeight, val);
+
+    it("should have no max-height normally to avoid unexpected cropping", () => {
+      setState();
+
+      checkHeight("");
+    });
+    it("should have a max-height when animating open to a target height", () => {
+      setState({isAnimating: true});
+
+      checkHeight(maxHeight);
+    });
+    it("should not have a max-height when already collapsed", () => {
+      setup({collapsed: true});
+
+      checkHeight("");
+    });
+    it("should not have a max-height when animating closed to a css-set 0", () => {
+      setup({collapsed: true});
+      setState({isAnimating: true});
+
+      checkHeight("");
+    });
+  });
+});
+
+describe("<Disclaimer>", () => {
+  let wrapper;
+  const DISCLAIMER_PROPS = {
+    disclaimer: {text: {id: "text"}, link: {id: "link"}, button: {id: "button"}},
+    disclaimerPref: "section.test.showDisclaimer",
+    eventSource: "test"
+  };
+
+  function setup(props = {}) {
+    const customProps = Object.assign({}, DISCLAIMER_PROPS, props);
+    wrapper = shallowWithIntl(<Disclaimer {...customProps}>foo</Disclaimer>);
+  }
+
+  beforeEach(() => setup());
+
+  it("should render disclaimer", () => {
+    assert.lengthOf(wrapper.find(".section-disclaimer"), 1);
+  });
+
+  it("should send telemetry and set pref to acknowledge disclaimer when button is clicked", () => {
+    const dispatch = sinon.spy();
+    setup({dispatch});
+
+    wrapper.find(".section-disclaimer").childAt(1).simulate("click");
+    assert.calledTwice(dispatch);
+    assert.calledWith(dispatch.firstCall, ac.SetPref("section.test.showDisclaimer", false));
+    assert.calledWith(dispatch.secondCall, ac.UserEvent({event: "DISCLAIMER_ACKED", source: "test"}));
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/components/ComponentPerfTimer.test.jsx
@@ -0,0 +1,342 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {ComponentPerfTimer} from "content-src/components/ComponentPerfTimer/ComponentPerfTimer";
+import createMockRaf from "mock-raf";
+import React from "react";
+
+import {shallow} from "enzyme";
+
+const perfSvc = {
+  mark() {},
+  getMostRecentAbsMarkStartByName() {}
+};
+
+let DEFAULT_PROPS = {
+  initialized: true,
+  rows: [],
+  id: "highlights",
+  dispatch() {},
+  intl: {formatMessage: x => x},
+  perfSvc
+};
+
+describe("<ComponentPerfTimer>", () => {
+  let mockRaf;
+  let sandbox;
+  let wrapper;
+
+  const InnerEl = () => (<div>Inner Element</div>);
+
+  beforeEach(() => {
+    mockRaf = createMockRaf();
+    sandbox = sinon.sandbox.create();
+    sandbox.stub(window, "requestAnimationFrame").callsFake(mockRaf.raf);
+    wrapper = shallow(<ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>);
+  });
+  afterEach(() => {
+    sandbox.restore();
+  });
+
+  it("should render props.children", () => {
+    assert.ok(wrapper.contains(<InnerEl />));
+  });
+
+  describe("#constructor", () => {
+    beforeEach(() => {
+      sandbox.stub(ComponentPerfTimer.prototype, "_maybeSendBadStateEvent");
+      sandbox.stub(ComponentPerfTimer.prototype, "_ensureFirstRenderTsRecorded");
+      wrapper = shallow(<ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>, {disableLifecycleMethods: true});
+    });
+
+    it("should have the correct defaults", () => {
+      const instance = wrapper.instance();
+
+      assert.isFalse(instance._reportMissingData);
+      assert.isFalse(instance._timestampHandled);
+      assert.isFalse(instance._recordedFirstRender);
+    });
+  });
+
+  describe("#render", () => {
+    beforeEach(() => {
+      sandbox.stub(DEFAULT_PROPS, "id").value("fake_section");
+      sandbox.stub(ComponentPerfTimer.prototype, "_maybeSendBadStateEvent");
+      sandbox.stub(ComponentPerfTimer.prototype, "_ensureFirstRenderTsRecorded");
+      wrapper = shallow(<ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>);
+    });
+
+    it("should not call telemetry on sections that we don't want to record", () => {
+      const instance = wrapper.instance();
+
+      assert.notCalled(instance._maybeSendBadStateEvent);
+      assert.notCalled(instance._ensureFirstRenderTsRecorded);
+    });
+  });
+
+  describe("#_componentDidMount", () => {
+    it("should call _maybeSendPaintedEvent", () => {
+      const instance = wrapper.instance();
+      const stub = sandbox.stub(instance, "_maybeSendPaintedEvent");
+
+      instance.componentDidMount();
+
+      assert.calledOnce(stub);
+    });
+
+    it("should not call _maybeSendPaintedEvent if id not in RECORDED_SECTIONS", () => {
+      sandbox.stub(DEFAULT_PROPS, "id").value("topstories");
+      wrapper = shallow(<ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>);
+      const instance = wrapper.instance();
+      const stub = sandbox.stub(instance, "_maybeSendPaintedEvent");
+
+      instance.componentDidMount();
+
+      assert.notCalled(stub);
+    });
+  });
+
+  describe("#_componentDidUpdate", () => {
+    it("should call _maybeSendPaintedEvent", () => {
+      const instance = wrapper.instance();
+      const maybeSendPaintStub = sandbox.stub(instance, "_maybeSendPaintedEvent");
+
+      instance.componentDidUpdate();
+
+      assert.calledOnce(maybeSendPaintStub);
+    });
+
+    it("should not call _maybeSendPaintedEvent if id not in RECORDED_SECTIONS", () => {
+      sandbox.stub(DEFAULT_PROPS, "id").value("topstories");
+      wrapper = shallow(<ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>);
+      const instance = wrapper.instance();
+      const stub = sandbox.stub(instance, "_maybeSendPaintedEvent");
+
+      instance.componentDidUpdate();
+
+      assert.notCalled(stub);
+    });
+  });
+
+  describe("_ensureFirstRenderTsRecorded", () => {
+    let recordFirstRenderStub;
+    beforeEach(() => {
+      sandbox.stub(ComponentPerfTimer.prototype, "_maybeSendBadStateEvent");
+      recordFirstRenderStub = sandbox.stub(ComponentPerfTimer.prototype, "_ensureFirstRenderTsRecorded");
+    });
+
+    it("should set _recordedFirstRender", () => {
+      sandbox.stub(DEFAULT_PROPS, "initialized").value(false);
+      wrapper = shallow(<ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>);
+      const instance = wrapper.instance();
+
+      assert.isFalse(instance._recordedFirstRender);
+
+      recordFirstRenderStub.callThrough();
+      instance._ensureFirstRenderTsRecorded();
+
+      assert.isTrue(instance._recordedFirstRender);
+    });
+
+    it("should mark first_render_ts", () => {
+      sandbox.stub(DEFAULT_PROPS, "initialized").value(false);
+      wrapper = shallow(<ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>);
+      const instance = wrapper.instance();
+      const stub = sandbox.stub(perfSvc, "mark");
+
+      recordFirstRenderStub.callThrough();
+      instance._ensureFirstRenderTsRecorded();
+
+      assert.calledOnce(stub);
+      assert.calledWithExactly(stub, `${DEFAULT_PROPS.id}_first_render_ts`);
+    });
+  });
+
+  describe("#_maybeSendBadStateEvent", () => {
+    let sendBadStateStub;
+    beforeEach(() => {
+      sendBadStateStub = sandbox.stub(ComponentPerfTimer.prototype, "_maybeSendBadStateEvent");
+      sandbox.stub(ComponentPerfTimer.prototype, "_ensureFirstRenderTsRecorded");
+    });
+
+    it("should set this._reportMissingData=true when called with initialized === false", () => {
+      sandbox.stub(DEFAULT_PROPS, "initialized").value(false);
+      wrapper = shallow(<ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>);
+      const instance = wrapper.instance();
+
+      assert.isFalse(instance._reportMissingData);
+
+      sendBadStateStub.callThrough();
+      instance._maybeSendBadStateEvent();
+
+      assert.isTrue(instance._reportMissingData);
+    });
+
+    it("should call _sendBadStateEvent if initialized & other metrics have been recorded", () => {
+      const instance = wrapper.instance();
+      const stub = sandbox.stub(instance, "_sendBadStateEvent");
+      instance._reportMissingData = true;
+      instance._timestampHandled = true;
+      instance._recordedFirstRender = true;
+
+      sendBadStateStub.callThrough();
+      instance._maybeSendBadStateEvent();
+
+      assert.calledOnce(stub);
+      assert.isFalse(instance._reportMissingData);
+    });
+  });
+
+  describe("#_maybeSendPaintedEvent", () => {
+    it("should call _sendPaintedEvent if props.initialized is true", () => {
+      sandbox.stub(DEFAULT_PROPS, "initialized").value(true);
+      wrapper = shallow(
+        <ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>,
+        {disableLifecycleMethods: true});
+      const instance = wrapper.instance();
+      const stub = sandbox.stub(instance, "_afterFramePaint");
+
+      assert.isFalse(instance._timestampHandled);
+
+      instance._maybeSendPaintedEvent();
+
+      assert.calledOnce(stub);
+      assert.calledWithExactly(stub, instance._sendPaintedEvent);
+      assert.isTrue(wrapper.instance()._timestampHandled);
+    });
+    it("should not call _sendPaintedEvent if this._timestampHandled is true", () => {
+      const instance = wrapper.instance();
+      const spy = sinon.spy(instance, "_afterFramePaint");
+      instance._timestampHandled = true;
+
+      instance._maybeSendPaintedEvent();
+      spy.neverCalledWith(instance._sendPaintedEvent);
+    });
+    it("should not call _sendPaintedEvent if component not initialized", () => {
+      sandbox.stub(DEFAULT_PROPS, "initialized").value(false);
+      wrapper = shallow(<ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>);
+      const instance = wrapper.instance();
+      const spy = sinon.spy(instance, "_afterFramePaint");
+
+      instance._maybeSendPaintedEvent();
+
+      spy.neverCalledWith(instance._sendPaintedEvent);
+    });
+  });
+
+  describe("#_afterFramePaint", () => {
+    it("should call callback after the requestAnimationFrame callback returns", done => {
+      // Setting the callback to done is the test that it does finally get
+      // called at the correct time, after the event loop ticks again.
+      // If it doesn't get called, this test will time out.
+      this.callback = () => done();
+      sandbox.spy(this, "callback");
+
+      const instance = wrapper.instance();
+
+      instance._afterFramePaint(this.callback);
+
+      assert.notCalled(this.callback);
+      mockRaf.step({count: 1});
+    });
+  });
+
+  describe("#_sendBadStateEvent", () => {
+    it("should call perfSvc.mark", () => {
+      sandbox.spy(perfSvc, "mark");
+      const key = `${DEFAULT_PROPS.id}_data_ready_ts`;
+
+      wrapper.instance()._sendBadStateEvent();
+
+      assert.calledOnce(perfSvc.mark);
+      assert.calledWithExactly(perfSvc.mark, key);
+    });
+
+    it("should call compute the delta from first render to data ready", () => {
+      sandbox.stub(perfSvc, "getMostRecentAbsMarkStartByName");
+
+      wrapper.instance()._sendBadStateEvent(`${DEFAULT_PROPS.id}_data_ready_ts`);
+
+      assert.calledTwice(perfSvc.getMostRecentAbsMarkStartByName);
+      assert.calledWithExactly(perfSvc.getMostRecentAbsMarkStartByName, `${DEFAULT_PROPS.id}_data_ready_ts`);
+      assert.calledWithExactly(perfSvc.getMostRecentAbsMarkStartByName, `${DEFAULT_PROPS.id}_first_render_ts`);
+    });
+
+    it("should call dispatch SAVE_SESSION_PERF_DATA", () => {
+      sandbox.stub(perfSvc, "getMostRecentAbsMarkStartByName")
+        .withArgs("highlights_first_render_ts").returns(0.5)
+        .withArgs("highlights_data_ready_ts")
+        .returns(3.2);
+
+      const dispatch = sandbox.spy(DEFAULT_PROPS, "dispatch");
+      wrapper = shallow(<ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>);
+
+      wrapper.instance()._sendBadStateEvent();
+
+      assert.calledOnce(dispatch);
+      assert.calledWithExactly(dispatch, ac.OnlyToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: {[`${DEFAULT_PROPS.id}_data_late_by_ms`]: 2}
+      }));
+    });
+  });
+
+  describe("#_sendPaintedEvent", () => {
+    beforeEach(() => {
+      sandbox.stub(ComponentPerfTimer.prototype, "_maybeSendBadStateEvent");
+      sandbox.stub(ComponentPerfTimer.prototype, "_ensureFirstRenderTsRecorded");
+    });
+
+    it("should not call mark with the wrong id", () => {
+      sandbox.stub(perfSvc, "mark");
+      sandbox.stub(DEFAULT_PROPS, "id").value("fake_id");
+      wrapper = shallow(<ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>);
+
+      wrapper.instance()._sendPaintedEvent();
+
+      assert.notCalled(perfSvc.mark);
+    });
+    it("should call mark with the correct topsites", () => {
+      sandbox.stub(perfSvc, "mark");
+      sandbox.stub(DEFAULT_PROPS, "id").value("topsites");
+      wrapper = shallow(<ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>);
+
+      wrapper.instance()._sendPaintedEvent();
+
+      assert.calledOnce(perfSvc.mark);
+      assert.calledWithExactly(perfSvc.mark, "topsites_first_painted_ts");
+    });
+    it("should not call getMostRecentAbsMarkStartByName if id!=topsites", () => {
+      sandbox.stub(perfSvc, "getMostRecentAbsMarkStartByName");
+      sandbox.stub(DEFAULT_PROPS, "id").value("fake_id");
+      wrapper = shallow(<ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>);
+
+      wrapper.instance()._sendPaintedEvent();
+
+      assert.notCalled(perfSvc.getMostRecentAbsMarkStartByName);
+    });
+    it("should call getMostRecentAbsMarkStartByName for topsites", () => {
+      sandbox.stub(perfSvc, "getMostRecentAbsMarkStartByName");
+      sandbox.stub(DEFAULT_PROPS, "id").value("topsites");
+      wrapper = shallow(<ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>);
+
+      wrapper.instance()._sendPaintedEvent();
+
+      assert.calledOnce(perfSvc.getMostRecentAbsMarkStartByName);
+      assert.calledWithExactly(perfSvc.getMostRecentAbsMarkStartByName,
+                               "topsites_first_painted_ts");
+    });
+    it("should dispatch SAVE_SESSION_PERF_DATA", () => {
+      sandbox.stub(perfSvc, "getMostRecentAbsMarkStartByName").returns(42);
+      sandbox.stub(DEFAULT_PROPS, "id").value("topsites");
+      const dispatch = sandbox.spy(DEFAULT_PROPS, "dispatch");
+      wrapper = shallow(<ComponentPerfTimer {...DEFAULT_PROPS}><InnerEl /></ComponentPerfTimer>);
+
+      wrapper.instance()._sendPaintedEvent();
+
+      assert.calledOnce(dispatch);
+      assert.calledWithExactly(dispatch, ac.OnlyToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: {"topsites_first_painted_ts": 42}
+      }));
+    });
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/components/ConfirmDialog.test.jsx
@@ -0,0 +1,150 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {_ConfirmDialog as ConfirmDialog} from "content-src/components/ConfirmDialog/ConfirmDialog";
+import {FormattedMessage} from "react-intl";
+import React from "react";
+import {shallowWithIntl} from "test/unit/utils";
+
+describe("<ConfirmDialog>", () => {
+  let wrapper;
+  let dispatch;
+  let ConfirmDialogProps;
+  beforeEach(() => {
+    dispatch = sinon.stub();
+    ConfirmDialogProps = {
+      visible: true,
+      data: {
+        onConfirm: [],
+        cancel_button_string_id: "manual_migration_cancel_button",
+        confirm_button_string_id: "manual_migration_import_button",
+        eventSource: "HIGHLIGHTS"
+      }
+    };
+    wrapper = shallowWithIntl(<ConfirmDialog dispatch={dispatch} {...ConfirmDialogProps} />);
+  });
+  it("should render an overlay", () => {
+    assert.ok(wrapper.find(".modal-overlay").exists());
+  });
+  it("should render a modal", () => {
+    assert.ok(wrapper.find(".confirmation-dialog").exists());
+  });
+  it("should not render if visible is false", () => {
+    ConfirmDialogProps.visible = false;
+    wrapper = shallowWithIntl(<ConfirmDialog dispatch={dispatch} {...ConfirmDialogProps} />);
+
+    assert.lengthOf(wrapper.find(".confirmation-dialog"), 0);
+  });
+  it("should display an icon if we provide one in props", () => {
+    const iconName = "modal-icon";
+    // If there is no icon in the props, we shouldn't display an icon
+    assert.lengthOf(wrapper.find(`.icon-${iconName}`), 0);
+
+    ConfirmDialogProps.data.icon = iconName;
+    wrapper = shallowWithIntl(<ConfirmDialog dispatch={dispatch} {...ConfirmDialogProps} />);
+
+    // But if we do provide an icon - we should show it
+    assert.lengthOf(wrapper.find(`.icon-${iconName}`), 1);
+  });
+  describe("intl message check", () => {
+    it("should render the message body sent via props", () => {
+      Object.assign(ConfirmDialogProps.data, {body_string_id: ["foo", "bar"]});
+      wrapper = shallowWithIntl(<ConfirmDialog dispatch={dispatch} {...ConfirmDialogProps} />);
+
+      let msgs = wrapper.find(".modal-message").find(FormattedMessage);
+      assert.equal(msgs.length, ConfirmDialogProps.data.body_string_id.length);
+
+      msgs.forEach((fm, i) => assert.equal(fm.props().id, ConfirmDialogProps.data.body_string_id[i]));
+    });
+    it("should render the correct primary button text", () => {
+      Object.assign(ConfirmDialogProps.data, {confirm_button_string_id: "primary_foo"});
+      wrapper = shallowWithIntl(<ConfirmDialog dispatch={dispatch} {...ConfirmDialogProps} />);
+
+      let doneLabel = wrapper.find(".actions").childAt(1).find(FormattedMessage);
+      assert.ok(doneLabel.exists());
+      assert.equal(doneLabel.props().id, ConfirmDialogProps.data.confirm_button_string_id);
+    });
+  });
+  describe("click events", () => {
+    it("should emit AlsoToMain DIALOG_CANCEL when you click the overlay", () => {
+      let overlay = wrapper.find(".modal-overlay");
+
+      assert.ok(overlay.exists());
+      overlay.simulate("click");
+
+      // Two events are emitted: UserEvent+AlsoToMain.
+      assert.calledTwice(dispatch);
+      assert.propertyVal(dispatch.firstCall.args[0], "type", at.DIALOG_CANCEL);
+      assert.calledWith(dispatch, {type: at.DIALOG_CANCEL});
+    });
+    it("should emit UserEvent DIALOG_CANCEL when you click the overlay", () => {
+      let overlay = wrapper.find(".modal-overlay");
+
+      assert.ok(overlay);
+      overlay.simulate("click");
+
+      // Two events are emitted: UserEvent+AlsoToMain.
+      assert.calledTwice(dispatch);
+      assert.isUserEventAction(dispatch.secondCall.args[0]);
+      assert.calledWith(dispatch, ac.UserEvent({event: at.DIALOG_CANCEL, source: "HIGHLIGHTS"}));
+    });
+    it("should emit AlsoToMain DIALOG_CANCEL on cancel", () => {
+      let cancelButton = wrapper.find(".actions").childAt(0);
+
+      assert.ok(cancelButton);
+      cancelButton.simulate("click");
+
+      // Two events are emitted: UserEvent+AlsoToMain.
+      assert.calledTwice(dispatch);
+      assert.propertyVal(dispatch.firstCall.args[0], "type", at.DIALOG_CANCEL);
+      assert.calledWith(dispatch, {type: at.DIALOG_CANCEL});
+    });
+    it("should emit UserEvent DIALOG_CANCEL on cancel", () => {
+      let cancelButton = wrapper.find(".actions").childAt(0);
+
+      assert.ok(cancelButton);
+      cancelButton.simulate("click");
+
+      // Two events are emitted: UserEvent+AlsoToMain.
+      assert.calledTwice(dispatch);
+      assert.isUserEventAction(dispatch.secondCall.args[0]);
+      assert.calledWith(dispatch, ac.UserEvent({event: at.DIALOG_CANCEL, source: "HIGHLIGHTS"}));
+    });
+    it("should emit UserEvent on primary button", () => {
+      Object.assign(ConfirmDialogProps.data, {
+        body_string_id: ["foo", "bar"],
+        onConfirm: [
+          ac.AlsoToMain({type: at.DELETE_URL, data: "foo.bar"}),
+          ac.UserEvent({event: "DELETE"})
+        ]
+      });
+      wrapper = shallowWithIntl(<ConfirmDialog dispatch={dispatch} {...ConfirmDialogProps} />);
+      let doneButton = wrapper.find(".actions").childAt(1);
+
+      assert.ok(doneButton);
+      doneButton.simulate("click");
+
+      // Two events are emitted: UserEvent+AlsoToMain.
+      assert.isUserEventAction(dispatch.secondCall.args[0]);
+
+      assert.calledTwice(dispatch);
+      assert.calledWith(dispatch, ConfirmDialogProps.data.onConfirm[1]);
+    });
+    it("should emit AlsoToMain on primary button", () => {
+      Object.assign(ConfirmDialogProps.data, {
+        body_string_id: ["foo", "bar"],
+        onConfirm: [
+          ac.AlsoToMain({type: at.DELETE_URL, data: "foo.bar"}),
+          ac.UserEvent({event: "DELETE"})
+        ]
+      });
+      wrapper = shallowWithIntl(<ConfirmDialog dispatch={dispatch} {...ConfirmDialogProps} />);
+      let doneButton = wrapper.find(".actions").childAt(1);
+
+      assert.ok(doneButton);
+      doneButton.simulate("click");
+
+      // Two events are emitted: UserEvent+AlsoToMain.
+      assert.calledTwice(dispatch);
+      assert.calledWith(dispatch, ConfirmDialogProps.data.onConfirm[0]);
+    });
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/components/ContextMenu.test.jsx
@@ -0,0 +1,55 @@
+import {ContextMenu, ContextMenuItem} from "content-src/components/ContextMenu/ContextMenu";
+import {mount, shallow} from "enzyme";
+import React from "react";
+
+const DEFAULT_PROPS = {
+  onUpdate: () => {},
+  options: [],
+  tabbableOptionsLength: 0
+};
+
+describe("<ContextMenu>", () => {
+  it("should render all the options provided", () => {
+    const options = [{label: "item1"}, {type: "separator"}, {label: "item2"}];
+    const wrapper = shallow(<ContextMenu {...DEFAULT_PROPS} options={options} />);
+    assert.lengthOf(wrapper.find(".context-menu-list").children(), 3);
+  });
+  it("should not add a link for a separator", () => {
+    const options = [{label: "item1"}, {type: "separator"}];
+    const wrapper = shallow(<ContextMenu {...DEFAULT_PROPS} options={options} />);
+    assert.lengthOf(wrapper.find(".separator"), 1);
+  });
+  it("should add a link for all types that are not separators", () => {
+    const options = [{label: "item1"}, {type: "separator"}];
+    const wrapper = shallow(<ContextMenu {...DEFAULT_PROPS} options={options} />);
+    assert.lengthOf(wrapper.find(ContextMenuItem), 1);
+  });
+  it("should add an icon to items that need icons", () => {
+    const options = [{label: "item1", icon: "icon1"}, {type: "separator"}];
+    const wrapper = mount(<ContextMenu {...DEFAULT_PROPS} options={options} />);
+    assert.lengthOf(wrapper.find(".icon-icon1"), 1);
+  });
+  it("should be tabbable", () => {
+    const options = [{label: "item1", icon: "icon1"}, {type: "separator"}];
+    const wrapper = mount(<ContextMenu {...DEFAULT_PROPS} options={options} />);
+    assert.equal(wrapper.find(".context-menu-item").props().role, "menuitem");
+  });
+  it("should call onUpdate with false when an option is clicked", () => {
+    const onUpdate = sinon.spy();
+    const onClick = sinon.spy();
+    const wrapper = mount(<ContextMenu {...DEFAULT_PROPS} onUpdate={onUpdate} options={[{label: "item1", onClick}]} />);
+    wrapper.find(".context-menu-item a").simulate("click");
+    assert.calledOnce(onUpdate);
+    assert.calledOnce(onClick);
+  });
+  it("should not have disabled className by default", () => {
+    const options = [{label: "item1", icon: "icon1"}, {type: "separator"}];
+    const wrapper = mount(<ContextMenu {...DEFAULT_PROPS} options={options} />);
+    assert.lengthOf(wrapper.find(".context-menu-item a.disabled"), 0);
+  });
+  it("should add disabled className to any disabled options", () => {
+    const options = [{label: "item1", icon: "icon1", disabled: true}, {type: "separator"}];
+    const wrapper = mount(<ContextMenu {...DEFAULT_PROPS} options={options} />);
+    assert.lengthOf(wrapper.find(".context-menu-item a.disabled"), 1);
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/components/ErrorBoundary.test.jsx
@@ -0,0 +1,103 @@
+import {ErrorBoundary, ErrorBoundaryFallback} from "content-src/components/ErrorBoundary/ErrorBoundary";
+import {FormattedMessage} from "react-intl";
+import React from "react";
+import {shallow} from "enzyme";
+
+describe("<ErrorBoundary>", () => {
+  it("should render its children if componentDidCatch wasn't called", () => {
+    const wrapper = shallow(<ErrorBoundary ><div className="kids" /></ErrorBoundary>);
+
+    assert.lengthOf(wrapper.find(".kids"), 1);
+  });
+
+  it("should render ErrorBoundaryFallback if componentDidCatch called", () => {
+    const wrapper = shallow(<ErrorBoundary />);
+
+    wrapper.instance().componentDidCatch();
+    // since shallow wrappers don't automatically manage lifecycle semantics:
+    wrapper.update();
+
+    assert.lengthOf(wrapper.find(ErrorBoundaryFallback), 1);
+  });
+
+  it("should render the given FallbackComponent if componentDidCatch called", () => {
+    class TestFallback extends React.PureComponent {
+      render() {
+        return <div className="my-fallback">doh!</div>;
+      }
+    }
+
+    const wrapper = shallow(<ErrorBoundary FallbackComponent={TestFallback} />);
+    wrapper.instance().componentDidCatch();
+    // since shallow wrappers don't automatically manage lifecycle semantics:
+    wrapper.update();
+
+    assert.lengthOf(wrapper.find(TestFallback), 1);
+  });
+
+  it("should pass the given className prop to the FallbackComponent", () => {
+    class TestFallback extends React.PureComponent {
+      render() {
+        return <div className={this.props.className}>doh!</div>;
+      }
+    }
+
+    const wrapper = shallow(
+      <ErrorBoundary FallbackComponent={TestFallback} className="sheep" />);
+    wrapper.instance().componentDidCatch();
+    // since shallow wrappers don't automatically manage lifecycle semantics:
+    wrapper.update();
+
+    assert.lengthOf(wrapper.find(".sheep"), 1);
+  });
+});
+
+describe("ErrorBoundaryFallback", () => {
+  it("should render a <div> with a class of as-error-fallback", () => {
+    const wrapper = shallow(<ErrorBoundaryFallback />);
+
+    assert.lengthOf(wrapper.find("div.as-error-fallback"), 1);
+  });
+
+  it("should render a <div> with the props.className and .as-error-fallback", () => {
+    const wrapper = shallow(<ErrorBoundaryFallback className="monkeys" />);
+
+    assert.lengthOf(wrapper.find("div.monkeys.as-error-fallback"), 1);
+  });
+
+  it("should call window.location.reload(true) if .reload-button clicked", () => {
+    const fakeWindow = {location: {reload: sinon.spy()}};
+    const wrapper = shallow(<ErrorBoundaryFallback windowObj={fakeWindow} />);
+
+    wrapper.find(".reload-button").simulate("click");
+
+    assert.calledOnce(fakeWindow.location.reload);
+    assert.calledWithExactly(fakeWindow.location.reload, true);
+  });
+
+  it("should render .reload-button as an <a> element with an href attr", () => {
+    const wrapper = shallow(<ErrorBoundaryFallback />);
+
+    assert.lengthOf(wrapper.find(".reload-button[href]"), 1);
+  });
+
+  it("should render error_fallback_default_refresh_suggestion FormattedMessage",
+    () => {
+      const wrapper = shallow(<ErrorBoundaryFallback />);
+
+      const msgWrapper =
+        wrapper.find('[id="error_fallback_default_refresh_suggestion"]');
+      assert.lengthOf(msgWrapper, 1);
+      assert.isTrue(msgWrapper.is(FormattedMessage));
+    });
+
+  it("should render error_fallback_default_info FormattedMessage",
+    () => {
+      const wrapper = shallow(<ErrorBoundaryFallback />);
+
+      const msgWrapper =
+        wrapper.find('[id="error_fallback_default_info"]');
+      assert.lengthOf(msgWrapper, 1);
+      assert.isTrue(msgWrapper.is(FormattedMessage));
+    });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/components/LinkMenu.test.jsx
@@ -0,0 +1,284 @@
+import {ContextMenu} from "content-src/components/ContextMenu/ContextMenu";
+import {IntlProvider} from "react-intl";
+import {_LinkMenu as LinkMenu} from "content-src/components/LinkMenu/LinkMenu";
+import React from "react";
+import {shallow} from "enzyme";
+import {shallowWithIntl} from "test/unit/utils";
+
+const messages = require("data/locales.json")["en-US"]; // eslint-disable-line import/no-commonjs
+
+describe("<LinkMenu>", () => {
+  let wrapper;
+  beforeEach(() => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: ""}} options={["CheckPinTopSite", "CheckBookmark", "OpenInNewWindow"]} dispatch={() => {}} />);
+  });
+  it("should render a ContextMenu element", () => {
+    assert.ok(wrapper.find(ContextMenu).exists());
+  });
+  it("should pass onUpdate, and options to ContextMenu", () => {
+    assert.ok(wrapper.find(ContextMenu).exists());
+    const contextMenuProps = wrapper.find(ContextMenu).props();
+    ["onUpdate", "options"].forEach(prop => assert.property(contextMenuProps, prop));
+  });
+  it("should give ContextMenu the correct tabbable options length for a11y", () => {
+    const {options} = wrapper.find(ContextMenu).props();
+    const [firstItem] = options;
+    const lastItem = options[options.length - 1];
+
+    // first item should have {first: true}
+    assert.isTrue(firstItem.first);
+    assert.ok(!firstItem.last);
+
+    // last item should have {last: true}
+    assert.isTrue(lastItem.last);
+    assert.ok(!lastItem.first);
+
+    // middle items should have neither
+    for (let i = 1; i < options.length - 1; i++) {
+      assert.ok(!options[i].first && !options[i].last);
+    }
+  });
+  it("should show the correct options for default sites", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", isDefault: true}} options={["CheckBookmark"]} source={"TOP_SITES"} isPrivateBrowsingEnabled={true} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    let i = 0;
+    assert.propertyVal(options[i++], "id", "menu_action_pin");
+    assert.propertyVal(options[i++], "id", "edit_topsites_button_text");
+    assert.propertyVal(options[i++], "type", "separator");
+    assert.propertyVal(options[i++], "id", "menu_action_open_new_window");
+    assert.propertyVal(options[i++], "id", "menu_action_open_private_window");
+    assert.propertyVal(options[i++], "type", "separator");
+    assert.propertyVal(options[i++], "id", "menu_action_dismiss");
+    assert.propertyVal(options, "length", i);
+    // Double check that delete options are not included for default top sites
+    options.filter(o => o.type !== "separator").forEach(o => {
+      assert.notInclude(["menu_action_delete"], o.id);
+    });
+  });
+  it("should show Unpin option for a pinned site if CheckPinTopSite in options list", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", isPinned: true}} source={"TOP_SITES"} options={["CheckPinTopSite"]} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_unpin")));
+  });
+  it("should show Pin option for an unpinned site if CheckPinTopSite in options list", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", isPinned: false}} source={"TOP_SITES"} options={["CheckPinTopSite"]} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_pin")));
+  });
+  it("should show Unbookmark option for a bookmarked site if CheckBookmark in options list", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", bookmarkGuid: 1234}} source={"TOP_SITES"} options={["CheckBookmark"]} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_remove_bookmark")));
+  });
+  it("should show Bookmark option for an unbookmarked site if CheckBookmark in options list", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", bookmarkGuid: 0}} source={"TOP_SITES"} options={["CheckBookmark"]} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_bookmark")));
+  });
+  it("should show Save to Pocket option for an unsaved Pocket item if CheckSavedToPocket in options list", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", bookmarkGuid: 0}} source={"HIGHLIGHTS"} options={["CheckSavedToPocket"]} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_save_to_pocket")));
+  });
+  it("should show Delete from Pocket option for a saved Pocket item if CheckSavedToPocket in options list", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", pocket_id: 1234}} source={"HIGHLIGHTS"} options={["CheckSavedToPocket"]} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_delete_pocket")));
+  });
+  it("should show Archive from Pocket option for a saved Pocket item if CheckBookmarkOrArchive", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", pocket_id: 1234}} source={"HIGHLIGHTS"} options={["CheckBookmarkOrArchive"]} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_archive_pocket")));
+  });
+  it("should show Bookmark option for an unbookmarked site if CheckBookmarkOrArchive in options list and no pocket_id", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: ""}} source={"HIGHLIGHTS"} options={["CheckBookmarkOrArchive"]} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_bookmark")));
+  });
+  it("should show Unbookmark option for a bookmarked site if CheckBookmarkOrArchive in options list and no pocket_id", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", bookmarkGuid: 1234}} source={"HIGHLIGHTS"} options={["CheckBookmarkOrArchive"]} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_remove_bookmark")));
+  });
+  it("should show Open File option for a downloaded item", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", type: "download", path: "foo"}} source={"HIGHLIGHTS"} options={["OpenFile"]} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_open_file")));
+  });
+  it("should show Show File option for a downloaded item on a default platform", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", type: "download", path: "foo"}} source={"HIGHLIGHTS"} options={["ShowFile"]} platform={"default"} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_show_file_default")));
+  });
+  it("should show Show in Finder option for a downloaded item on a mac", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", type: "download"}} source={"HIGHLIGHTS"} options={["ShowFile"]} platform={"macosx"} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_show_file_mac_os")));
+  });
+  it("should show Open containing folder option for a downloaded item on windows", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", type: "download"}} source={"HIGHLIGHTS"} options={["ShowFile"]} platform={"win"} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_show_file_windows")));
+  });
+  it("should show Open containing folder option for a downloaded item on linux", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", type: "download"}} source={"HIGHLIGHTS"} options={["ShowFile"]} platform={"linux"} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_show_file_linux")));
+  });
+  it("should show Copy Downlad Link option for a downloaded item when CopyDownloadLink", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", type: "download"}} source={"HIGHLIGHTS"} options={["CopyDownloadLink"]} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_copy_download_link")));
+  });
+  it("should show Go To Download Page option for a downloaded item when GoToDownloadPage", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", type: "download", referrer: "foo"}} source={"HIGHLIGHTS"} options={["GoToDownloadPage"]} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_go_to_download_page")));
+    assert.isFalse(options[0].disabled);
+  });
+  it("should show Go To Download Page option as disabled for a downloaded item when GoToDownloadPage if no referrer exists", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", type: "download", referrer: null}} source={"HIGHLIGHTS"} options={["GoToDownloadPage"]} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_go_to_download_page")));
+    assert.isTrue(options[0].disabled);
+  });
+  it("should show Remove Download Link option for a downloaded item when RemoveDownload", () => {
+    wrapper = shallowWithIntl(<LinkMenu site={{url: "", type: "download"}} source={"HIGHLIGHTS"} options={["RemoveDownload"]} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "menu_action_remove_download")));
+  });
+  it("should show Edit option", () => {
+    const props = {url: "foo", label: "label"};
+    const index = 5;
+    wrapper = shallowWithIntl(<LinkMenu site={props} index={5} source={"TOP_SITES"} options={["EditTopSite"]} dispatch={() => {}} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    const option = options.find(o => (o.id && o.id === "edit_topsites_button_text"));
+    assert.isDefined(option);
+    assert.equal(option.action.data.index, index);
+  });
+  it("should call intl.formatMessage with the correct string ids", () => {
+    const FAKE_OPTIONS = ["AddBookmark", "OpenInNewWindow"];
+    const intlProvider = new IntlProvider({locale: "en", messages});
+    const {intl} = intlProvider.getChildContext();
+    const spy = sinon.spy(intl, "formatMessage");
+
+    // Identical to calling shallowWithIntl, but passing in the mocked intl object
+    const node = <LinkMenu site={{url: ""}} options={FAKE_OPTIONS} dispatch={() => {}} />;
+    shallow(React.cloneElement(node, {intl}), {context: {intl}});
+
+    // Called once for each option in the menu
+    assert.ok(spy.callCount === FAKE_OPTIONS.length);
+
+    // Called with correct ids both times
+    assert.ok(spy.firstCall.calledWith(sinon.match({id: "menu_action_bookmark"})));
+    assert.ok(spy.secondCall.calledWith(sinon.match({id: "menu_action_open_new_window"})));
+  });
+  describe(".onClick", () => {
+    const FAKE_INDEX = 3;
+    const FAKE_SOURCE = "TOP_SITES";
+    const FAKE_SITE = {
+      bookmarkGuid: 1234,
+      hostname: "foo",
+      path: "foo",
+      pocket_id: "1234",
+      referrer: "https://foo.com/ref",
+      title: "bar",
+      type: "bookmark",
+      typedBonus: true,
+      url: "https://foo.com"
+    };
+    const dispatch = sinon.stub();
+    const propOptions = ["ShowFile", "CopyDownloadLink", "GoToDownloadPage", "RemoveDownload", "Separator", "RemoveBookmark", "AddBookmark", "OpenInNewWindow", "OpenInPrivateWindow", "BlockUrl", "DeleteUrl", "PinTopSite", "UnpinTopSite", "SaveToPocket", "DeleteFromPocket", "ArchiveFromPocket", "WebExtDismiss"];
+    const expectedActionData = {
+      menu_action_remove_bookmark: FAKE_SITE.bookmarkGuid,
+      menu_action_bookmark: {url: FAKE_SITE.url, title: FAKE_SITE.title, type: FAKE_SITE.type},
+      menu_action_open_new_window: {url: FAKE_SITE.url, referrer: FAKE_SITE.referrer, typedBonus: FAKE_SITE.typedBonus},
+      menu_action_open_private_window: {url: FAKE_SITE.url, referrer: FAKE_SITE.referrer},
+      menu_action_dismiss: {url: FAKE_SITE.url, pocket_id: FAKE_SITE.pocket_id},
+      menu_action_webext_dismiss: {source: "TOP_SITES", url: FAKE_SITE.url, action_position: 3},
+      menu_action_delete: {url: FAKE_SITE.url, pocket_id: FAKE_SITE.pocket_id, forceBlock: FAKE_SITE.bookmarkGuid},
+      menu_action_pin: {site: {url: FAKE_SITE.url}, index: FAKE_INDEX},
+      menu_action_unpin: {site: {url: FAKE_SITE.url}},
+      menu_action_save_to_pocket: {site: {url: FAKE_SITE.url, title: FAKE_SITE.title}},
+      menu_action_delete_pocket: {pocket_id: "1234"},
+      menu_action_archive_pocket: {pocket_id: "1234"},
+      menu_action_show_file_default: {url: FAKE_SITE.url},
+      menu_action_copy_download_link: {url: FAKE_SITE.url},
+      menu_action_go_to_download_page: {url: FAKE_SITE.referrer},
+      menu_action_remove_download: {url: FAKE_SITE.url}
+    };
+
+    const {options} = shallowWithIntl(<LinkMenu
+      site={FAKE_SITE}
+      siteInfo={{value: {card_type: FAKE_SITE.type}}}
+      dispatch={dispatch}
+      index={FAKE_INDEX}
+      isPrivateBrowsingEnabled={true}
+      platform={"default"}
+      options={propOptions}
+      source={FAKE_SOURCE}
+      shouldSendImpressionStats={true} />)
+      .find(ContextMenu).props();
+    afterEach(() => dispatch.reset());
+    options.filter(o => o.type !== "separator").forEach(option => {
+      it(`should fire a ${option.action.type} action for ${option.id} with the expected data`, () => {
+        option.onClick();
+
+        if (option.impression && option.userEvent) {
+          assert.calledThrice(dispatch);
+        } else if (option.impression || option.userEvent) {
+          assert.calledTwice(dispatch);
+        } else {
+          assert.calledOnce(dispatch);
+        }
+
+        // option.action is dispatched
+        assert.ok(dispatch.firstCall.calledWith(option.action));
+
+        // option.action has correct data
+        // (delete is a special case as it dispatches a nested DIALOG_OPEN-type action)
+        // in the case of this FAKE_SITE, we send a bookmarkGuid therefore we also want
+        // to block this if we delete it
+        if (option.id === "menu_action_delete") {
+          assert.deepEqual(option.action.data.onConfirm[0].data, expectedActionData[option.id]);
+          // Test UserEvent send correct meta about item deleted
+          assert.propertyVal(option.action.data.onConfirm[1].data, "action_position", FAKE_INDEX);
+          assert.propertyVal(option.action.data.onConfirm[1].data, "source", FAKE_SOURCE);
+        } else {
+          assert.deepEqual(option.action.data, expectedActionData[option.id]);
+        }
+      });
+      it(`should fire a UserEvent action for ${option.id} if configured`, () => {
+        if (option.userEvent) {
+          option.onClick();
+          const [action] = dispatch.secondCall.args;
+          assert.isUserEventAction(action);
+          assert.propertyVal(action.data, "source", FAKE_SOURCE);
+          assert.propertyVal(action.data, "action_position", FAKE_INDEX);
+          assert.propertyVal(action.data.value, "card_type", FAKE_SITE.type);
+        }
+      });
+      it(`should send impression stats for ${option.id}`, () => {
+        if (option.impression) {
+          option.onClick();
+          const [action] = dispatch.thirdCall.args;
+          assert.deepEqual(action, option.impression);
+        }
+      });
+    });
+    it(`should not send impression stats if not configured`, () => {
+      const fakeOptions = shallowWithIntl(<LinkMenu site={FAKE_SITE} dispatch={dispatch} index={FAKE_INDEX} options={propOptions} source={FAKE_SOURCE} shouldSendImpressionStats={false} />)
+        .find(ContextMenu).props().options;
+
+      fakeOptions.filter(o => o.type !== "separator").forEach(option => {
+        if (option.impression) {
+          option.onClick();
+          assert.calledTwice(dispatch);
+          assert.notEqual(dispatch.firstCall.args[0], option.impression);
+          assert.notEqual(dispatch.secondCall.args[0], option.impression);
+          dispatch.reset();
+        }
+      });
+    });
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/components/ManualMigration.test.jsx
@@ -0,0 +1,58 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {FormattedMessage} from "react-intl";
+import {_ManualMigration as ManualMigration} from "content-src/components/ManualMigration/ManualMigration";
+import React from "react";
+import {shallowWithIntl} from "test/unit/utils";
+
+describe("<ManualMigration>", () => {
+  let wrapper;
+  let dispatch;
+  beforeEach(() => {
+    dispatch = sinon.stub();
+    wrapper = shallowWithIntl(<ManualMigration dispatch={dispatch} />);
+  });
+  it("should render the component", () => {
+    assert.isNotNull(wrapper.getElement());
+  });
+  it("should render correct intl string", () => {
+    const fm = wrapper.find("p").find(FormattedMessage);
+
+    assert.isNotNull(fm.getElement());
+    assert.equal(fm.props().id, "manual_migration_explanation2");
+  });
+  describe("actions", () => {
+    it("should render two buttons", () => {
+      assert.equal(wrapper.find(".actions").children().length, 2);
+    });
+    it("should render correct intl string", () => {
+      const fm = wrapper.find(".actions").childAt(0).find(FormattedMessage);
+
+      assert.isNotNull(fm.getElement());
+      assert.equal(fm.props().id, "manual_migration_cancel_button");
+    });
+    it("should render correct intl string", () => {
+      const fm = wrapper.find(".actions").childAt(1).find(FormattedMessage);
+
+      assert.isNotNull(fm.getElement());
+      assert.equal(fm.props().id, "manual_migration_import_button");
+    });
+    it("cancel btn should dispatch correct events", () => {
+      const cancelBtn = wrapper.find(".actions").childAt(0);
+
+      cancelBtn.simulate("click");
+
+      assert.calledTwice(dispatch);
+      assert.calledWith(dispatch, ac.AlsoToMain({type: at.MIGRATION_CANCEL}));
+      assert.calledWith(dispatch, ac.UserEvent({event: at.MIGRATION_CANCEL}));
+    });
+    it("import btn should dispatch correct events", () => {
+      const cancelBtn = wrapper.find(".actions").childAt(1);
+
+      cancelBtn.simulate("click");
+
+      assert.calledTwice(dispatch);
+      assert.calledWith(dispatch, ac.AlsoToMain({type: at.MIGRATION_START}));
+      assert.calledWith(dispatch, ac.UserEvent({event: at.MIGRATION_START}));
+    });
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/components/Search.test.jsx
@@ -0,0 +1,76 @@
+import {GlobalOverrider, mountWithIntl, shallowWithIntl} from "test/unit/utils";
+import React from "react";
+import {_Search as Search} from "content-src/components/Search/Search";
+
+const DEFAULT_PROPS = {dispatch() {}};
+
+describe("<Search>", () => {
+  let globals;
+  let sandbox;
+  beforeEach(() => {
+    globals = new GlobalOverrider();
+    sandbox = globals.sandbox;
+
+    global.ContentSearchUIController.prototype = {search: sandbox.spy()};
+  });
+  afterEach(() => {
+    globals.restore();
+  });
+
+  it("should render a Search element", () => {
+    const wrapper = shallowWithIntl(<Search {...DEFAULT_PROPS} />);
+    assert.ok(wrapper.exists());
+  });
+  it("should not use a <form> element", () => {
+    const wrapper = mountWithIntl(<Search {...DEFAULT_PROPS} />);
+
+    assert.equal(wrapper.find("form").length, 0);
+  });
+  it("should listen for ContentSearchClient on render", () => {
+    const spy = globals.set("addEventListener", sandbox.spy());
+
+    const wrapper = mountWithIntl(<Search {...DEFAULT_PROPS} />);
+
+    assert.calledOnce(spy.withArgs("ContentSearchClient", wrapper.instance()));
+  });
+  it("should stop listening for ContentSearchClient on unmount", () => {
+    const spy = globals.set("removeEventListener", sandbox.spy());
+    const wrapper = mountWithIntl(<Search {...DEFAULT_PROPS} />);
+    // cache the instance as we can't call this method after unmount is called
+    const instance = wrapper.instance();
+
+    wrapper.unmount();
+
+    assert.calledOnce(spy.withArgs("ContentSearchClient", instance));
+  });
+  it("should add gContentSearchController as a global", () => {
+    // current about:home tests need gContentSearchController to exist as a global
+    // so let's test it here too to ensure we don't break this behaviour
+    mountWithIntl(<Search {...DEFAULT_PROPS} />);
+    assert.property(window, "gContentSearchController");
+    assert.ok(window.gContentSearchController);
+  });
+  it("should pass along search when clicking the search button", () => {
+    const wrapper = mountWithIntl(<Search {...DEFAULT_PROPS} />);
+
+    wrapper.find(".search-button").simulate("click");
+
+    const {search} = window.gContentSearchController;
+    assert.calledOnce(search);
+    assert.propertyVal(search.firstCall.args[0], "type", "click");
+  });
+  it("should send a UserEvent action", () => {
+    global.ContentSearchUIController.prototype.search = () => {
+      dispatchEvent(new CustomEvent("ContentSearchClient", {detail: {type: "Search"}}));
+    };
+    const dispatch = sinon.spy();
+    const wrapper = mountWithIntl(<Search {...DEFAULT_PROPS} dispatch={dispatch} />);
+
+    wrapper.find(".search-button").simulate("click");
+
+    assert.calledOnce(dispatch);
+    const [action] = dispatch.firstCall.args;
+    assert.isUserEventAction(action);
+    assert.propertyVal(action.data, "event", "SEARCH");
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/components/SectionMenu.test.jsx
@@ -0,0 +1,178 @@
+import {ContextMenu} from "content-src/components/ContextMenu/ContextMenu";
+import {IntlProvider} from "react-intl";
+import React from "react";
+import {_SectionMenu as SectionMenu} from "content-src/components/SectionMenu/SectionMenu";
+import {shallow} from "enzyme";
+import {shallowWithIntl} from "test/unit/utils";
+
+const messages = require("data/locales.json")["en-US"]; // eslint-disable-line import/no-commonjs
+
+const DEFAULT_PROPS = {
+  name: "Section Name",
+  id: "sectionId",
+  source: "TOP_SITES",
+  showPrefName: "showSection",
+  collapsePrefName: "collapseSection",
+  collapsed: false,
+  onUpdate: () => {},
+  visible: false,
+  dispatch: () => {}
+};
+
+describe("<SectionMenu>", () => {
+  let wrapper;
+  beforeEach(() => {
+    wrapper = shallowWithIntl(<SectionMenu {...DEFAULT_PROPS} />);
+  });
+  it("should render a ContextMenu element", () => {
+    assert.ok(wrapper.find(ContextMenu).exists());
+  });
+  it("should pass onUpdate, and options to ContextMenu", () => {
+    assert.ok(wrapper.find(ContextMenu).exists());
+    const contextMenuProps = wrapper.find(ContextMenu).props();
+    ["onUpdate", "options"].forEach(prop => assert.property(contextMenuProps, prop));
+  });
+  it("should give ContextMenu the correct tabbable options length for a11y", () => {
+    const {options} = wrapper.find(ContextMenu).props();
+    const [firstItem] = options;
+    const lastItem = options[options.length - 1];
+
+    // first item should have {first: true}
+    assert.isTrue(firstItem.first);
+    assert.ok(!firstItem.last);
+
+    // last item should have {last: true}
+    assert.isTrue(lastItem.last);
+    assert.ok(!lastItem.first);
+
+    // middle items should have neither
+    for (let i = 1; i < options.length - 1; i++) {
+      assert.ok(!options[i].first && !options[i].last);
+    }
+  });
+  it("should show the correct default options", () => {
+    wrapper = shallowWithIntl(<SectionMenu {...DEFAULT_PROPS} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    let i = 0;
+    assert.propertyVal(options[i++], "id", "section_menu_action_move_up");
+    assert.propertyVal(options[i++], "id", "section_menu_action_move_down");
+    assert.propertyVal(options[i++], "type", "separator");
+    assert.propertyVal(options[i++], "id", "section_menu_action_remove_section");
+    assert.propertyVal(options[i++], "id", "section_menu_action_collapse_section");
+    assert.propertyVal(options[i++], "type", "separator");
+    assert.propertyVal(options[i++], "id", "section_menu_action_manage_section");
+    assert.propertyVal(options, "length", i);
+  });
+  it("should show the correct default options for a web extension", () => {
+    wrapper = shallowWithIntl(<SectionMenu {...DEFAULT_PROPS} isWebExtension={true} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    let i = 0;
+    assert.propertyVal(options[i++], "id", "section_menu_action_move_up");
+    assert.propertyVal(options[i++], "id", "section_menu_action_move_down");
+    assert.propertyVal(options[i++], "type", "separator");
+    assert.propertyVal(options[i++], "id", "section_menu_action_collapse_section");
+    assert.propertyVal(options[i++], "type", "separator");
+    assert.propertyVal(options[i++], "id", "section_menu_action_manage_webext");
+    assert.propertyVal(options, "length", i);
+  });
+  it("should show Collapse option for an expanded section if CheckCollapsed in options list", () => {
+    wrapper = shallowWithIntl(<SectionMenu {...DEFAULT_PROPS} collapsed={false} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "section_menu_action_collapse_section")));
+  });
+  it("should show Expand option for a collapsed section if CheckCollapsed in options list", () => {
+    wrapper = shallowWithIntl(<SectionMenu {...DEFAULT_PROPS} collapsed={true} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.isDefined(options.find(o => (o.id && o.id === "section_menu_action_expand_section")));
+  });
+  it("should show Add Top Site option", () => {
+    wrapper = shallowWithIntl(<SectionMenu {...DEFAULT_PROPS} extraOptions={["AddTopSite"]} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.equal(options[0].id, "section_menu_action_add_topsite");
+  });
+  it("should show Privacy Notice option if privacyNoticeURL is passed", () => {
+    wrapper = shallowWithIntl(<SectionMenu {...DEFAULT_PROPS} privacyNoticeURL="https://mozilla.org/privacy" />);
+    const {options} = wrapper.find(ContextMenu).props();
+    let i = 0;
+    assert.propertyVal(options[i++], "id", "section_menu_action_move_up");
+    assert.propertyVal(options[i++], "id", "section_menu_action_move_down");
+    assert.propertyVal(options[i++], "type", "separator");
+    assert.propertyVal(options[i++], "id", "section_menu_action_remove_section");
+    assert.propertyVal(options[i++], "id", "section_menu_action_collapse_section");
+    assert.propertyVal(options[i++], "type", "separator");
+    assert.propertyVal(options[i++], "id", "section_menu_action_privacy_notice");
+    assert.propertyVal(options[i++], "id", "section_menu_action_manage_section");
+    assert.propertyVal(options, "length", i);
+  });
+  it("should call intl.formatMessage with the correct string ids", () => {
+    const intlProvider = new IntlProvider({locale: "en", messages});
+    const {intl} = intlProvider.getChildContext();
+    const spy = sinon.spy(intl, "formatMessage");
+
+    // Identical to calling shallowWithIntl, but passing in the mocked intl object
+    const node = <SectionMenu {...DEFAULT_PROPS} />;
+    shallow(React.cloneElement(node, {intl}), {context: {intl}});
+
+    // Called once for each option in the menu
+    assert.equal(spy.callCount, 5);
+
+    // Called with correct ids
+    assert.ok(spy.calledWith(sinon.match({id: "section_menu_action_move_up"})));
+    assert.ok(spy.calledWith(sinon.match({id: "section_menu_action_move_down"})));
+    assert.ok(spy.calledWith(sinon.match({id: "section_menu_action_remove_section"})));
+    assert.ok(spy.calledWith(sinon.match({id: "section_menu_action_collapse_section"})));
+    assert.ok(spy.calledWith(sinon.match({id: "section_menu_action_manage_section"})));
+  });
+  it("should disable Move Up on first section", () => {
+    wrapper = shallowWithIntl(<SectionMenu {...DEFAULT_PROPS} isFirst={true} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.ok(options[0].disabled);
+  });
+  it("should disable Move Down on last section", () => {
+    wrapper = shallowWithIntl(<SectionMenu {...DEFAULT_PROPS} isLast={true} />);
+    const {options} = wrapper.find(ContextMenu).props();
+    assert.ok(options[1].disabled);
+  });
+  describe(".onClick", () => {
+    const dispatch = sinon.stub();
+    const propOptions = ["Separator", "MoveUp", "MoveDown", "RemoveSection", "CollapseSection", "ExpandSection", "ManageSection", "AddTopSite", "PrivacyNotice"];
+    const expectedActionData = {
+      section_menu_action_move_up: {id: "sectionId", direction: -1},
+      section_menu_action_move_down: {id: "sectionId", direction: +1},
+      section_menu_action_remove_section: {name: "showSection", value: false},
+      section_menu_action_collapse_section: {id: DEFAULT_PROPS.id, value: {collapsed: true}},
+      section_menu_action_expand_section: {id: DEFAULT_PROPS.id, value: {collapsed: false}},
+      section_menu_action_manage_section: undefined,
+      section_menu_action_add_topsite: {index: -1},
+      section_menu_action_privacy_notice: {url: DEFAULT_PROPS.privacyNoticeURL}
+    };
+    const {options} = shallowWithIntl(<SectionMenu {...DEFAULT_PROPS} dispatch={dispatch} options={propOptions} />)
+      .find(ContextMenu).props();
+    afterEach(() => dispatch.reset());
+    options.filter(o => o.type !== "separator").forEach(option => {
+      it(`should fire a ${option.action.type} action for ${option.id} with the expected data`, () => {
+        option.onClick();
+
+        if (option.userEvent && option.action) {
+          assert.calledTwice(dispatch);
+        } else if (option.userEvent || option.action) {
+          assert.calledOnce(dispatch);
+        } else {
+          assert.notCalled(dispatch);
+        }
+
+        // option.action is dispatched
+        assert.ok(dispatch.firstCall.calledWith(option.action));
+        assert.deepEqual(option.action.data, expectedActionData[option.id]);
+      });
+      it(`should fire a UserEvent action for ${option.id} if configured`, () => {
+        if (option.userEvent) {
+          option.onClick();
+          const [action] = dispatch.secondCall.args;
+          assert.isUserEventAction(action);
+          assert.propertyVal(action.data, "source", DEFAULT_PROPS.source);
+        }
+      });
+    });
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/components/Sections.test.jsx
@@ -0,0 +1,421 @@
+import {combineReducers, createStore} from "redux";
+import {INITIAL_STATE, reducers} from "common/Reducers.jsm";
+import {mountWithIntl, shallowWithIntl} from "test/unit/utils";
+import {Section, SectionIntl, _Sections as Sections} from "content-src/components/Sections/Sections";
+import {actionTypes as at} from "common/Actions.jsm";
+import {PlaceholderCard} from "content-src/components/Card/Card";
+import {Provider} from "react-redux";
+import React from "react";
+import {SectionMenu} from "content-src/components/SectionMenu/SectionMenu";
+import {shallow} from "enzyme";
+import {TopSites} from "content-src/components/TopSites/TopSites";
+
+function mountSectionWithProps(props) {
+  const store = createStore(combineReducers(reducers), INITIAL_STATE);
+  return mountWithIntl(<Provider store={store}><Section {...props} /></Provider>);
+}
+
+describe("<Sections>", () => {
+  let wrapper;
+  let FAKE_SECTIONS;
+  beforeEach(() => {
+    FAKE_SECTIONS = new Array(5).fill(null).map((v, i) => ({
+      id: `foo_bar_${i}`,
+      title: `Foo Bar ${i}`,
+      enabled: !!(i % 2),
+      rows: []
+    }));
+    wrapper = shallow(<Sections Sections={FAKE_SECTIONS} Prefs={{values: {sectionOrder: FAKE_SECTIONS.map(i => i.id).join(",")}}} />);
+  });
+  it("should render a Sections element", () => {
+    assert.ok(wrapper.exists());
+  });
+  it("should render a Section for each one passed in props.Sections with .enabled === true", () => {
+    const sectionElems = wrapper.find(SectionIntl);
+    assert.lengthOf(sectionElems, 2);
+    sectionElems.forEach((section, i) => {
+      assert.equal(section.props().id, FAKE_SECTIONS[2 * i + 1].id);
+      assert.equal(section.props().enabled, true);
+    });
+  });
+  it("should render Top Sites if feeds.topsites pref is true", () => {
+    wrapper = shallow(<Sections Sections={FAKE_SECTIONS} Prefs={{values: {"feeds.topsites": true, "sectionOrder": "topsites,topstories,highlights"}}} />);
+    assert.equal(wrapper.find(TopSites).length, 1);
+  });
+  it("should NOT render Top Sites if feeds.topsites pref is false", () => {
+    wrapper = shallow(<Sections Sections={FAKE_SECTIONS} Prefs={{values: {"feeds.topsites": false, "sectionOrder": "topsites,topstories,highlights"}}} />);
+    assert.equal(wrapper.find(TopSites).length, 0);
+  });
+  it("should render the sections in the order specifed by sectionOrder pref", () => {
+    wrapper = shallow(<Sections Sections={FAKE_SECTIONS} Prefs={{values: {sectionOrder: "foo_bar_1,foo_bar_3"}}} />);
+    let sections = wrapper.find(SectionIntl);
+    assert.lengthOf(sections, 2);
+    assert.equal(sections.first().props().id, "foo_bar_1");
+    assert.equal(sections.last().props().id, "foo_bar_3");
+    wrapper = shallow(<Sections Sections={FAKE_SECTIONS} Prefs={{values: {sectionOrder: "foo_bar_3,foo_bar_1"}}} />);
+    sections = wrapper.find(SectionIntl);
+    assert.lengthOf(sections, 2);
+    assert.equal(sections.first().props().id, "foo_bar_3");
+    assert.equal(sections.last().props().id, "foo_bar_1");
+  });
+});
+
+describe("<Section>", () => {
+  let wrapper;
+  let FAKE_SECTION;
+
+  beforeEach(() => {
+    FAKE_SECTION = {
+      id: `foo_bar_1`,
+      pref: {collapsed: false},
+      title: `Foo Bar 1`,
+      rows: [{link: "http://localhost", index: 0}],
+      emptyState: {
+        icon: "check",
+        message: "Some message"
+      },
+      rowsPref: "section.rows",
+      maxRows: 4,
+      Prefs: {values: {"section.rows": 2}}
+    };
+    wrapper = mountSectionWithProps(FAKE_SECTION);
+  });
+
+  describe("context menu", () => {
+    it("should render a context menu button", () => {
+      wrapper = mountSectionWithProps(FAKE_SECTION);
+
+      assert.equal(wrapper.find(".section-top-bar .context-menu-button").length, 1);
+    });
+    it("should render a section menu when button is clicked", () => {
+      wrapper = mountSectionWithProps(FAKE_SECTION);
+
+      const button = wrapper.find(".section-top-bar .context-menu-button");
+      assert.equal(wrapper.find(SectionMenu).length, 0);
+      button.simulate("click", {preventDefault: () => {}});
+      assert.equal(wrapper.find(SectionMenu).length, 1);
+    });
+    it("should not render a section menu by default", () => {
+      wrapper = shallowWithIntl(<Section {...FAKE_SECTION} />);
+      assert.equal(wrapper.find(SectionMenu).length, 0);
+    });
+  });
+
+  describe("placeholders", () => {
+    const CARDS_PER_ROW = 3;
+    const fakeSite = {link: "http://localhost"};
+    function renderWithSites(rows) {
+      const store = createStore(combineReducers(reducers), INITIAL_STATE);
+      return mountWithIntl(<Provider store={store}><Section {...FAKE_SECTION} rows={rows} /></Provider>);
+    }
+
+    it("should return 2 row of placeholders if realRows is 0", () => {
+      wrapper = renderWithSites([]);
+      assert.lengthOf(wrapper.find(PlaceholderCard), 6);
+    });
+    it("should fill in the rest of the rows", () => {
+      wrapper = renderWithSites(new Array(CARDS_PER_ROW).fill(fakeSite));
+      assert.lengthOf(wrapper.find(PlaceholderCard), CARDS_PER_ROW, "CARDS_PER_ROW");
+
+      wrapper = renderWithSites(new Array(CARDS_PER_ROW + 1).fill(fakeSite));
+      assert.lengthOf(wrapper.find(PlaceholderCard), 2, "CARDS_PER_ROW + 1");
+
+      wrapper = renderWithSites(new Array(CARDS_PER_ROW + 2).fill(fakeSite));
+      assert.lengthOf(wrapper.find(PlaceholderCard), 1, "CARDS_PER_ROW + 2");
+
+      wrapper = renderWithSites(new Array(2 * CARDS_PER_ROW - 1).fill(fakeSite));
+      assert.lengthOf(wrapper.find(PlaceholderCard), 1, "CARDS_PER_ROW - 1");
+    });
+    it("should not add placeholders all the rows are full", () => {
+      wrapper = renderWithSites(new Array(2 * CARDS_PER_ROW).fill(fakeSite));
+      assert.lengthOf(wrapper.find(PlaceholderCard), 0, "2 rows");
+    });
+  });
+
+  describe("empty state", () => {
+    beforeEach(() => {
+      Object.assign(FAKE_SECTION, {
+        initialized: true,
+        rows: [],
+        emptyState: {message: "Some message", icon: "moz-extension://some/extension/path"}
+      });
+      wrapper = shallowWithIntl(
+        <Section {...FAKE_SECTION} />);
+    });
+    it("should be shown when rows is empty and initialized is true", () => {
+      assert.ok(wrapper.find(".empty-state").exists());
+    });
+    it("should not be shown in initialized is false", () => {
+      Object.assign(FAKE_SECTION, {
+        initialized: false,
+        rows: [],
+        emptyState: {message: "Some message", icon: "moz-extension://some/extension/path"}
+      });
+      wrapper = shallowWithIntl(
+        <Section {...FAKE_SECTION} />);
+      assert.isFalse(wrapper.find(".empty-state").exists());
+    });
+    it("should use the icon prop as the icon url if it starts with `moz-extension://`", () => {
+      const props = wrapper.find(".empty-state-icon").first().props();
+      assert.equal(props.style["background-image"], `url('${FAKE_SECTION.emptyState.icon}')`);
+    });
+  });
+
+  describe("topics component", () => {
+    let TOP_STORIES_SECTION;
+    beforeEach(() => {
+      TOP_STORIES_SECTION = {
+        id: "topstories",
+        title: "TopStories",
+        pref: {collapsed: false},
+        rows: [{guid: 1, link: "http://localhost", isDefault: true}],
+        topics: [],
+        read_more_endpoint: "http://localhost/read-more",
+        maxRows: 1,
+        eventSource: "TOP_STORIES"
+      };
+    });
+    it("should not render for empty topics", () => {
+      wrapper = mountSectionWithProps(TOP_STORIES_SECTION);
+
+      assert.lengthOf(wrapper.find(".topic"), 0);
+    });
+    it("should render for non-empty topics", () => {
+      TOP_STORIES_SECTION.topics = [{name: "topic1", url: "topic-url1"}];
+
+      wrapper = mountSectionWithProps(TOP_STORIES_SECTION);
+
+      assert.lengthOf(wrapper.find(".topic"), 1);
+    });
+    it("should render for uninitialized topics", () => {
+      delete TOP_STORIES_SECTION.topics;
+
+      wrapper = mountSectionWithProps(TOP_STORIES_SECTION);
+
+      assert.lengthOf(wrapper.find(".topic"), 1);
+    });
+  });
+
+  describe("impression stats", () => {
+    const FAKE_TOPSTORIES_SECTION_PROPS = {
+      id: "TopStories",
+      title: "Foo Bar 1",
+      pref: {collapsed: false},
+      maxRows: 1,
+      rows: [{guid: 1}, {guid: 2}],
+      shouldSendImpressionStats: true,
+
+      document: {
+        visibilityState: "visible",
+        addEventListener: sinon.stub(),
+        removeEventListener: sinon.stub()
+      },
+      eventSource: "TOP_STORIES",
+      options: {personalized: false}
+    };
+
+    function renderSection(props = {}) {
+      return shallowWithIntl(<Section
+        {...FAKE_TOPSTORIES_SECTION_PROPS}
+        {...props} />);
+    }
+
+    it("should send impression with the right stats when the page loads", () => {
+      const dispatch = sinon.spy();
+      renderSection({dispatch});
+
+      assert.calledOnce(dispatch);
+
+      const [action] = dispatch.firstCall.args;
+      assert.equal(action.type, at.TELEMETRY_IMPRESSION_STATS);
+      assert.equal(action.data.source, "TOP_STORIES");
+      assert.deepEqual(action.data.tiles, [{id: 1}, {id: 2}]);
+    });
+    it("should not send impression stats if not configured", () => {
+      const dispatch = sinon.spy();
+      const props = Object.assign({}, FAKE_TOPSTORIES_SECTION_PROPS, {shouldSendImpressionStats: false, dispatch});
+      renderSection(props);
+      assert.notCalled(dispatch);
+    });
+    it("should not send impression stats if the section is collapsed", () => {
+      const dispatch = sinon.spy();
+      const props = Object.assign({}, FAKE_TOPSTORIES_SECTION_PROPS, {pref: {collapsed: true}});
+      renderSection(props);
+      assert.notCalled(dispatch);
+    });
+    it("should send 1 impression when the page becomes visibile after loading", () => {
+      const props = {
+        dispatch: sinon.spy(),
+        document: {
+          visibilityState: "hidden",
+          addEventListener: sinon.spy(),
+          removeEventListener: sinon.spy()
+        }
+      };
+
+      renderSection(props);
+
+      // Was the event listener added?
+      assert.calledWith(props.document.addEventListener, "visibilitychange");
+
+      // Make sure dispatch wasn't called yet
+      assert.notCalled(props.dispatch);
+
+      // Simulate a visibilityChange event
+      const [, listener] = props.document.addEventListener.firstCall.args;
+      props.document.visibilityState = "visible";
+      listener();
+
+      // Did we actually dispatch an event?
+      assert.calledOnce(props.dispatch);
+      assert.equal(props.dispatch.firstCall.args[0].type, at.TELEMETRY_IMPRESSION_STATS);
+
+      // Did we remove the event listener?
+      assert.calledWith(props.document.removeEventListener, "visibilitychange", listener);
+    });
+    it("should remove visibility change listener when section is removed", () => {
+      const props = {
+        dispatch: sinon.spy(),
+        document: {
+          visibilityState: "hidden",
+          addEventListener: sinon.spy(),
+          removeEventListener: sinon.spy()
+        }
+      };
+
+      const section = renderSection(props);
+      assert.calledWith(props.document.addEventListener, "visibilitychange");
+      const [, listener] = props.document.addEventListener.firstCall.args;
+
+      section.unmount();
+      assert.calledWith(props.document.removeEventListener, "visibilitychange", listener);
+    });
+    it("should send an impression if props are updated and props.rows are different", () => {
+      const props = {dispatch: sinon.spy()};
+      wrapper = renderSection(props);
+      props.dispatch.reset();
+
+      // New rows
+      wrapper.setProps(Object.assign({},
+        FAKE_TOPSTORIES_SECTION_PROPS,
+        {rows: [{guid: 123}]}
+      ));
+
+      assert.calledOnce(props.dispatch);
+    });
+    it("should not send an impression if props are updated but props.rows are the same", () => {
+      const props = {dispatch: sinon.spy()};
+      wrapper = renderSection(props);
+      props.dispatch.reset();
+
+      // Only update the disclaimer prop
+      wrapper.setProps(Object.assign({},
+        FAKE_TOPSTORIES_SECTION_PROPS,
+        {disclaimer: {id: "bar"}}
+      ));
+
+      assert.notCalled(props.dispatch);
+    });
+    it("should not send an impression if props are updated and props.rows are the same but section is collapsed", () => {
+      const props = {dispatch: sinon.spy()};
+      wrapper = renderSection(props);
+      props.dispatch.reset();
+
+      // New rows and collapsed
+      wrapper.setProps(Object.assign({},
+        FAKE_TOPSTORIES_SECTION_PROPS,
+        {
+          rows: [{guid: 123}],
+          pref: {collapsed: true}
+        }
+      ));
+
+      assert.notCalled(props.dispatch);
+
+      // Expand the section. Now the impression stats should be sent
+      wrapper.setProps(Object.assign({},
+        FAKE_TOPSTORIES_SECTION_PROPS,
+        {
+          rows: [{guid: 123}],
+          pref: {collapsed: false}
+        }
+      ));
+
+      assert.calledOnce(props.dispatch);
+    });
+    it("should not send an impression if props are updated but GUIDs are the same", () => {
+      const props = {dispatch: sinon.spy()};
+      wrapper = renderSection(props);
+      props.dispatch.reset();
+
+      wrapper.setProps(Object.assign({},
+        FAKE_TOPSTORIES_SECTION_PROPS,
+        {rows: [{guid: 1}, {guid: 2}]}
+      ));
+
+      assert.notCalled(props.dispatch);
+    });
+    it("should only send the latest impression on a visibility change", () => {
+      const listeners = new Set();
+      const props = {
+        dispatch: sinon.spy(),
+        document: {
+          visibilityState: "hidden",
+          addEventListener: (ev, cb) => listeners.add(cb),
+          removeEventListener: (ev, cb) => listeners.delete(cb)
+        }
+      };
+
+      wrapper = renderSection(props);
+
+      // Update twice
+      wrapper.setProps(Object.assign({}, props,
+        {rows: [{guid: 123}]}
+      ));
+      wrapper.setProps(Object.assign({}, props,
+        {rows: [{guid: 2432}]}
+      ));
+
+      assert.notCalled(props.dispatch);
+
+      // Simulate listeners getting called
+      props.document.visibilityState = "visible";
+      listeners.forEach(l => l());
+
+      // Make sure we only sent the latest event
+      assert.calledOnce(props.dispatch);
+      const [action] = props.dispatch.firstCall.args;
+      assert.deepEqual(action.data.tiles, [{id: 2432}]);
+    });
+  });
+
+  describe("#numRows", () => {
+    it("should return maxRows if there is no rowsPref set", () => {
+      delete FAKE_SECTION.rowsPref;
+      wrapper = mountSectionWithProps(FAKE_SECTION);
+      assert.equal(wrapper.find(Section).instance().numRows, FAKE_SECTION.maxRows);
+    });
+
+    it("should return number of rows set in Pref if rowsPref is set", () => {
+      const numRows = 2;
+      Object.assign(FAKE_SECTION, {
+        rowsPref: "section.rows",
+        maxRows: 4,
+        Prefs: {values: {"section.rows": numRows}}
+      });
+      wrapper = mountSectionWithProps(FAKE_SECTION);
+      assert.equal(wrapper.find(Section).instance().numRows, numRows);
+    });
+
+    it("should return number of rows set in Pref even if higher than maxRows value", () => {
+      const numRows = 10;
+      Object.assign(FAKE_SECTION, {
+        rowsPref: "section.rows",
+        maxRows: 4,
+        Prefs: {values: {"section.rows": numRows}}
+      });
+      wrapper = mountSectionWithProps(FAKE_SECTION);
+      assert.equal(wrapper.find(Section).instance().numRows, numRows);
+    });
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/components/StartupOverlay.test.jsx
@@ -0,0 +1,33 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {mountWithIntl} from "test/unit/utils";
+import React from "react";
+import {_StartupOverlay as StartupOverlay} from "content-src/components/StartupOverlay/StartupOverlay";
+
+describe("<StartupOverlay>", () => {
+  let wrapper;
+  let dispatch;
+  beforeEach(() => {
+    dispatch = sinon.stub();
+    wrapper = mountWithIntl(<StartupOverlay dispatch={dispatch} />);
+  });
+
+  it("should emit UserEvent SKIPPED_SIGNIN when you click the skip button", () => {
+    let skipButton = wrapper.find(".skip-button");
+    assert.ok(skipButton.exists());
+    skipButton.simulate("click");
+
+    assert.calledOnce(dispatch);
+    assert.isUserEventAction(dispatch.firstCall.args[0]);
+    assert.calledWith(dispatch, ac.UserEvent({event: at.SKIPPED_SIGNIN}));
+  });
+
+  it("should emit UserEvent SUBMIT_EMAIL when you submit the form", () => {
+    let form = wrapper.find("form");
+    assert.ok(form.exists());
+    form.simulate("submit");
+
+    assert.calledOnce(dispatch);
+    assert.isUserEventAction(dispatch.firstCall.args[0]);
+    assert.calledWith(dispatch, ac.UserEvent({event: at.SUBMIT_EMAIL}));
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/components/TopSites.test.jsx
@@ -0,0 +1,1169 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {GlobalOverrider, mountWithIntl, shallowWithIntl} from "test/unit/utils";
+import {MIN_CORNER_FAVICON_SIZE, MIN_RICH_FAVICON_SIZE} from "content-src/components/TopSites/TopSitesConstants";
+import {TOP_SITES_DEFAULT_ROWS, TOP_SITES_MAX_SITES_PER_ROW} from "common/Reducers.jsm";
+import {TopSite, TopSiteLink, _TopSiteList as TopSiteList, TopSitePlaceholder} from "content-src/components/TopSites/TopSite";
+import {FormattedMessage} from "react-intl";
+import {LinkMenu} from "content-src/components/LinkMenu/LinkMenu";
+import React from "react";
+import {SectionMenu} from "content-src/components/SectionMenu/SectionMenu";
+import {shallow} from "enzyme";
+import {TopSiteForm} from "content-src/components/TopSites/TopSiteForm";
+import {TopSiteFormInput} from "content-src/components/TopSites/TopSiteFormInput";
+import {_TopSites as TopSites} from "content-src/components/TopSites/TopSites";
+
+const perfSvc = {
+  mark() {},
+  getMostRecentAbsMarkStartByName() {}
+};
+
+const DEFAULT_PROPS = {
+  TopSites: {initialized: true, rows: []},
+  TopSitesRows: TOP_SITES_DEFAULT_ROWS,
+  topSiteIconType: () => "no_image",
+  dispatch() {},
+  intl: {formatMessage: x => x},
+  perfSvc
+};
+
+describe("<TopSites>", () => {
+  let sandbox;
+
+  beforeEach(() => {
+    sandbox = sinon.sandbox.create();
+  });
+
+  afterEach(() => {
+    sandbox.restore();
+  });
+
+  it("should render a TopSites element", () => {
+    const wrapper = shallow(<TopSites {...DEFAULT_PROPS} />);
+    assert.ok(wrapper.exists());
+  });
+  describe("context menu", () => {
+    it("should render a context menu button", () => {
+      const wrapper = mountWithIntl(<TopSites {...DEFAULT_PROPS} />);
+      assert.equal(wrapper.find(".section-top-bar .context-menu-button").length, 1);
+    });
+    it("should render a section menu when button is clicked", () => {
+      const wrapper = mountWithIntl(<TopSites {...DEFAULT_PROPS} />);
+      const button = wrapper.find(".section-top-bar .context-menu-button");
+      assert.equal(wrapper.find(SectionMenu).length, 0);
+      button.simulate("click", {preventDefault: () => {}});
+      assert.equal(wrapper.find(SectionMenu).length, 1);
+    });
+    it("should not render a section menu by default", () => {
+      const wrapper = mountWithIntl(<TopSites {...DEFAULT_PROPS} />);
+      assert.equal(wrapper.find(SectionMenu).length, 0);
+    });
+    it("should pass through the correct menu extraOptions to SectionMenu", () => {
+      const wrapper = mountWithIntl(<TopSites {...DEFAULT_PROPS} />);
+      wrapper.find(".section-top-bar .context-menu-button").simulate("click", {preventDefault: () => {}});
+      const sectionMenuProps = wrapper.find(SectionMenu).props();
+      assert.deepEqual(sectionMenuProps.extraOptions, ["AddTopSite"]);
+    });
+  });
+  describe("#_dispatchTopSitesStats", () => {
+    let globals;
+    let wrapper;
+    let dispatchStatsSpy;
+
+    beforeEach(() => {
+      globals = new GlobalOverrider();
+      sandbox.stub(DEFAULT_PROPS, "dispatch");
+      wrapper = shallow(<TopSites {...DEFAULT_PROPS} />, {disableLifecycleMethods: true});
+      dispatchStatsSpy = sandbox.spy(wrapper.instance(), "_dispatchTopSitesStats");
+    });
+    afterEach(() => {
+      globals.restore();
+      sandbox.restore();
+    });
+    it("should call _dispatchTopSitesStats on componentDidMount", () => {
+      wrapper.instance().componentDidMount();
+
+      assert.calledOnce(dispatchStatsSpy);
+    });
+    it("should call _dispatchTopSitesStats on componentDidUpdate", () => {
+      wrapper.instance().componentDidUpdate();
+
+      assert.calledOnce(dispatchStatsSpy);
+    });
+    it("should dispatch SAVE_SESSION_PERF_DATA", () => {
+      wrapper.instance()._dispatchTopSitesStats();
+
+      assert.calledOnce(DEFAULT_PROPS.dispatch);
+      assert.calledWithExactly(DEFAULT_PROPS.dispatch, ac.AlsoToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: {
+          topsites_icon_stats: {
+            "custom_screenshot": 0,
+            "screenshot_with_icon": 0,
+            "screenshot": 0,
+            "tippytop": 0,
+            "rich_icon": 0,
+            "no_image": 0
+          },
+          topsites_pinned: 0
+        }
+      }));
+    });
+    it("should correctly count TopSite images - just screenshot", () => {
+      const rows = [{screenshot: true}];
+      sandbox.stub(DEFAULT_PROPS.TopSites, "rows").value(rows);
+      wrapper.instance()._dispatchTopSitesStats();
+
+      assert.calledOnce(DEFAULT_PROPS.dispatch);
+      assert.calledWithExactly(DEFAULT_PROPS.dispatch, ac.AlsoToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: {
+          topsites_icon_stats: {
+            "custom_screenshot": 0,
+            "screenshot_with_icon": 0,
+            "screenshot": 1,
+            "tippytop": 0,
+            "rich_icon": 0,
+            "no_image": 0
+          },
+          topsites_pinned: 0
+        }
+      }));
+    });
+    it("should correctly count TopSite images - custom_screenshot", () => {
+      const rows = [{customScreenshotURL: true}];
+      sandbox.stub(DEFAULT_PROPS.TopSites, "rows").value(rows);
+      wrapper.instance()._dispatchTopSitesStats();
+
+      assert.calledOnce(DEFAULT_PROPS.dispatch);
+      assert.calledWithExactly(DEFAULT_PROPS.dispatch, ac.AlsoToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: {
+          topsites_icon_stats: {
+            "custom_screenshot": 1,
+            "screenshot_with_icon": 0,
+            "screenshot": 0,
+            "tippytop": 0,
+            "rich_icon": 0,
+            "no_image": 0
+          },
+          topsites_pinned: 0
+        }
+      }));
+    });
+    it("should correctly count TopSite images - screenshot + favicon", () => {
+      const rows = [{screenshot: true, faviconSize: MIN_CORNER_FAVICON_SIZE}];
+      sandbox.stub(DEFAULT_PROPS.TopSites, "rows").value(rows);
+      wrapper.instance()._dispatchTopSitesStats();
+
+      assert.calledOnce(DEFAULT_PROPS.dispatch);
+      assert.calledWithExactly(DEFAULT_PROPS.dispatch, ac.AlsoToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: {
+          topsites_icon_stats: {
+            "custom_screenshot": 0,
+            "screenshot_with_icon": 1,
+            "screenshot": 0,
+            "tippytop": 0,
+            "rich_icon": 0,
+            "no_image": 0
+          },
+          topsites_pinned: 0
+        }
+      }));
+    });
+    it("should correctly count TopSite images - rich_icon", () => {
+      const rows = [{faviconSize: MIN_RICH_FAVICON_SIZE}];
+      sandbox.stub(DEFAULT_PROPS.TopSites, "rows").value(rows);
+      wrapper.instance()._dispatchTopSitesStats();
+
+      assert.calledOnce(DEFAULT_PROPS.dispatch);
+      assert.calledWithExactly(DEFAULT_PROPS.dispatch, ac.AlsoToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: {
+          topsites_icon_stats: {
+            "custom_screenshot": 0,
+            "screenshot_with_icon": 0,
+            "screenshot": 0,
+            "tippytop": 0,
+            "rich_icon": 1,
+            "no_image": 0
+          },
+          topsites_pinned: 0
+        }
+      }));
+    });
+    it("should correctly count TopSite images - tippytop", () => {
+      const rows = [{tippyTopIcon: "foo"}, {faviconRef: "tippytop"}, {faviconRef: "foobar"}];
+      sandbox.stub(DEFAULT_PROPS.TopSites, "rows").value(rows);
+      wrapper.instance()._dispatchTopSitesStats();
+
+      assert.calledOnce(DEFAULT_PROPS.dispatch);
+      assert.calledWithExactly(DEFAULT_PROPS.dispatch, ac.AlsoToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: {
+          topsites_icon_stats: {
+            "custom_screenshot": 0,
+            "screenshot_with_icon": 0,
+            "screenshot": 0,
+            "tippytop": 2,
+            "rich_icon": 0,
+            "no_image": 1
+          },
+          topsites_pinned: 0
+        }
+      }));
+    });
+    it("should correctly count TopSite images - no image", () => {
+      const rows = [{}];
+      sandbox.stub(DEFAULT_PROPS.TopSites, "rows").value(rows);
+      wrapper.instance()._dispatchTopSitesStats();
+
+      assert.calledOnce(DEFAULT_PROPS.dispatch);
+      assert.calledWithExactly(DEFAULT_PROPS.dispatch, ac.AlsoToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: {
+          topsites_icon_stats: {
+            "custom_screenshot": 0,
+            "screenshot_with_icon": 0,
+            "screenshot": 0,
+            "tippytop": 0,
+            "rich_icon": 0,
+            "no_image": 1
+          },
+          topsites_pinned: 0
+        }
+      }));
+    });
+    it("should correctly count pinned Top Sites", () => {
+      const rows = [{isPinned: true}, {isPinned: false}, {isPinned: true}];
+      sandbox.stub(DEFAULT_PROPS.TopSites, "rows").value(rows);
+      wrapper.instance()._dispatchTopSitesStats();
+
+      assert.calledOnce(DEFAULT_PROPS.dispatch);
+      assert.calledWithExactly(DEFAULT_PROPS.dispatch, ac.AlsoToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: {
+          topsites_icon_stats: {
+            "custom_screenshot": 0,
+            "screenshot_with_icon": 0,
+            "screenshot": 0,
+            "tippytop": 0,
+            "rich_icon": 0,
+            "no_image": 3
+          },
+          topsites_pinned: 2
+        }
+      }));
+    });
+    it("should only count visible top sites on wide layout", () => {
+      globals.set("matchMedia", () => ({matches: true}));
+      const rows = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}];
+      sandbox.stub(DEFAULT_PROPS.TopSites, "rows").value(rows);
+
+      wrapper.instance()._dispatchTopSitesStats();
+      assert.calledOnce(DEFAULT_PROPS.dispatch);
+      assert.calledWithExactly(DEFAULT_PROPS.dispatch, ac.AlsoToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: {
+          topsites_icon_stats: {
+            "custom_screenshot": 0,
+            "screenshot_with_icon": 0,
+            "screenshot": 0,
+            "tippytop": 0,
+            "rich_icon": 0,
+            "no_image": 8
+          },
+          topsites_pinned: 0
+        }
+      }));
+    });
+    it("should only count visible top sites on normal layout", () => {
+      globals.set("matchMedia", () => ({matches: false}));
+      const rows = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}];
+      sandbox.stub(DEFAULT_PROPS.TopSites, "rows").value(rows);
+      wrapper.instance()._dispatchTopSitesStats();
+      assert.calledOnce(DEFAULT_PROPS.dispatch);
+      assert.calledWithExactly(DEFAULT_PROPS.dispatch, ac.AlsoToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: {
+          topsites_icon_stats: {
+            "custom_screenshot": 0,
+            "screenshot_with_icon": 0,
+            "screenshot": 0,
+            "tippytop": 0,
+            "rich_icon": 0,
+            "no_image": 6
+          },
+          topsites_pinned: 0
+        }
+      }));
+    });
+  });
+});
+
+describe("<TopSiteLink>", () => {
+  let link;
+  beforeEach(() => {
+    link = {url: "https://foo.com", screenshot: "foo.jpg", hostname: "foo"};
+  });
+  it("should add the right url", () => {
+    link.url = "https://www.foobar.org";
+    const wrapper = shallow(<TopSiteLink link={link} />);
+    assert.propertyVal(wrapper.find("a").props(), "href", "https://www.foobar.org");
+  });
+  it("should have rtl direction automatically set for text", () => {
+    const wrapper = shallow(<TopSiteLink link={link} />);
+
+    assert.isTrue(wrapper.find("[dir='auto']").length > 0);
+  });
+  it("should render a title", () => {
+    const wrapper = shallow(<TopSiteLink link={link} title="foobar" />);
+    const titleEl = wrapper.find(".title");
+
+    assert.equal(titleEl.text(), "foobar");
+  });
+  it("should have only the title as the text of the link", () => {
+    const wrapper = shallow(<TopSiteLink link={link} title="foobar" />);
+
+    assert.equal(wrapper.find("a").text(), "foobar");
+  });
+  it("should render the pin icon for pinned links", () => {
+    link.isPinned = true;
+    link.pinnedIndex = 7;
+    const wrapper = shallow(<TopSiteLink link={link} />);
+    assert.equal(wrapper.find(".icon-pin-small").length, 1);
+  });
+  it("should not render the pin icon for non pinned links", () => {
+    link.isPinned = false;
+    const wrapper = shallow(<TopSiteLink link={link} />);
+    assert.equal(wrapper.find(".icon-pin-small").length, 0);
+  });
+  it("should render the first letter of the title as a fallback for missing screenshots", () => {
+    const wrapper = shallow(<TopSiteLink link={link} title={"foo"} />);
+    assert.equal(wrapper.find(".tile").prop("data-fallback"), "f");
+  });
+  it("should render a screenshot with the .active class, if it is provided", () => {
+    const wrapper = shallow(<TopSiteLink link={link} />);
+    const screenshotEl = wrapper.find(".screenshot");
+
+    assert.propertyVal(screenshotEl.props().style, "backgroundImage", "url(foo.jpg)");
+    assert.isTrue(screenshotEl.hasClass("active"));
+  });
+  it("should render a small icon with fallback letter with the screenshot if the icon is smaller than 16x16", () => {
+    link.favicon = "too-small-icon.png";
+    link.faviconSize = 10;
+    const wrapper = shallow(<TopSiteLink link={link} title="foo" />);
+    const screenshotEl = wrapper.find(".screenshot");
+    const defaultIconEl = wrapper.find(".default-icon");
+
+    assert.propertyVal(screenshotEl.props().style, "backgroundImage", "url(foo.jpg)");
+    assert.isTrue(screenshotEl.hasClass("active"));
+    assert.lengthOf(defaultIconEl, 1);
+    assert.equal(defaultIconEl.prop("data-fallback"), "f");
+  });
+  it("should render a small icon with fallback letter with the screenshot if the icon is missing", () => {
+    const wrapper = shallow(<TopSiteLink link={link} title="foo" />);
+    const screenshotEl = wrapper.find(".screenshot");
+    const defaultIconEl = wrapper.find(".default-icon");
+
+    assert.propertyVal(screenshotEl.props().style, "backgroundImage", "url(foo.jpg)");
+    assert.isTrue(screenshotEl.hasClass("active"));
+    assert.lengthOf(defaultIconEl, 1);
+    assert.equal(defaultIconEl.prop("data-fallback"), "f");
+  });
+  it("should render a small icon with the screenshot if the icon is bigger than 32x32", () => {
+    link.favicon = "small-icon.png";
+    link.faviconSize = 32;
+
+    const wrapper = shallow(<TopSiteLink link={link} />);
+    const screenshotEl = wrapper.find(".screenshot");
+    const defaultIconEl = wrapper.find(".default-icon");
+
+    assert.propertyVal(screenshotEl.props().style, "backgroundImage", "url(foo.jpg)");
+    assert.isTrue(screenshotEl.hasClass("active"));
+    assert.propertyVal(defaultIconEl.props().style, "backgroundImage", `url(${link.favicon})`);
+    assert.lengthOf(wrapper.find(".rich-icon"), 0);
+  });
+  it("should not add the .active class to the screenshot element if no screenshot prop is provided", () => {
+    link.screenshot = null;
+    const wrapper = shallow(<TopSiteLink link={link} />);
+    assert.isFalse(wrapper.find(".screenshot").hasClass("active"));
+  });
+  it("should render the tippy top icon if provided and not a small icon", () => {
+    link.tippyTopIcon = "foo.png";
+    link.backgroundColor = "#FFFFFF";
+    const wrapper = shallow(<TopSiteLink link={link} />);
+    assert.lengthOf(wrapper.find(".screenshot"), 0);
+    assert.lengthOf(wrapper.find(".default-icon"), 0);
+    const tippyTop = wrapper.find(".rich-icon");
+    assert.propertyVal(tippyTop.props().style, "backgroundImage", "url(foo.png)");
+    assert.propertyVal(tippyTop.props().style, "backgroundColor", "#FFFFFF");
+  });
+  it("should render a rich icon if provided and not a small icon", () => {
+    link.favicon = "foo.png";
+    link.faviconSize = 196;
+    link.backgroundColor = "#FFFFFF";
+    const wrapper = shallow(<TopSiteLink link={link} />);
+    assert.lengthOf(wrapper.find(".screenshot"), 0);
+    assert.lengthOf(wrapper.find(".default-icon"), 0);
+    const richIcon = wrapper.find(".rich-icon");
+    assert.propertyVal(richIcon.props().style, "backgroundImage", "url(foo.png)");
+    assert.propertyVal(richIcon.props().style, "backgroundColor", "#FFFFFF");
+  });
+  it("should not render a rich icon if it is smaller than 96x96", () => {
+    link.favicon = "foo.png";
+    link.faviconSize = 48;
+    link.backgroundColor = "#FFFFFF";
+    const wrapper = shallow(<TopSiteLink link={link} />);
+    assert.equal(wrapper.find(".screenshot").length, 1);
+    assert.equal(wrapper.find(".rich-icon").length, 0);
+  });
+  it("should apply just the default class name to the outer link if props.className is falsey", () => {
+    const wrapper = shallow(<TopSiteLink className={false} />);
+    assert.ok(wrapper.find("li").hasClass("top-site-outer"));
+  });
+  it("should add props.className to the outer link element", () => {
+    const wrapper = shallow(<TopSiteLink className="foo bar" />);
+    assert.ok(wrapper.find("li").hasClass("top-site-outer foo bar"));
+  });
+  describe("#onDragEvent", () => {
+    let simulate;
+    let wrapper;
+    beforeEach(() => {
+      wrapper = shallow(<TopSiteLink isDraggable={true} onDragEvent={() => {}} />);
+      simulate = type => {
+        const event = {
+          dataTransfer: {setData() {}, types: {includes() {}}},
+          preventDefault() {
+            this.prevented = true;
+          },
+          target: {blur() {}},
+          type
+        };
+        wrapper.simulate(type, event);
+        return event;
+      };
+    });
+    it("should allow clicks without dragging", () => {
+      simulate("mousedown");
+      simulate("mouseup");
+
+      const event = simulate("click");
+
+      assert.notOk(event.prevented);
+    });
+    it("should prevent clicks after dragging", () => {
+      simulate("mousedown");
+      simulate("dragstart");
+      simulate("dragenter");
+      simulate("drop");
+      simulate("dragend");
+      simulate("mouseup");
+
+      const event = simulate("click");
+
+      assert.ok(event.prevented);
+    });
+    it("should allow clicks after dragging then clicking", () => {
+      simulate("mousedown");
+      simulate("dragstart");
+      simulate("dragenter");
+      simulate("drop");
+      simulate("dragend");
+      simulate("mouseup");
+      simulate("click");
+
+      simulate("mousedown");
+      simulate("mouseup");
+
+      const event = simulate("click");
+
+      assert.notOk(event.prevented);
+    });
+  });
+});
+
+describe("<TopSite>", () => {
+  let link;
+  beforeEach(() => {
+    link = {url: "https://foo.com", screenshot: "foo.jpg", hostname: "foo"};
+  });
+
+  it("should render a TopSite", () => {
+    const wrapper = shallow(<TopSite link={link} />);
+    assert.ok(wrapper.exists());
+  });
+
+  it("should render a shortened title based off the url", () => {
+    link.url = "https://www.foobar.org";
+    link.hostname = "foobar";
+    link.eTLD = "org";
+    const wrapper = shallow(<TopSite link={link} />);
+
+    assert.equal(wrapper.find(TopSiteLink).props().title, "foobar");
+  });
+
+  it("should have .active class, on top-site-outer if context menu is open", () => {
+    const wrapper = shallow(<TopSite link={link} index={1} activeIndex={1} />);
+    wrapper.setState({showContextMenu: true});
+
+    assert.equal(wrapper.find(TopSiteLink).props().className.trim(), "active");
+  });
+  it("should not add .active class, on top-site-outer if context menu is closed", () => {
+    const wrapper = shallow(<TopSite link={link} index={1} />);
+    wrapper.setState({showContextMenu: false, activeTile: 1});
+    assert.equal(wrapper.find(TopSiteLink).props().className, "");
+  });
+  it("should render a context menu button", () => {
+    const wrapper = shallow(<TopSite link={link} />);
+    assert.equal(wrapper.find(".context-menu-button").length, 1);
+  });
+  it("should render a link menu when button is clicked", () => {
+    const wrapper = shallow(<TopSite link={link} />);
+    let button = wrapper.find(".context-menu-button");
+    assert.equal(wrapper.find(LinkMenu).length, 0);
+    button.simulate("click", {preventDefault: () => {}});
+    assert.equal(wrapper.find(LinkMenu).length, 1);
+  });
+  it("should not render a link menu by default", () => {
+    const wrapper = shallow(<TopSite link={link} />);
+    assert.equal(wrapper.find(LinkMenu).length, 0);
+  });
+  it("should pass onUpdate, site, options, and index to LinkMenu", () => {
+    const wrapper = shallow(<TopSite link={link} />);
+    wrapper.find(".context-menu-button").simulate("click", {preventDefault: () => {}});
+    const linkMenuProps = wrapper.find(LinkMenu).props();
+    ["onUpdate", "site", "index", "options"].forEach(prop => assert.property(linkMenuProps, prop));
+  });
+  it("should pass through the correct menu options to LinkMenu", () => {
+    const wrapper = shallow(<TopSite link={link} />);
+    wrapper.find(".context-menu-button").simulate("click", {preventDefault: () => {}});
+    const linkMenuProps = wrapper.find(LinkMenu).props();
+    assert.deepEqual(linkMenuProps.options,
+      ["CheckPinTopSite", "EditTopSite", "Separator", "OpenInNewWindow", "OpenInPrivateWindow", "Separator", "BlockUrl", "DeleteUrl"]);
+  });
+
+  describe("#onLinkClick", () => {
+    it("should call dispatch when the link is clicked", () => {
+      const dispatch = sinon.stub();
+      const wrapper = shallow(<TopSite link={link} index={3} dispatch={dispatch} />);
+
+      wrapper.find(TopSiteLink).simulate("click", {preventDefault() {}});
+
+      assert.calledTwice(dispatch);
+    });
+    it("should dispatch a UserEventAction with the right data", () => {
+      const dispatch = sinon.stub();
+      const wrapper = shallow(<TopSite link={Object.assign({}, link, {iconType: "rich_icon", isPinned: true})} index={3} dispatch={dispatch} />);
+
+      wrapper.find(TopSiteLink).simulate("click", {preventDefault() {}});
+
+      const [action] = dispatch.firstCall.args;
+      assert.isUserEventAction(action);
+
+      assert.propertyVal(action.data, "event", "CLICK");
+      assert.propertyVal(action.data, "source", "TOP_SITES");
+      assert.propertyVal(action.data, "action_position", 3);
+      assert.propertyVal(action.data.value, "card_type", "pinned");
+      assert.propertyVal(action.data.value, "icon_type", "rich_icon");
+    });
+    it("should dispatch OPEN_LINK with the right data", () => {
+      const dispatch = sinon.stub();
+      const wrapper = shallow(<TopSite link={Object.assign({}, link, {typedBonus: true})} index={3} dispatch={dispatch} />);
+
+      wrapper.find(TopSiteLink).simulate("click", {preventDefault() {}});
+
+      const [action] = dispatch.secondCall.args;
+      assert.propertyVal(action, "type", at.OPEN_LINK);
+      assert.propertyVal(action.data, "typedBonus", true);
+    });
+  });
+});
+
+describe("<TopSiteForm>", () => {
+  let wrapper;
+  let sandbox;
+
+  function setup(props = {}) {
+    sandbox = sinon.sandbox.create();
+    const customProps = Object.assign({}, {onClose: sandbox.spy(), dispatch: sandbox.spy()}, props);
+    wrapper = mountWithIntl(<TopSiteForm {...customProps} />);
+  }
+
+  describe("validateForm", () => {
+    beforeEach(() => setup({site: {url: "http://foo"}}));
+
+    it("should return true for a correct URL", () => {
+      wrapper.setState({url: "foo"});
+
+      assert.isTrue(wrapper.instance().validateForm());
+    });
+
+    it("should return false for a incorrect URL", () => {
+      wrapper.setState({url: " "});
+
+      assert.isNull(wrapper.instance().validateForm());
+      assert.isTrue(wrapper.state().validationError);
+    });
+
+    it("should return true for a correct custom screenshot URL", () => {
+      wrapper.setState({customScreenshotUrl: "foo"});
+
+      assert.isTrue(wrapper.instance().validateForm());
+    });
+
+    it("should return false for a incorrect custom screenshot URL", () => {
+      wrapper.setState({customScreenshotUrl: " "});
+
+      assert.isNull(wrapper.instance().validateForm());
+    });
+
+    it("should return true for an empty custom screenshot URL", () => {
+      wrapper.setState({customScreenshotUrl: ""});
+
+      assert.isTrue(wrapper.instance().validateForm());
+    });
+
+    it("should return false for file: protocol", () => {
+      wrapper.setState({customScreenshotUrl: "file:///C:/Users/foo"});
+
+      assert.isFalse(wrapper.instance().validateForm());
+    });
+  });
+
+  describe("#previewButton", () => {
+    beforeEach(() => setup({
+      site: {customScreenshotURL: "http://foo.com"},
+      previewResponse: null
+    }));
+
+    it("should render the preview button on invalid urls", () => {
+      assert.equal(0, wrapper.find(".preview").length);
+
+      wrapper.setState({customScreenshotUrl: " "});
+
+      assert.equal(1, wrapper.find(".preview").length);
+    });
+
+    it("should render the preview button when input value updated", () => {
+      assert.equal(0, wrapper.find(".preview").length);
+
+      wrapper.setState({customScreenshotUrl: "http://baz.com", screenshotPreview: null});
+
+      assert.equal(1, wrapper.find(".preview").length);
+    });
+  });
+
+  describe("preview request", () => {
+    beforeEach(() => {
+      setup({
+        site: {customScreenshotURL: "http://foo.com", url: "http://foo.com"},
+        previewResponse: null
+      });
+    });
+
+    it("shouldn't dispatch a request for invalid urls", () => {
+      wrapper.setState({customScreenshotUrl: " ", url: "foo"});
+
+      wrapper.find(".preview").simulate("click");
+
+      assert.notCalled(wrapper.props().dispatch);
+    });
+
+    it("should dispatch a PREVIEW_REQUEST", () => {
+      wrapper.setState({customScreenshotUrl: "screenshot"});
+      wrapper.find(".preview").simulate("click");
+
+      assert.calledTwice(wrapper.props().dispatch);
+      assert.calledWith(wrapper.props().dispatch, ac.AlsoToMain({
+        type: at.PREVIEW_REQUEST,
+        data: {url: "http://screenshot"}
+      }));
+      assert.calledWith(wrapper.props().dispatch, ac.UserEvent({
+        event: "PREVIEW_REQUEST",
+        source: "TOP_SITES"
+      }));
+    });
+  });
+
+  describe("#TopSiteLink", () => {
+    it("should display a TopSiteLink preview", () => {
+      assert.equal(wrapper.find(TopSiteLink).length, 1);
+    });
+
+    it("should display the preview screenshot", () => {
+      wrapper.setProps({site: {tippyTopIcon: "bar"}});
+
+      assert.equal(wrapper.find(".top-site-icon").getDOMNode().style["background-image"], "url(\"bar\")");
+
+      wrapper.setProps({previewResponse: "foo", previewUrl: "foo"});
+
+      assert.equal(wrapper.find(".top-site-icon").getDOMNode().style["background-image"], "url(\"foo\")");
+    });
+
+    it("should not render any icon on error", () => {
+      wrapper.setProps({previewResponse: ""});
+
+      assert.equal(wrapper.find(".top-site-icon").length, 0);
+    });
+  });
+
+  describe("#addMode", () => {
+    beforeEach(() => setup());
+
+    it("should render the component", () => {
+      assert.ok(wrapper.find(TopSiteForm).exists());
+    });
+    it("should have the correct header", () => {
+      assert.equal(wrapper.findWhere(n => n.length && n.props().id === "topsites_form_add_header").length, 1);
+    });
+    it("should have the correct button text", () => {
+      assert.equal(wrapper.findWhere(n => n.length && n.props().id === "topsites_form_save_button").length, 0);
+      assert.equal(wrapper.findWhere(n => n.length && n.props().id === "topsites_form_add_button").length, 1);
+    });
+    it("should not render a preview button", () => {
+      assert.equal(0, wrapper.find(".custom-image-input-container").length);
+    });
+    it("should call onClose if Cancel button is clicked", () => {
+      wrapper.find(".cancel").simulate("click");
+      assert.calledOnce(wrapper.instance().props.onClose);
+    });
+    it("should set validationError if url is empty", () => {
+      assert.equal(wrapper.state().validationError, false);
+      wrapper.find(".done").simulate("click");
+      assert.equal(wrapper.state().validationError, true);
+    });
+    it("should set validationError if url is invalid", () => {
+      wrapper.setState({"url": "not valid"});
+      assert.equal(wrapper.state().validationError, false);
+      wrapper.find(".done").simulate("click");
+      assert.equal(wrapper.state().validationError, true);
+    });
+    it("should call onClose and dispatch with right args if URL is valid", () => {
+      wrapper.setState({"url": "valid.com", "label": "a label"});
+      wrapper.find(".done").simulate("click");
+      assert.calledOnce(wrapper.instance().props.onClose);
+      assert.calledWith(
+        wrapper.instance().props.dispatch,
+        {
+          data: {site: {label: "a label", url: "http://valid.com"}, index: -1},
+          meta: {from: "ActivityStream:Content", to: "ActivityStream:Main"},
+          type: at.TOP_SITES_PIN
+        }
+      );
+      assert.calledWith(
+        wrapper.instance().props.dispatch,
+        {
+          data: {action_position: -1, source: "TOP_SITES", event: "TOP_SITES_EDIT"},
+          meta: {from: "ActivityStream:Content", to: "ActivityStream:Main"},
+          type: at.TELEMETRY_USER_EVENT
+        }
+      );
+    });
+    it("should not pass empty string label in dispatch data", () => {
+      wrapper.setState({"url": "valid.com", "label": ""});
+      wrapper.find(".done").simulate("click");
+      assert.calledWith(
+        wrapper.instance().props.dispatch,
+        {
+          data: {site: {url: "http://valid.com"}, index: -1},
+          meta: {from: "ActivityStream:Content", to: "ActivityStream:Main"},
+          type: at.TOP_SITES_PIN
+        }
+      );
+    });
+    it("should open the custom screenshot input", () => {
+      assert.isFalse(wrapper.state().showCustomScreenshotForm);
+
+      wrapper.find(".enable-custom-image-input").simulate("click");
+
+      assert.isTrue(wrapper.state().showCustomScreenshotForm);
+    });
+  });
+
+  describe("edit existing Topsite", () => {
+    beforeEach(() => setup({site: {url: "https://foo.bar", label: "baz", customScreenshotURL: "http://foo"}, index: 7}));
+
+    it("should render the component", () => {
+      assert.ok(wrapper.find(TopSiteForm).exists());
+    });
+    it("should have the correct header", () => {
+      assert.equal(wrapper.findWhere(n => n.props().id === "topsites_form_edit_header").length, 1);
+    });
+    it("should have the correct button text", () => {
+      assert.equal(wrapper.findWhere(n => n.props().id === "topsites_form_add_button").length, 0);
+      assert.equal(wrapper.findWhere(n => n.props().id === "topsites_form_save_button").length, 1);
+    });
+    it("should call onClose if Cancel button is clicked", () => {
+      wrapper.find(".cancel").simulate("click");
+      assert.calledOnce(wrapper.instance().props.onClose);
+    });
+    it("should show error and not call onClose or dispatch if URL is empty", () => {
+      wrapper.setState({"url": ""});
+      assert.equal(wrapper.state().validationError, false);
+      wrapper.find(".done").simulate("click");
+      assert.equal(wrapper.state().validationError, true);
+      assert.notCalled(wrapper.instance().props.onClose);
+      assert.notCalled(wrapper.instance().props.dispatch);
+    });
+    it("should show error and not call onClose or dispatch if URL is invalid", () => {
+      wrapper.setState({"url": "not valid"});
+      assert.equal(wrapper.state().validationError, false);
+      wrapper.find(".done").simulate("click");
+      assert.equal(wrapper.state().validationError, true);
+      assert.notCalled(wrapper.instance().props.onClose);
+      assert.notCalled(wrapper.instance().props.dispatch);
+    });
+    it("should call onClose and dispatch with right args if URL is valid", () => {
+      wrapper.find(".done").simulate("click");
+      assert.calledOnce(wrapper.instance().props.onClose);
+      assert.calledTwice(wrapper.instance().props.dispatch);
+      assert.calledWith(
+        wrapper.instance().props.dispatch,
+        {
+          data: {site: {label: "baz", url: "https://foo.bar", customScreenshotURL: "http://foo"}, index: 7},
+          meta: {from: "ActivityStream:Content", to: "ActivityStream:Main"},
+          type: at.TOP_SITES_PIN
+        }
+      );
+      assert.calledWith(
+        wrapper.instance().props.dispatch,
+        {
+          data: {action_position: 7, source: "TOP_SITES", event: "TOP_SITES_EDIT"},
+          meta: {from: "ActivityStream:Content", to: "ActivityStream:Main"},
+          type: at.TELEMETRY_USER_EVENT
+        }
+      );
+    });
+    it("should set customScreenshotURL to null if it was removed", () => {
+      wrapper.setState({customScreenshotUrl: ""});
+
+      wrapper.find(".done").simulate("click");
+
+      assert.calledWith(
+        wrapper.instance().props.dispatch,
+        {
+          data: {site: {label: "baz", url: "https://foo.bar", customScreenshotURL: null}, index: 7},
+          meta: {from: "ActivityStream:Content", to: "ActivityStream:Main"},
+          type: at.TOP_SITES_PIN
+        }
+      );
+    });
+    it("should call onClose and dispatch with right args if URL is valid (negative index)", () => {
+      wrapper.setProps({index: -1});
+      wrapper.find(".done").simulate("click");
+      assert.calledOnce(wrapper.instance().props.onClose);
+      assert.calledTwice(wrapper.instance().props.dispatch);
+      assert.calledWith(
+        wrapper.instance().props.dispatch,
+        {
+          data: {site: {label: "baz", url: "https://foo.bar", customScreenshotURL: "http://foo"}, index: -1},
+          meta: {from: "ActivityStream:Content", to: "ActivityStream:Main"},
+          type: at.TOP_SITES_PIN
+        }
+      );
+    });
+    it("should not pass empty string label in dispatch data", () => {
+      wrapper.setState({"label": ""});
+      wrapper.find(".done").simulate("click");
+      assert.calledWith(
+        wrapper.instance().props.dispatch,
+        {
+          data: {site: {url: "https://foo.bar", customScreenshotURL: "http://foo"}, index: 7},
+          meta: {from: "ActivityStream:Content", to: "ActivityStream:Main"},
+          type: at.TOP_SITES_PIN
+        }
+      );
+    });
+    it("should render the save button if custom screenshot request finished", () => {
+      wrapper.setState({customScreenshotUrl: "foo", screenshotPreview: "custom"});
+      assert.equal(0, wrapper.find(".preview").length);
+      assert.equal(1, wrapper.find(".done").length);
+    });
+    it("should render the save button if custom screenshot url was cleared", () => {
+      wrapper.setState({customScreenshotUrl: ""});
+      wrapper.setProps({site: {customScreenshotURL: "foo"}});
+      assert.equal(0, wrapper.find(".preview").length);
+      assert.equal(1, wrapper.find(".done").length);
+    });
+  });
+
+  describe("#previewMode", () => {
+    beforeEach(() => setup({previewResponse: null}));
+
+    it("should transition from save to preview", () => {
+      wrapper.setProps({site: {url: "https://foo.bar", customScreenshotURL: "baz"}, index: 7});
+
+      assert.equal(wrapper.findWhere(n => n.length && n.props().id === "topsites_form_save_button").length, 1);
+
+      wrapper.setState({customScreenshotUrl: "foo"});
+
+      assert.equal(wrapper.findWhere(n => n.length && n.props().id === "topsites_form_preview_button").length, 1);
+    });
+
+    it("should transition from add to preview", () => {
+      assert.equal(wrapper.findWhere(n => n.length && n.props().id === "topsites_form_add_button").length, 1);
+
+      wrapper.setState({customScreenshotUrl: "foo"});
+
+      assert.equal(wrapper.findWhere(n => n.length && n.props().id === "topsites_form_preview_button").length, 1);
+    });
+  });
+
+  describe("#validateUrl", () => {
+    it("should properly validate URLs", () => {
+      setup();
+      assert.ok(wrapper.instance().validateUrl("mozilla.org"));
+      assert.ok(wrapper.instance().validateUrl("https://mozilla.org"));
+      assert.ok(wrapper.instance().validateUrl("http://mozilla.org"));
+      assert.ok(wrapper.instance().validateUrl("https://mozilla.invisionapp.com/d/main/#/projects/prototypes"));
+      assert.ok(wrapper.instance().validateUrl("httpfoobar"));
+      assert.ok(wrapper.instance().validateUrl("httpsfoo.bar"));
+      assert.isNull(wrapper.instance().validateUrl("mozilla org"));
+      assert.isNull(wrapper.instance().validateUrl(""));
+    });
+  });
+
+  describe("#cleanUrl", () => {
+    it("should properly prepend http:// to URLs when required", () => {
+      setup();
+      assert.equal("http://mozilla.org", wrapper.instance().cleanUrl("mozilla.org"));
+      assert.equal("http://https.org", wrapper.instance().cleanUrl("https.org"));
+      assert.equal("http://httpcom", wrapper.instance().cleanUrl("httpcom"));
+      assert.equal("http://mozilla.org", wrapper.instance().cleanUrl("http://mozilla.org"));
+      assert.equal("https://firefox.com", wrapper.instance().cleanUrl("https://firefox.com"));
+    });
+  });
+});
+
+describe("<TopSiteList>", () => {
+  it("should render a TopSiteList element", () => {
+    const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} />);
+    assert.ok(wrapper.exists());
+  });
+  it("should render a TopSite for each link with the right url", () => {
+    const rows = [{url: "https://foo.com"}, {url: "https://bar.com"}];
+    const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} TopSites={{rows}} />);
+    const links = wrapper.find(TopSite);
+    assert.lengthOf(links, 2);
+    rows.forEach((row, i) => assert.equal(links.get(i).props.link.url, row.url));
+  });
+  it("should slice the TopSite rows to the TopSitesRows pref", () => {
+    const rows = [];
+    for (let i = 0; i < TOP_SITES_DEFAULT_ROWS * TOP_SITES_MAX_SITES_PER_ROW + 3; i++) {
+      rows.push({url: `https://foo${i}.com`});
+    }
+    const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} TopSites={{rows}} TopSitesRows={TOP_SITES_DEFAULT_ROWS} />);
+    const links = wrapper.find(TopSite);
+    assert.lengthOf(links, TOP_SITES_DEFAULT_ROWS * TOP_SITES_MAX_SITES_PER_ROW);
+  });
+  it("should fill with placeholders if TopSites rows is less than TopSitesRows", () => {
+    const rows = [{url: "https://foo.com"}, {url: "https://bar.com"}];
+    const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} TopSites={{rows}} TopSitesRows={1} />);
+    assert.lengthOf(wrapper.find(TopSite), 2, "topSites");
+    assert.lengthOf(wrapper.find(TopSitePlaceholder), TOP_SITES_MAX_SITES_PER_ROW - 2, "placeholders");
+  });
+  it("should fill any holes in TopSites with placeholders", () => {
+    const rows = [{url: "https://foo.com"}];
+    rows[3] = {url: "https://bar.com"};
+    const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} TopSites={{rows}} TopSitesRows={1} />);
+    assert.lengthOf(wrapper.find(TopSite), 2, "topSites");
+    assert.lengthOf(wrapper.find(TopSitePlaceholder), TOP_SITES_MAX_SITES_PER_ROW - 2, "placeholders");
+  });
+  it("should update state onDragStart and clear it onDragEnd", () => {
+    const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} />);
+    const instance = wrapper.instance();
+    const index = 7;
+    const link = {url: "https://foo.com"};
+    const title = "foo";
+    instance.onDragEvent({type: "dragstart"}, index, link, title);
+    assert.equal(instance.state.draggedIndex, index);
+    assert.equal(instance.state.draggedSite, link);
+    assert.equal(instance.state.draggedTitle, title);
+    instance.onDragEvent({type: "dragend"});
+    assert.deepEqual(instance.state, TopSiteList.DEFAULT_STATE);
+  });
+  it("should clear state when new props arrive after a drop", () => {
+    const site1 = {url: "https://foo.com"};
+    const site2 = {url: "https://bar.com"};
+    const rows = [site1, site2];
+    const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} TopSites={{rows}} />);
+    const instance = wrapper.instance();
+    instance.setState({
+      draggedIndex: 1,
+      draggedSite: site2,
+      draggedTitle: "bar",
+      topSitesPreview: []
+    });
+    wrapper.setProps({TopSites: {rows: [site2, site1]}});
+    assert.deepEqual(instance.state, TopSiteList.DEFAULT_STATE);
+  });
+  it("should dispatch events on drop", () => {
+    const dispatch = sinon.spy();
+    const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} dispatch={dispatch} />);
+    const instance = wrapper.instance();
+    const index = 7;
+    const link = {url: "https://foo.com", customScreenshotURL: "foo"};
+    const title = "foo";
+    instance.onDragEvent({type: "dragstart"}, index, link, title);
+    dispatch.reset();
+    instance.onDragEvent({type: "drop"}, 3);
+    assert.calledTwice(dispatch);
+    assert.calledWith(dispatch, {
+      data: {draggedFromIndex: 7, index: 3, site: {label: "foo", url: "https://foo.com", customScreenshotURL: "foo"}},
+      meta: {from: "ActivityStream:Content", to: "ActivityStream:Main"},
+      type: "TOP_SITES_INSERT"
+    });
+    assert.calledWith(dispatch, {
+      data: {action_position: 3, event: "DROP", source: "TOP_SITES"},
+      meta: {from: "ActivityStream:Content", to: "ActivityStream:Main"},
+      type: "TELEMETRY_USER_EVENT"
+    });
+  });
+  it("should make a topSitesPreview onDragEnter", () => {
+    const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} />);
+    const instance = wrapper.instance();
+    const site = {url: "https://foo.com"};
+    instance.setState({
+      draggedIndex: 4,
+      draggedSite: site,
+      draggedTitle: "foo"
+    });
+    const draggedSite = Object.assign({}, site, {isPinned: true, isDragged: true});
+    instance.onDragEvent({type: "dragenter"}, 2);
+    assert.ok(instance.state.topSitesPreview);
+    assert.deepEqual(instance.state.topSitesPreview[2], draggedSite);
+  });
+  it("should _makeTopSitesPreview correctly", () => {
+    const site1 = {url: "https://foo.com"};
+    const site2 = {url: "https://bar.com"};
+    const site3 = {url: "https://baz.com"};
+    const rows = [site1, site2, site3];
+    let wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} TopSites={{rows}} TopSitesRows={1} />);
+    let instance = wrapper.instance();
+    instance.setState({
+      draggedIndex: 0,
+      draggedSite: site1,
+      draggedTitle: "foo"
+    });
+    let draggedSite = Object.assign({}, site1, {isPinned: true, isDragged: true});
+    assert.deepEqual(instance._makeTopSitesPreview(1), [site2, draggedSite, site3, null, null, null, null, null]);
+    assert.deepEqual(instance._makeTopSitesPreview(2), [site2, site3, draggedSite, null, null, null, null, null]);
+    assert.deepEqual(instance._makeTopSitesPreview(3), [site2, site3, null, draggedSite, null, null, null, null]);
+    site2.isPinned = true;
+    assert.deepEqual(instance._makeTopSitesPreview(1), [site2, draggedSite, site3, null, null, null, null, null]);
+    assert.deepEqual(instance._makeTopSitesPreview(2), [site3, site2, draggedSite, null, null, null, null, null]);
+    site3.isPinned = true;
+    assert.deepEqual(instance._makeTopSitesPreview(1), [site2, draggedSite, site3, null, null, null, null, null]);
+    assert.deepEqual(instance._makeTopSitesPreview(2), [site2, site3, draggedSite, null, null, null, null, null]);
+    site2.isPinned = false;
+    assert.deepEqual(instance._makeTopSitesPreview(1), [site2, draggedSite, site3, null, null, null, null, null]);
+    assert.deepEqual(instance._makeTopSitesPreview(2), [site2, site3, draggedSite, null, null, null, null, null]);
+    site3.isPinned = false;
+    instance.setState({
+      draggedIndex: 1,
+      draggedSite: site2,
+      draggedTitle: "bar"
+    });
+    draggedSite = Object.assign({}, site2, {isPinned: true, isDragged: true});
+    assert.deepEqual(instance._makeTopSitesPreview(0), [draggedSite, site1, site3, null, null, null, null, null]);
+    assert.deepEqual(instance._makeTopSitesPreview(2), [site1, site3, draggedSite, null, null, null, null, null]);
+  });
+  it("should add a className hide-for-narrow to sites after 6/row", () => {
+    const rows = [];
+    for (let i = 0; i < TOP_SITES_MAX_SITES_PER_ROW; i++) {
+      rows.push({url: `https://foo${i}.com`});
+    }
+    const wrapper = mountWithIntl(<TopSiteList {...DEFAULT_PROPS} TopSites={{rows}} TopSitesRows={1} />);
+    assert.lengthOf(wrapper.find("li.hide-for-narrow"), 2);
+  });
+});
+
+describe("TopSitePlaceholder", () => {
+  it("should dispatch a TOP_SITES_EDIT action when edit-button is clicked", () => {
+    const dispatch = sinon.spy();
+    const wrapper =
+      shallowWithIntl(<TopSitePlaceholder dispatch={dispatch} index={7} />);
+
+    wrapper.find(".edit-button").first().simulate("click");
+
+    assert.calledOnce(dispatch);
+    assert.calledWithExactly(dispatch,
+      {type: at.TOP_SITES_EDIT, data: {index: 7}});
+  });
+});
+
+describe("#TopSiteFormInput", () => {
+  let wrapper;
+  let onChangeStub;
+
+  describe("no errors", () => {
+    beforeEach(() => {
+      onChangeStub = sinon.stub();
+
+      wrapper = mountWithIntl(<TopSiteFormInput titleId="topsites_form_title_label"
+        placeholderId="topsites_form_title_placeholder"
+        errorMessageId="topsites_form_url_validation"
+        onChange={onChangeStub}
+        value="foo" />);
+    });
+
+    it("should render the provided title", () => {
+      const title = wrapper.find(FormattedMessage);
+
+      assert.propertyVal(title.props(), "id", "topsites_form_title_label");
+    });
+
+    it("should render the provided value", () => {
+      const input = wrapper.find("input");
+
+      assert.equal(input.getDOMNode().value, "foo");
+    });
+
+    it("should render the clear button if cb is provided", () => {
+      assert.equal(wrapper.find(".icon-clear-input").length, 0);
+
+      wrapper.setProps({onClear: sinon.stub()});
+
+      assert.equal(wrapper.find(".icon-clear-input").length, 1);
+    });
+
+    it("should show the loading indicator", () => {
+      assert.equal(wrapper.find(".loading-container").length, 0);
+
+      wrapper.setProps({loading: true});
+
+      assert.equal(wrapper.find(".loading-container").length, 1);
+    });
+    it("should disable the input when loading indicator is present", () => {
+      assert.isFalse(wrapper.find("input").getDOMNode().disabled);
+
+      wrapper.setProps({loading: true});
+
+      assert.isTrue(wrapper.find("input").getDOMNode().disabled);
+    });
+  });
+
+  describe("with error", () => {
+    beforeEach(() => {
+      onChangeStub = sinon.stub();
+
+      wrapper = mountWithIntl(<TopSiteFormInput titleId="topsites_form_title_label"
+        placeholderId="topsites_form_title_placeholder"
+        onChange={onChangeStub}
+        validationError={true}
+        errorMessageId="topsites_form_url_validation"
+        value="foo" />);
+    });
+
+    it("should render the error message", () => {
+      assert.equal(wrapper.findWhere(n => n.props().id === "topsites_form_url_validation").length, 1);
+    });
+
+    it("should reset the error state on value change", () => {
+      wrapper.find("input").simulate("change", {target: {value: "bar"}});
+
+      assert.isFalse(wrapper.state().validationError);
+    });
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/components/Topics.test.jsx
@@ -0,0 +1,28 @@
+import {Topic, Topics} from "content-src/components/Topics/Topics";
+import React from "react";
+import {shallow} from "enzyme";
+import {shallowWithIntl} from "test/unit/utils";
+
+describe("<Topics>", () => {
+  it("should render a Topics element", () => {
+    const wrapper = shallowWithIntl(<Topics topics={[]} />);
+    assert.ok(wrapper.exists());
+  });
+  it("should render a Topic element for each topic with the right url", () => {
+    const data = [{name: "topic1", url: "https://topic1.com"}, {name: "topic2", url: "https://topic2.com"}];
+
+    const wrapper = shallow(<Topics topics={data} />);
+
+    const topics = wrapper.find(Topic);
+    assert.lengthOf(topics, 2);
+    topics.forEach((topic, i) => assert.equal(topic.props().url, data[i].url));
+  });
+  it("should render read more link", () => {
+    const readMoreEndpoint = "http://test-read-more.com";
+    const wrapper = shallow(<Topics topics={[]} read_more_endpoint={readMoreEndpoint} />);
+
+    const readMore = wrapper.find(".topic-read-more");
+    assert.lengthOf(readMore, 1);
+    assert.equal(readMore.props().href, readMoreEndpoint);
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/lib/detect-user-session-start.test.js
@@ -0,0 +1,90 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {DetectUserSessionStart} from "content-src/lib/detect-user-session-start";
+
+describe("detectUserSessionStart", () => {
+  let store;
+  class PerfService {
+    getMostRecentAbsMarkStartByName() { return 1234; }
+    mark() {}
+  }
+
+  beforeEach(() => {
+    store = {dispatch: () => {}};
+  });
+  describe("#sendEventOrAddListener", () => {
+    it("should call ._sendEvent immediately if the document is visible", () => {
+      const mockDocument = {visibilityState: "visible"};
+      const instance = new DetectUserSessionStart(store, {document: mockDocument});
+      sinon.stub(instance, "_sendEvent");
+
+      instance.sendEventOrAddListener();
+
+      assert.calledOnce(instance._sendEvent);
+    });
+    it("should add an event listener on visibility changes the document is not visible", () => {
+      const mockDocument = {visibilityState: "hidden", addEventListener: sinon.spy()};
+      const instance = new DetectUserSessionStart(store, {document: mockDocument});
+      sinon.stub(instance, "_sendEvent");
+
+      instance.sendEventOrAddListener();
+
+      assert.notCalled(instance._sendEvent);
+      assert.calledWith(mockDocument.addEventListener, "visibilitychange", instance._onVisibilityChange);
+    });
+  });
+  describe("#_sendEvent", () => {
+    it("should dispatch an action with the SAVE_SESSION_PERF_DATA", () => {
+      const dispatch = sinon.spy(store, "dispatch");
+      const instance = new DetectUserSessionStart(store);
+
+      instance._sendEvent();
+
+      assert.calledWith(dispatch, ac.AlsoToMain({
+        type: at.SAVE_SESSION_PERF_DATA,
+        data: {visibility_event_rcvd_ts: sinon.match.number}
+      }));
+    });
+
+    it("shouldn't send a message if getMostRecentAbsMarkStartByName throws", () => {
+      let perfService = new PerfService();
+      sinon.stub(perfService, "getMostRecentAbsMarkStartByName").throws();
+      const dispatch = sinon.spy(store, "dispatch");
+      const instance = new DetectUserSessionStart(store, {perfService});
+
+      instance._sendEvent();
+
+      assert.notCalled(dispatch);
+    });
+
+    it('should call perfService.mark("visibility_event_rcvd_ts")', () => {
+      let perfService = new PerfService();
+      sinon.stub(perfService, "mark");
+      const instance = new DetectUserSessionStart(store, {perfService});
+
+      instance._sendEvent();
+
+      assert.calledWith(perfService.mark, "visibility_event_rcvd_ts");
+    });
+  });
+
+  describe("_onVisibilityChange", () => {
+    it("should not send an event if visiblity is not visible", () => {
+      const instance = new DetectUserSessionStart(store, {document: {visibilityState: "hidden"}});
+      sinon.stub(instance, "_sendEvent");
+
+      instance._onVisibilityChange();
+
+      assert.notCalled(instance._sendEvent);
+    });
+    it("should send an event and remove the event listener if visibility is visible", () => {
+      const mockDocument = {visibilityState: "visible", removeEventListener: sinon.spy()};
+      const instance = new DetectUserSessionStart(store, {document: mockDocument});
+      sinon.stub(instance, "_sendEvent");
+
+      instance._onVisibilityChange();
+
+      assert.calledOnce(instance._sendEvent);
+      assert.calledWith(mockDocument.removeEventListener, "visibilitychange", instance._onVisibilityChange);
+    });
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/test/unit/content-src/lib/snippets.test.js
@@ -0,0 +1,541 @@
+import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
+import {
+  addSnippetsSubscriber,
+  SNIPPETS_UPDATE_INTERVAL_MS,
+  SnippetsMap,
+  SnippetsProvider
+} from "content-src/lib/snippets.js";
+import {combineReducers, createStore} from "redux";
+import {GlobalOverrider} from "test/unit/utils";
+import {INCOMING_MESSAGE_NAME} from "content-src/lib/init-store";
+import {reducers} from "common/Reducers.jsm";
+
+describe("SnippetsMap", () => {
+  let snippetsMap;
+  let dispatch;
+  let sandbox = sinon.sandbox.create();
+  let globals;
+  beforeEach(() => {
+    dispatch = sandbox.spy();
+    snippetsMap = new SnippetsMap(dispatch);
+    globals = new GlobalOverrider();
+    globals.set("addMessageListener", sandbox.spy());
+    globals.set("removeMessageListener", sandbox.spy());
+  });
+  afterEach(async () => {
+    sandbox.restore();
+    globals.restore();
+    await snippetsMap.clear();
+  });
+  describe("#set", () => {
+    it("should set a value without connecting a db", async () => {
+      await snippetsMap.set("foo", 123);
+      assert.equal(snippetsMap.get("foo"), 123);
+    });
+    it("should set an item in indexedDB when connected", async () => {
+      await snippetsMap.connect();
+      await snippetsMap.set("foo", 123);
+
+      // destroy the old snippetsMap, create a new one
+      snippetsMap = new SnippetsMap(dispatch);
+      await snippetsMap.connect();
+      assert.equal(snippetsMap.get("foo"), 123);
+    });
+  });
+  describe("#delete", () => {
+    it("should delete a value without connecting a db", async () => {
+      snippetsMap.set("foo", 123);
+      assert.isTrue(snippetsMap.has("foo"));
+
+      await snippetsMap.delete("foo");
+
+      assert.isFalse(snippetsMap.has("foo"));
+    });
+    it("should delete an item from indexedDB when connected", async () => {
+      await snippetsMap.connect();
+      await snippetsMap.set("foo", 123);
+      await snippetsMap.set("bar", 123);
+      await snippetsMap.delete("foo");
+
+      // destroy the old snippetsMap, create a new one
+      snippetsMap = new SnippetsMap(dispatch);
+      await snippetsMap.connect();
+      assert.isFalse(snippetsMap.has("foo"));
+      assert.isTrue(snippetsMap.has("bar"));
+    });
+  });
+  describe("#clear", () => {
+    it("should clear all items without connecting a db", async () => {
+      snippetsMap.set("foo", 123);
+      snippetsMap.set("bar", 123);
+      assert.propertyVal(snippetsMap, "size", 2);
+
+      await snippetsMap.clear();
+
+      assert.propertyVal(snippetsMap, "size", 0);
+    });
+    it("should clear the indexedDB store when connected", async () => {
+      await snippetsMap.connect();
+      snippetsMap.set("foo", 123);
+      snippetsMap.set("bar", 123);
+      await snippetsMap.clear();
+
+      // destroy the old snippetsMap, create a new one
+      snippetsMap = new SnippetsMap(dispatch);
+      await snippetsMap.connect();
+      assert.propertyVal(snippetsMap, "size", 0);
+    });
+    it("should send SNIPPETS_BLOCKLIST_CLEARED", async () => {
+      await snippetsMap.clear();
+
+      assert.calledOnce(dispatch);
+      assert.calledWithExactly(dispatch, ac.OnlyToMain({type: at.SNIPPETS_BLOCKLIST_CLEARED}));
+    });
+  });
+  describe("#.blockList", () => {
+    it("should return an empty array if blockList is not set", () => {
+      assert.deepEqual(snippetsMap.blockList, []);
+    });
+    it("should return the blockList it is set", () => {
+      snippetsMap.blockSnippetById(123);
+      assert.deepEqual(snippetsMap.blockList, [123]);
+    });
+  });
+  describe("#blockSnippetById(id)", () => {
+    it("should not modify the blockList if no id was passed in", () => {
+      snippetsMap.blockSnippetById(null);
+      assert.deepEqual(snippetsMap.blockList, []);
+    });
+    it("should add new ids to the blockList", () => {
+      snippetsMap.blockSnippetById(123);
+      assert.deepEqual(snippetsMap.blockList, [123]);
+    });
+    it("should dispatch a SNIPPETS_BLOCKLIST_UPDATED event", () => {
+      snippetsMap.blockSnippetById(789);
+
+      assert.calledOnce(dispatch);
+      assert.calledWith(dispatch, ac.AlsoToMain({type: at.SNIPPETS_BLOCKLIST_UPDATED, data: 789}));
+    });
+    it("should not add ids that are already blocked", () => {
+      snippetsMap.blockSnippetById(123);
+      snippetsMap.blockSnippetById(123);
+      snippetsMap.blockSnippetById(456);
+      assert.deepEqual(snippetsMap.blockList, [123, 456]);
+    });
+    it("should not call snippetsMap.set or dispatch an event for ids that are already blocked", async () => {
+      snippetsMap.set("blockList", [123, 456]);
+      // spy is added after so the first .set doesn't count
+      sandbox.spy(snippetsMap, "set");
+
+      await snippetsMap.blockSnippetById(123);
+
+      assert.notCalled(dispatch);
+      assert.notCalled(snippetsMap.set);
+    });
+  });
+  describe("#showFirefoxAccounts", () => {
+    it("should dispatch the a SHOW_FIREFOX_ACCOUNTS action", () => {
+      snippetsMap.showFirefoxAccounts();
+      assert.calledOnce(dispatch);
+      assert.equal(dispatch.firstCall.args[0].type, at.SHOW_FIREFOX_ACCOUNTS);
+    });
+  });
+  describe("#disableOnboarding", () => {
+    it("should dispatch a DISABLE_ONBOARDING action", () => {
+      snippetsMap.disableOnboarding();
+      assert.calledOnce(dispatch);
+      assert.equal(dispatch.firstCall.args[0].type, at.DISABLE_ONBOARDING);
+    });
+  });
+  describe("#getTotalBookmarksCount", () => {
+    it("should dispatch a TOTAL_BOOKMARKS_REQUEST and resolve with the right data", async () => {
+      const bookmarksPromise = snippetsMap.getTotalBookmarksCount();
+
+      assert.calledOnce(dispatch);
+      assert.equal(dispatch.firstCall.args[0].type, at.TOTAL_BOOKMARKS_REQUEST);
+      assert.calledWith(global.addMessageListener, INCOMING_MESSAGE_NAME);
+
+      // Call listener
+      const [, listener] = global.addMessageListener.firstCall.args;
+      listener({data: {type: at.TOTAL_BOOKMARKS_RESPONSE, data: 42}});
+
+      const result = await bookmarksPromise;
+
+      assert.equal(result, 42);
+      assert.calledWith(global.removeMessageListener, INCOMING_MESSAGE_NAME, listener);
+    });
+  });
+  describe("#getAddonsInfo", () => {
+    it("should dispatch a ADDONS_INFO_REQUEST and resolve with the right data", async () => {
+      const addonsPromise = snippetsMap.getAddonsInfo();
+
+      assert.calledOnce(dispatch);
+      assert.equal(dispatch.firstCall.args[0].type, at.ADDONS_INFO_REQUEST);
+      assert.calledWith(global.addMessageListener, INCOMING_MESSAGE_NAME);
+
+      // Call listener
+      const [, listener] = global.addMessageListener.firstCall.args;
+      const addonsInfo = {isFullData: true, addons: {foo: {}}};
+      listener({data: {type: at.ADDONS_INFO_RESPONSE, data: addonsInfo}});
+
+      const result = await addonsPromise;
+
+      assert.equal(result, addonsInfo);
+      assert.calledWith(global.removeMessageListener, INCOMING_MESSAGE_NAME, listener);
+    });
+  });
+});
+
+describe("SnippetsProvider", () => {
+  let sandbox;
+  let snippets;
+  let globals;
+  let dispatch;
+  beforeEach(() => {
+    sandbox = sinon.sandbox.create();
+    sandbox.stub(window, "fetch").returns(Promise.resolve(""));
+    globals = new GlobalOverrider();
+    globals.set("addMessageListener", sandbox.spy());
+    globals.set("removeMessageListener", sandbox.spy());
+    dispatch = sandbox.stub();
+  });
+  afterEach(async () => {
+    if (global.gSnippetsMap) {
+      await global.gSnippetsMap.clear();
+    }
+    delete global.gSnippetsMap;
+    globals.restore();
+    sandbox.restore();
+  });
+  it("should create a gSnippetsMap with a dispatch function", () => {
+    snippets = new SnippetsProvider(dispatch);
+    assert.instanceOf(global.gSnippetsMap, SnippetsMap);
+    assert.equal(global.gSnippetsMap._dispatch, dispatch);
+  });
+  describe("#init(options)", () => {
+    beforeEach(() => {
+      snippets = new SnippetsProvider(dispatch);
+      sandbox.stub(snippets, "_refreshSnippets").returns(Promise.resolve());
+      sandbox.stub(snippets, "_showRemoteSnippets");
+      sandbox.stub(snippets, "_noSnippetFallback");
+    });
+    it("should connect to the database by default", () => {
+      sandbox.stub(global.gSnippetsMap, "connect").returns(Promise.resolve());
+
+      snippets.init();
+
+      assert.calledOnce(global.gSnippetsMap.connect);
+    });
+    it("should log connection errors without throwing", async () => {
+      sandbox.stub(global.console, "error");
+      sandbox.stub(global.gSnippetsMap, "connect").returns(() => { throw new Error(); });
+      await snippets.init();
+
+      assert.calledOnce(global.console.error);
+    });
+    it("should not call connect if options.connect is false", async () => {
+      sandbox.stub(global.gSnippetsMap, "connect").returns(Promise.resolve());
+
+      await snippets.init({connect: false});
+
+      assert.notCalled(global.gSnippetsMap.connect);
+    });
+    it("should call _refreshSnippets and _showRemoteSnippets", async () => {
+      await snippets.init({connect: false});
+
+      assert.calledOnce(snippets._refreshSnippets);
+      assert.calledOnce(snippets._showRemoteSnippets);
+    });
+    it("should call _noSnippetFallback if _showRemoteSnippets throws an error", async () => {
+      snippets._showRemoteSnippets.callsFake(() => { throw new Error("error"); });
+      await snippets.init({connect: false});
+
+      assert.calledOnce(snippets._noSnippetFallback);
+    });
+    it("should set each item in .appData in gSnippetsMap as appData.{item}", async () => {
+      await snippets.init({connect: false, appData: {foo: 123, bar: "hello"}});
+      assert.equal(snippets.snippetsMap.get("appData.foo"), 123);
+      assert.equal(snippets.snippetsMap.get("appData.bar"), "hello");
+    });
+    it("should dispatch a Snippets:Enabled DOM event", async () => {
+      const spy = sinon.spy();
+      window.addEventListener("Snippets:Enabled", spy);
+      await snippets.init({connect: false});
+      assert.calledOnce(spy);
+      window.removeEventListener("Snippets:Enabled", spy);
+    });
+    it("should show the onboarding element if it exists", async () => {
+      const fakeEl = {style: {display: "none"}};
+      sandbox.stub(global.document, "getElementById").returns(fakeEl);
+      snippets = new SnippetsProvider(dispatch);
+
+      await snippets.init({connect: false});
+
+      assert.equal(fakeEl.style.display, "");
+    });
+    it("should add a message listener for incoming messages", async () => {
+      await snippets.init({connect: false});
+      assert.calledWith(global.addMessageListener, INCOMING_MESSAGE_NAME, snippets._onAction);
+    });
+    it("should set the blocklist based on init options", async () => {
+      const blockList = [1, 2, 3];
+      await snippets.init({appData: {blockList}});
+
+      assert.equal(snippets.snippetsMap.get("blockList"), blockList);
+    });
+  });
+  describe("#uninit", () => {
+    let fakeEl;
+    beforeEach(() => {
+      fakeEl = {style: {}};
+      sandbox.stub(global.document, "getElementById").returns(fakeEl);
+    });
+    it("should dispatch a Snippets:Disabled DOM event", () => {
+      const spy = sinon.spy();
+      window.addEventListener("Snippets:Disabled", spy);
+      snippets = new SnippetsProvider(dispatch);
+      snippets.uninit();
+      assert.calledOnce(spy);
+      window.removeEventListener("Snippets:Disabled", spy);
+    });
+    it("should hide the onboarding element if it exists", () => {
+      snippets = new SnippetsProvider(dispatch);
+      snippets.uninit();
+      assert.equal(fakeEl.style.display, "none");
+    });
+    it("should remove the message listener for incoming messages", () => {
+      snippets = new SnippetsProvider(dispatch);
+      snippets.uninit();
+      assert.calledWith(global.removeMessageListener, INCOMING_MESSAGE_NAME, snippets._onAction);
+    });
+  });
+  describe("#_refreshSnippets", () => {
+    let clock;
+    beforeEach(() => {
+      clock = sinon.useFakeTimers();
+      snippets = new SnippetsProvider(dispatch);
+      global.gSnippetsMap.set("snippets-cached-version", 4);
+    });
+    afterEach(() => {
+      clock.restore();
+    });
+    it("should clear gSnippetsMap if the cached version is different than the current version or missing", async () => {
+      sandbox.spy(global.gSnippetsMap, "clear");
+      await snippets.init({connect: false, appData: {version: 5, snippetsURL: "foo.com"}});
+      assert.calledOnce(global.gSnippetsMap.clear);
+
+      global.gSnippetsMap.clear.reset();
+      global.gSnippetsMap.delete("snippets-cached-version");
+      await snippets.init({connect: false, appData: {version: 5, snippetsURL: "foo.com"}});
+      assert.calledOnce(global.gSnippetsMap.clear);
+    });
+    it("should not clear gSnippetsMap if the cached version the same as the current version", async () => {
+      sandbox.spy(global.gSnippetsMap, "clear");
+      await snippets.init({connect: false, appData: {version: 4, snippetsURL: "foo.com"}});
+      assert.notCalled(global.gSnippetsMap.clear);
+    });
+    it("should fetch new data if no last update time was cached", async () => {
+      await snippets.init({connect: false, appData: {version: 4, snippetsURL: "foo.com"}});
+      assert.calledOnce(global.fetch);
+    });
+    it("should fetch new data if it has been at least SNIPPETS_UPDATE_INTERVAL_MS since the last update", async () => {
+      global.gSnippetsMap.set("snippets-last-update", Date.now());
+      clock.tick(SNIPPETS_UPDATE_INTERVAL_MS + 1);
+
+      await snippets.init({connect: false, appData: {version: 4, snippetsURL: "foo.com"}});
+
+      assert.calledOnce(global.fetch);
+    });
+    it("should NOT fetch new data if it has been less than 4 hours since the last update", async () => {
+      global.gSnippetsMap.set("snippets-last-update", Date.now());
+
+      clock.tick(5);
+
+      await snippets.init({connect: false, appData: {version: 4, snippetsURL: "foo.com"}});
+
+      assert.notCalled(global.fetch);
+    });
+    it("should set payload, last-update, and cached-version after fetching", async () => {
+      clock.tick(7);
+      global.fetch.returns(Promise.resolve({status: 200, text: () => Promise.resolve("foo123")}));
+
+      await snippets.init({connect: false, appData: {version: 5, snippetsURL: "foo.com"}});
+
+      assert.equal(global.gSnippetsMap.get("snippets"), "foo123");
+      assert.equal(global.gSnippetsMap.get("snippets-last-update"), 7);
+      assert.equal(global.gSnippetsMap.get("snippets-cached-version"), 5);
+    });
+    it("should catch fetch errors gracefully", async () => {
+      sandbox.stub(global.console, "error");
+      global.fetch.returns(Promise.reject(new Error({status: 400})));
+
+      await snippets.init({connect: false, appData: {version: 5, snippetsURL: "foo.com"}});
+
+      assert.calledOnce(global.console.error);
+    });
+  });
+  describe("#_showRemoteSnippets", () => {
+    beforeEach(() => {
+      snippets = new SnippetsProvider(dispatch);
+      sandbox.stub(snippets, "_refreshSnippets").returns(Promise.resolve());
+      sandbox.stub(snippets, "_noSnippetFallback");
+      let fakeEl = {style: {}, getElementsByTagName() { return [{parentNode: {replaceChild() {}}}]; }};
+      sandbox.stub(global.document, "getElementById").returns(fakeEl);
+    });
+    it("should call _noSnippetFallback if no snippets element exists", async () => {
+      global.gSnippetsMap.set("snippets", "foo123");
+      global.document.getElementById.returns(null);
+      await snippets.init({connect: false});
+
+      assert.calledOnce(snippets._noSnippetFallback);
+      const [error] = snippets._noSnippetFallback.firstCall.args;
+      assert.match(error.message, "No element was found");
+    });
+    it("should call _noSnippetFallback if no payload is found", async () => {
+      global.gSnippetsMap.set("snippets", "");
+      await snippets.init({connect: false});
+
+      const [error] = snippets._noSnippetFallback.firstCall.args;
+      assert.match(error.message, "No remote snippets were found");
+    });
+    it("should call _noSnippetFallback if the payload is not a string", async () => {
+      global.gSnippetsMap.set("snippets", true);
+      await snippets.init({connect: false});
+
+      const [error] = snippets._noSnippetFallback.firstCall.args;
+      assert.match(error.message, "Snippet payload was incorrectly formatted");
+    });
+    it("should not call _noSnippetFallback if the payload and element are ok", async () => {
+      global.gSnippetsMap.set("snippets", "foo123");
+      await snippets.init({connect: false});
+      assert.notCalled(snippets._noSnippetFallback);
+    });
+  });
+  describe("blocking", () => {
+    let containerEl;
+    beforeEach(() => {
+      snippets = new SnippetsProvider(dispatch);
+      containerEl = {style: {}};
+      sandbox.stub(global.document, "getElementById").returns(containerEl);
+    });
+    it("should set the blockList and hide the element if an incoming SNIPPET_BLOCKED message is received", async () => {
+      assert.deepEqual(global.gSnippetsMap.blockList, []);
+      await snippets.init({connect: false});
+      const action = {type: at.SNIPPET_BLOCKED, data: "foo"};
+
+      snippets._onAction({name: INCOMING_MESSAGE_NAME, data: action});
+
+      assert.deepEqual(global.gSnippetsMap.blockList, ["foo"]);
+      assert.calledWith(global.document.getElementById, "snippets-container");
+      assert.equal(containerEl.style.display, "none");
+    });
+    it("should not do anything if the incoming message is not a SNIPPET_BLOCKED action", async () => {
+      await snippets.init({connect: false});
+      const prevValue = containerEl.style.display;
+      const action = {type: "FOO", data: ["foo"]};
+
+      snippets._onAction({name: INCOMING_MESSAGE_NAME, data: action});
+      assert.deepEqual(global.gSnippetsMap.blockList, []);
+      assert.equal(containerEl.style.display, prevValue);
+    });
+  });
+});
+
+describe("addSnippetsSubscriber", () => {
+  let store;
+  let sandbox;
+  let snippets;
+  let asrouterContent;
+  function setSnippetEnabledPref(value) {
+    store.dispatch({type: at.PREF_CHANGED, data: {name: "feeds.snippets", value}});
+  }
+  beforeEach(() => {
+    sandbox = sinon.sandbox.create();
+    store = createStore(combineReducers(reducers));
+    sandbox.spy(store, "subscribe");
+    setSnippetEnabledPref(true);
+    ({snippets, asrouterContent} = addSnippetsSubscriber(store));
+
+    sandbox.spy(asrouterContent, "init");
+    sandbox.spy(asrouterContent, "uninit");
+    // These need to be stubbed because they do dom stuff
+    sandbox.stub(asrouterContent, "_mount");
+    sandbox.stub(asrouterContent, "_unmount");
+
+    sandbox.stub(snippets, "init").resolves();
+    sandbox.stub(snippets, "uninit");
+  });
+  afterEach(async () => {
+    sandbox.restore();
+    if (global.gSnippetsMap) {
+      await global.gSnippetsMap.clear();
+    }
+    delete global.gSnippetsMap;
+  });
+  it("should initialize feeds.snippets pref is true and SnippetsProvider if .initialize is true", () => {
+    store.dispatch({type: at.SNIPPETS_DATA, data: {}});
+    assert.calledOnce(snippets.init);
+  });
+  it("should not initialize if feeds.snippets pref is true and .initialize is false", () => {
+    store.dispatch({type: "FOO"});
+
+    assert.calledOnce(store.subscribe);
+    assert.notCalled(snippets.init);
+  });
+  it("should not initialize if disableSnippets pref is true", () => {
+    store.dispatch({type: at.PREF_CHANGED, data: {name: "disableSnippets", value: true}});
+    store.dispatch({type: at.SNIPPETS_DATA, data: {}});
+
+    assert.calledOnce(store.subscribe);
+    assert.notCalled(snippets.init);
+  });
+  it("should not initialize if feeds.snippets pref is false", () => {
+    setSnippetEnabledPref(false);
+    store.dispatch({type: at.SNIPPETS_DATA, data: {}});
+    assert.notCalled(snippets.init);
+  });
+  it("should uninitialize SnippetsProvider if SnippetsProvider has been initialized and feeds.snippets pref is false", async () => {
+    await store.dispatch({type: at.SNIPPETS_DATA, data: {}});
+    snippets.initialized = true;
+    setSnippetEnabledPref(false);
+    assert.calledOnce(snippets.uninit);
+  });
+  it("should uninitialize SnippetsProvider if SnippetsProvider has been initialized and disableSnippets pref is true", async () => {
+    await store.dispatch({type: at.SNIPPETS_DATA, data: {}});
+    snippets.initialized = true;
+    store.dispatch({type: at.PREF_CHANGED, data: {name: "disableSnippets", value: true}});
+    assert.calledOnce(snippets.uninit);
+  });
+  it("should not initialize snippets if asrouterExperimentEnabled pref is true", () => {
+    store.dispatch({type: "FOO"});
+    store.dispatch({type: at.PREF_CHANGED, data: {name: "asrouterExperimentEnabled", value: true}});
+
+    assert.calledOnce(store.subscribe);
+    assert.notCalled(snippets.init);
+  });
+  describe("asrouter", () => {
+    it("should initialize asrouter once if asrouterExperimentEnabled and snippets pref are both true", () => {
+      store.dispatch({type: "FOO"});
+      store.dispatch({type: at.PREF_CHANGED, data: {name: "asrouterExperimentEnabled", value: true}});
+
+      assert.calledOnce(asrouterContent.init);
+      assert.isTrue(asrouterContent.initialized);
+    });
+    it("should uninitialize asrouter if asrouterExperimentEnabled pref is turned off", () => {
+      store.dispatch({type: at.PREF_CHANGED, data: {name: "asrouterExperimentEnabled", value: true}});
+      assert.isTrue(asrouterContent.initialized);
+
+      store.dispatch({type: at.PREF_CHANGED, data: {name: "asrouterExperimentEnabled", value: false}});
+      assert.calledOnce(asrouterContent.uninit);
+      assert.isFalse(asrouterContent.initialized);
+    });
+    it("should uninitialize asrouter if snippets pref is turned off", () => {
+      store.dispatch({type: at.PREF_CHANGED, data: {name: "asrouterExperimentEnabled", value: true}});
+      assert.isTrue(asrouterContent.initialized);
+
+      store.dispatch({type: at.PREF_CHANGED, data: {name: "feeds.snippets", value: false}});
+      assert.calledOnce(asrouterContent.uninit);
+      assert.isFalse(asrouterContent.initialized);
+    });
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/webpack.prerender.config.js
@@ -0,0 +1,29 @@
+const path = require("path");
+const webpackConfig = require("./webpack.system-addon.config");
+const webpack = require("webpack");
+
+const srcPath = "content-src/activity-stream-prerender.jsx";
+
+const banner = `
+NOTE: This file is generated by webpack from ${srcPath}
+using the buildmc:html npm task.
+`;
+
+module.exports = Object.assign({}, webpackConfig, {
+  target: "node",
+  devtool: "sourcemap",
+  entry: path.join(__dirname, srcPath),
+  output: {
+    path: path.join(__dirname, "bin"),
+    filename: "prerender.js",
+    libraryTarget: "commonjs2"
+  },
+  externals: {
+    "prop-types": "commonjs prop-types",
+    "react": "commonjs react",
+    "react-dom": "commonjs react-dom"
+  },
+  plugins: [
+    new webpack.BannerPlugin(banner)
+  ]
+});
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/webpack.system-addon.config.js
@@ -0,0 +1,49 @@
+const path = require("path");
+const webpack = require("webpack");
+
+const absolute = relPath => path.join(__dirname, relPath);
+
+const resourcePathRegEx = /^resource:\/\/activity-stream\//;
+
+module.exports = {
+  entry: absolute("content-src/activity-stream.jsx"),
+  output: {
+    path: absolute("data/content"),
+    filename: "activity-stream.bundle.js"
+  },
+  devtool: "source-map",
+  plugins: [new webpack.optimize.ModuleConcatenationPlugin()],
+  module: {
+    rules: [
+      {
+        test: /\.jsx?$/,
+        exclude: /node_modules/,
+        loader: "babel-loader",
+        options: {presets: ["react"], plugins: [["transform-object-rest-spread", {"useBuiltIns": true}]]}
+      },
+      {
+        test: /\.jsm$/,
+        exclude: /node_modules/,
+        loader: "babel-loader",
+        // Converts .jsm files into common-js modules
+        options: {plugins: [["jsm-to-esmodules", {basePath: resourcePathRegEx, replace: true}], ["transform-object-rest-spread", {"useBuiltIns": true}]]}
+      }
+    ]
+  },
+  // This resolve config allows us to import with paths relative to the root directory, e.g. "lib/ActivityStream.jsm"
+  resolve: {
+    extensions: [".js", ".jsx"],
+    modules: [
+      "node_modules",
+      "."
+    ]
+  },
+  externals: {
+    "prop-types": "PropTypes",
+    "react": "React",
+    "react-dom": "ReactDOM",
+    "react-intl": "ReactIntl",
+    "redux": "Redux",
+    "react-redux": "ReactRedux"
+  }
+};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/activity-stream/yamscripts.yml
@@ -0,0 +1,70 @@
+# This file compiles to package.json scripts.
+# When you add or modify anything, you *MUST* run:
+#      npm run yamscripts
+# to compile your changes.
+
+scripts:
+  # Run the activity-stream mochitests
+  mochitest: (cd $npm_package_config_mc_dir && ./mach mochitest browser/extensions/activity-stream/test/functional/mochitest )
+
+  # Run the activity-stream mochitests with the browser toolbox debugger.
+  # Often handy in combination with adding a "debugger" statement in your
+  # mochitest somewhere.
+  mochitest-debug: (cd $npm_package_config_mc_dir && ./mach mochitest --jsdebugger browser/extensions/activity-stream/test/functional/mochitest)
+
+# bundle: Build all assets for activity stream
+  bundle:
+    locales: pontoon-to-json --src locales --dest data
+    webpack: webpack --config webpack.system-addon.config.js --display-optimization-bailout
+    css: node-sass --source-map true --source-map-contents content-src/styles -o css
+    html: rimraf prerendered && webpack --config webpack.prerender.config.js && node ./bin/render-activity-stream-html.js
+
+# buildmc: Export the bootstraped add-on to mozilla central
+  buildmc:
+    pre: rimraf $npm_package_config_mc_dir/browser/extensions/activity-stream/
+    bundle: => bundle
+    copy: rsync --exclude-from .mcignore -a . $npm_package_config_mc_dir/browser/extensions/activity-stream/
+    version: node ./bin/update-version.js $npm_package_config_mc_dir/browser/extensions/activity-stream
+    stringsExport: cp locales/en-US/strings.properties $npm_package_config_mc_dir/browser/locales/en-US/chrome/browser/activity-stream/newtab.properties
+    copyPingCentre: cpx "ping-centre/PingCentre.jsm" $npm_package_config_mc_dir/browser/modules
+
+# startmc: Start developing the bootstrapped add-on
+  startmc:
+    _parallel: true
+    pre: =>buildmc
+    # This copies only the system addon sub-folder; changing anything outside of it will need a full rebuild.
+    copy: cpx "{{,.}*,!(node_modules)/**/{,.}*}" $npm_package_config_mc_dir/browser/extensions/activity-stream/ -w
+    copyPingCentre: =>buildmc:copyPingCentre -- -w
+    webpack: =>bundle:webpack -- -w
+    css: =>bundle:css && =>bundle:css -- -w
+
+  # importmc: Import changes from mc to github repo
+  importmc: rsync --exclude-from .mcignore -a $npm_package_config_mc_dir/browser/extensions/activity-stream/ .
+
+  testmc:
+    lint: =>lint
+    build: =>bundle:webpack && =>bundle:locales
+    unit: karma start karma.mc.config.js || (cat logs/coverage/text.txt && exit 2)
+    post: cat logs/coverage/text-summary.txt
+
+  tddmc: karma start karma.mc.config.js --tdd
+
+  debugcoverage: open logs/coverage/report-html/index.html
+
+# lint: Run eslint and sass-lint
+  lint:
+    eslint: esw --ext=.js,.jsm,.json,.jsx .
+    sasslint: sass-lint -v -q
+
+# strings-import: Replace local strings with those from l10n-central
+  strings-import: node ./bin/strings-import.js
+
+# test: Run all tests once
+  test: =>testmc
+
+# tdd: Run content tests continuously
+  tdd: =>tddmc
+
+  # This is just to make sure we don't make commits with failing tests
+  # or uncompiled yamscripts.yml. Run automatically with husky.
+  prepush: =>lint && =>yamscripts