diff --git a/.pyup.yml b/.pyup.yml new file mode 100644 index 00000000..29c7c230 --- /dev/null +++ b/.pyup.yml @@ -0,0 +1,3 @@ +# see https://pyup.io/docs/configuration/ for all available options + +schedule: every week diff --git a/.travis.yml b/.travis.yml index eee45206..ad655cb2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,11 @@ _aliases: language: node_js node_js: stable +cache: + directories: + - node_modules +cache: pip + sudo: required jobs: include: @@ -52,6 +57,7 @@ jobs: provider: pages on: branch: master + python: '3.6' skip_cleanup: true local_dir: site github_token: $GITHUB_TOKEN diff --git a/docs/.dir-locals.el b/docs/.dir-locals.el new file mode 100644 index 00000000..e23c659d --- /dev/null +++ b/docs/.dir-locals.el @@ -0,0 +1,2 @@ +((markdown-mode + (mode . visual-line))) diff --git a/docs/accessibility-test-plan.md b/docs/accessibility-test-plan.md new file mode 100644 index 00000000..ebc28d2b --- /dev/null +++ b/docs/accessibility-test-plan.md @@ -0,0 +1,48 @@ +# Manual Test Plan + +## Keyboard Navigation +_< 3 hours_ + +Navigate the web content using only the keyboard +- Tab Order:`TAB`, as well as `SHIFT + TAB`, follows a logical and intuitive order. +- All controls, links, buttons, etc., get focused. +- Focus should be visibly apparent. +- When a modal or pop up window opens, focus shifts to the pop up. + - Focus and tab order is constrained within the modal. + - Modal can be exited via keyboard. + - When a pop up window is closed, focus returns to a logical point. +- Ensure that all content that is visually hidden is also hidden from the keyboard and/or a screen reader. _Except content specifically for screen reader users._ +- Firefox toolbar icon can be accessed by keyboard and screen reader users. + +## Page Structure +_3 hours_ +- Links and buttons have text that give context. +- All images contain alt text to describe the purpose or content of the image to a non-sighted user. +- A logical hierarchy of header tags has been used. +- [ARIA landmark roles](https://accessibility.oit.ncsu.edu/it-accessibility-at-nc-state/developers/accessibility-handbook/aria-landmarks/) have been utilized where applicable. +- ARIA attributes have been put into use. + - Any custom controls have been given the proper role attribute. + - State changes are provided via [ARIA states](http://www.w3.org/TR/wai-aria/states_and_properties#attrs_widgets_header). +- Form input fields and buttons have been labeled for screen reader users. + +## Color +_< 1 hour_ +- Text has sufficient color contrast against its background. + - Contrast ratio of 4.5:1 for normal text (less than 18 point or 14 point bold.) + - Contrast ratio of 3:1 for large text (at least 18 point or 14 point bold). +- Information conveyed via color is also available by other means. +- Buttons and links are visually apparent when they have focus. +- Focus remains apparent, and contrast remains sufficient, when simulating varying types of colorblindness. [Color blind simulators](https://www.toptal.com/designers/colorfilter) + +## UX Design Considerations +- Interactions available with a mouse are also available using a keyboard. +- Information conveyed visually is also available by other means. + - Pop-ups and other state changes are announced to screen readers using appropriate ARIA attributes. + - Temporary on-screen events give users ample time to receive conveyed information. +- Animations are not excessively flashy, as this can cause seizures in some users. + +## Tools and Resources +Use a variety of testing tools to analyze pages: +- aXe developer tools by Deque +- Browser developer tools to inspect HTML for logical heading structure and ARIA roles +- [Color blind simulators](https://www.toptal.com/designers/colorfilter) diff --git a/docs/contributing.md b/docs/contributing.md index 773ddd14..ee6f2fb8 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -6,7 +6,7 @@ The following are guidelines for contributing to this project. ## Code of Conduct -This repository is governed by Mozilla's code of conduct and etiquette guidelines. For more details please see the [Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/) and [Developer Etiquette Guidelines](https://bugzilla.mozilla.org/page.cgi?id=etiquette.html). +This repository is governed by Mozilla's code of conduct and etiquette guidelines. For more details please see the [Mozilla Community Participation Guidelines][community-guidelines] and [Developer Etiquette Guidelines][etiquette-guidelines]. ## How to Get Started @@ -14,16 +14,32 @@ Please refer to installation and build instructions in the [install documentatio ## How to Report Bugs -Please open [a new issue in the appropriate GitHub repository](https://github.com/mozilla-lockbox/lockbox-extension/issues/new) with steps to reproduce the problem you're experiencing. +Please open [a new issue in the appropriate GitHub repository][new-issue] with steps to reproduce the problem you're experiencing. Be sure to include as much information including screenshots, text output, and both your expected and actual results. ## How to Request Enhancements -First, please refer to the applicable [GitHub repository](https://github.com/orgs/mozilla-lockbox/) and search [the repository's GitHub issues](https://github.com/mozilla-lockbox/lockbox-extension/issues) to make sure your idea has not been (or is not still) considered. It may also be easier to see and search across all projects combined on our [Waffle.io planning board](https://waffle.io/mozilla-lockbox/lockbox-extension). +First, please refer to the applicable [GitHub repository][github-repos] and search [the repository's GitHub issues][issues-list] to make sure your idea has not been (or is not still) considered. It may also be easier to see and search across all projects combined on our [Waffle.io planning board][waffle]. -Then, please [create a new issue in the GitHub repository](https://github.com/mozilla-lockbox/lockbox-extension/issues/new) describing your enhancement. +Then, please [create a new issue in the GitHub repository][new-issue] describing your enhancement. Be sure to include as much detail as possible including step-by-step descriptions, specific examples, screenshots or mockups, and reasoning for why the enhancement might be worthwhile. Please keep in mind, by opening an issue we provide no guarantee the enhancement will be implemented. + +## How to Contribute Code + +Before you get started writing code, be sure what you plan to work on is something we'll be able to accept. The easiest way is to look through out list of [good first issues][good-first-issues] and find something that sounds interesting. + +If there's something else you'd like to work on, just add a comment in the relevant issue and we'll be happy to discuss your plans. If you have an idea that doesn't have an issue at all, be sure to [file an issue](#how-to-request-enhancements) first. + +Once you have a patch ready, submit a pull request and request a review from **@mozilla-lockbox/engineering**. From there, we'll guide you through the review process to the eventual landing of your code! We aim to respond to all review requests within two business days. + +[community-guidelines]: https://www.mozilla.org/about/governance/policies/participation/ +[etiquette-guidelines]: https://bugzilla.mozilla.org/page.cgi?id=etiquette.html +[new-issue]: https://github.com/mozilla-lockbox/lockbox-extension/issues/new +[github-repos]: https://github.com/orgs/mozilla-lockbox/ +[issues-list]: https://github.com/mozilla-lockbox/lockbox-extension/issues +[waffle]: https://waffle.io/mozilla-lockbox/lockbox-extension +[good-first-issues]: https://github.com/mozilla-lockbox/lockbox-extension/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22 diff --git a/docs/metrics.md b/docs/metrics.md index 513cd2de..dc84ec48 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -1,60 +1,72 @@ # Lockbox Metrics Plan -_Last Updated: Nov 28, 2017_ +_Last Updated: Feb 19, 2018_ - [Analysis](#analysis) - [Collection](#collection) - [Event Registration and Recording](#event-registration-and-recording) -- [Metrics Overview](#metrics-overview) -- [Non-Event Metrics](#non-event-metrics) +- [Scalar Metrics](#scalar-metrics) - [List of Events Currently Recorded](#list-of-events-currently-recorded) +- [Sketch of iOS Telemetry Plan](#sketch-of-ios-telemetry-plan) - [References](#references) -This is the metrics collection plan for Lockbox's alpha release. It documents all events currently collected through telemetry, as well those planned for collection but not currently implemented. It will be updated to reflect all new and planned data collection. +This is the metrics collection plan for Lockbox. It documents all events currently collected through telemetry, as well those planned for collection but not currently implemented. It will be updated periodically to reflect all new and planned data collection. ## Analysis -Data collection is done solely for the purpose of product development, improvement and maintenance. We are particularly interested in data that will help us answer the following questions. +Data collection is done solely for the purpose of product development, improvement and maintenance. Specifically, it is done to help its creators examine the validity of the following hypothesis. + +Core Hypothesis: **We believe that people want the browser to do more than only remember their passwords.** + +We will know this to be true when: + +1. The password generator is clicked 20% of the time a new entry is created. **This will indicate that users value the ability to create secure passwords.** (Events regarding password generation will be added when feature development is complete) + +2. 75% of Lockbox downloads result in a Firefox account attached. **This will indicate that users value secure storage for their credentials.** We currently record the event `fxaUpgrade` to know whether a user has attached an Firefox account to their lockbox installation. + +3. 60% of users choose to import their existing credentials from Firefox into Lockbox. **This will indicate that users trust lockbox more than the browser for managing their credentials.** (Events regarding the importing of credentials from the firefox password manager will be added when feature development is complete) + +4. We observe increased engagement with the management system (Create-Read-Update-Delete; CRUD) for users that import their credentials. **This will indicate that users value greater visibility into the number of accounts that they have.** We currently record `render` events when a user opens the credential manager. + +5. CRUD usage rates are comparable to Firefox login manager usage prior to lockbox installation. **This will indicate that users value Lockbox's credential management system, and use it to access credentials when they are needed.** Firefox telemetry currently collects data on password autofill usage, which requires credentials be stored in the firefox password manager. We plan to compare lockbox credential usage (e.g. via the `usernameCopied` and `passwordCopied` lockbox events) to pre-lockbox autofill frequencies on a per-user basis. + +6. 20% of Lockbox users access their datastore on more than 1 device, **indicating that users value having a single datastore of credentials.** + + +Other questions we aim to answer through data collection, but are not directly related to the hypothesis above: - Do people Save Passwords in Lockbox? - - How many? (measured by count of items saved per user) - - How often? (number of credentials saved per user per time interval) + - How many? (measured by count of items saved per user) + - How often? (number of credentials saved per user per time interval) - Do people create their own passwords or use Lockbox to generate them? - - Ratio: (Number of times the PW generator is used when storing an item) / (number of credentials stored) + - Ratio: (Number of times the PW generator is used when storing an item) / (number of credentials stored) +- When using the pw generator, do people create purely random passwords or customize them with their own input? (if this is going to be in the final design) - Do people use the passwords they store on Lockbox? - - How many times (per some unit of time) do stored credentials get auto-filled or copied to the clipboard? - - How many times do users click to reveal a password? -- How well does does auto-filling credentials work **(not in alpha)**? - - When credentials are auto-filled, are they filled into the correct fields? - - How often must the user make a change to what fields were filled? - - How to measure these things??? is there an easier way than just asking if the auto-fill didn't work? + - How many times (per some unit of time) do stored credentials get filled? + - How many times (per some unit of time) do stored credentials get copied? +- How many times do users click to reveal a password? - Do people continue to use Lockbox after first use? - - Out of those who install, how many use it more than once? + - Out of those who install, how many use it more than once? - Where are the drop-off points in the user flow? - - Do the majority of people make it all the way through the setup process? - - Once initially setup, do people continue to add credentials? -- What are people's opinions on LB - - Feedback forms -- Do people sync their passwords **(not in alpha)**? - - How does syncing affect engagement? -- What type of sites do people use Lockbox with? - - Do they use Lockbox only for their most sensitive accounts? + - Do the majority of people make it all the way through the setup process? + - Once initially setup, do people continue to add credentials? +- Do people sync their passwords between Firefox instances? + - How does syncing affect engagement? -## Collection -**Note:** *This is the collection plan for our internal alpha release. For our beta release will be taking advantage of test pilot's telemetry API. The metrics plan for beta will be described in a separate document.* +## Collection At this point, all measurements related to Lockbox will be made client-side. However, future releases will give users the option to sync their Lockbox data via an FxA account, at which point additional measurements will be logged server-side through the FxA data pipeline. We are not directly responsible for the measurements made through that mechanism. -For our internal alpha release, we will be making use of the public JavaScript API that allows recording and sending of event data through an add-on. **This means that for our alpha release we will only be collecting event-based data**. The API is documented here: +For our internal alpha release, we will be making use of the public JavaScript API that allows recording and sending of event data and scalar data through an add-on. The API is documented here: https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/telemetry/collection/events.html#the-api -Once the events are logged in the client they should appear in [about:telemetry](about:telemetry). From there they will be submitted in the main ping payload under `processes.dynamic.events` and available through the usual services (STMO and ATMO), as well as amplitude. +Once events are logged in the client they should appear in [about:telemetry](about:telemetry). From there they will be submitted in the main ping payload under `processes.dynamic.events` and available through the usual services (STMO and ATMO), as well as amplitude. ### Event Registration and Recording @@ -94,33 +106,35 @@ When recording, we can use `null` for `value`. See the Events section for specific examples of event registration and recording. -## Metrics Overview - -(this section may redundant with analysis section) -For alpha, we'd like to (ideally) like to be able to track the following general categories of things: +#### Scalar recording -- The setup flow, so we can know at what points (if any) people quit the flow before finishing it -- Top-level interactions centered around use of the Lockbox toolbar icon. This includes interactions within the initial doorhanger that is displayed when the user clicks the icon. -- Interactions with the list of the user's Lockbox items (credentials) -- Interactions with the add / modify dialogs used to enter / edit item information -- Changes to the datastore that actually contains the user's items, in addition to user actions that lead to those changes -- When the user submits feedback about Lockbox -- Usage of the copy and reveal functions for stored Lockbox items. +We use the js api for scalar recording as well. Here registration happens with the following syntax: -Each of these are described below within their own Events subsection. - - -## Non-Event Metrics +```javascript +Services.telemetry.registerScalars(category, { + "scalar_name": { + kind: services.Telemetry.SCALAR_TYPE_COUNT, // SCALAR_TYPE_COUNT, SCALAR_TYPE_BOOLEAN. or SCALAR_TYPE_STRING + keyed: false, + record_on_release: false, // NEEDS TO BE SET TO RECORD ON RELEASE CHANNEL + expired: false, + } +``` +We set scalar values in the following way: -These are the metrics we plan to collect regarding the state of user datastores. Note that we won't be able to record these directly for alpha. We will have to infer them from the event data. +```javascript +Services.telemetry.scalarSet( + "category.scalar_name", value +); +``` +e.g. `lockboxV1.datastoreCount` for the scalar name. -- `n_items` The number of credentials that exist in the user's datastore. Integer +We can also use `scalarAdd` to increment a scalar value by some amount. -- `n_notes` The number of items for which the user has manually entered custom notes for. Integer +## Scalar Metrics -- `timestamp_last` The timestamp of the last edit the user made to the datastore. Does not necessarily correspond to the last time they opened the CRUD editor. +These are the metrics we currently collect regarding the state of user datastores. -- `n_uses` The number of times a user copied or auto-filled a Lockbox item. +- `datastoreCount` (integer). Current count of the number of items in the user's datastore. Note that this scalar is only updated when the user renders their full item list, either in the management view or in the doorhanger. So when testing whether this scalar is accurately updated, please re-render the item list. ## List of Events Currently Recorded @@ -150,20 +164,35 @@ All events are currently implemented under the **category: lockboxV0**. The `ext 12. `resetCompleted` fires when the user completes a reset of their Lockbox data in the Lockbox settings. **objects**: settings -## List of Planned Events +13. `fxaStart` fires when a user clicks the sign-in or sign-up button from the manager or firstrun screen. used to log user initiating fxa auth process. **objects**: welcomeSignin, manageAcctCreate, manageAcctSignin, unlockSignin + +14. `fxaAuth` has methods `fxaUpgrade`, `fxaSignin` and `fxaSignout` that fire when the user initially adds their fxa account to lockbox, signs in after having added their fxa account previously, or signs out of fxa. **object**: accounts + +15. `fxaFail` fires when the fxa process fails **objects**: accounts + +## Sketch of iOS Telemetry Plan + +These events are based on the invisionapp design plan + +1. `fxaStart` fires when a user taps the sign-in or sign-up button from the welcome screen. used to log user initiating fxa auth process. + +2. `fxaAuth` has methods `fxaSignin` and `fxaSignout` that fire when the user signs into or out of their fxa account. + +3. `touchIdEnabled`, `faceIdEnabled`, `touchIdSkipped`, `faceIdSkipped` fire when a user successfully authorizes the use of touchID/faceID to unlock lockbox or taps to skip. -These events will be implemented once the corresponding functionality is available. +4. `browserEnabled` fires when user successfully adds lockbox integration to their browser. **objects**: `firefox`, `chrome`, `safari` -1. `fxaSignIn` fires when someone clicks the signin button during firstrun. **objects**: fxaSignInPage. +5. `usernameCopied` and `passwordCopied` fire when a user copies their username or password from an item. **objects**: itemList -2. `confirmPW` fires when the user clicks the button to confirm their FxA pw. **objects**: confirmPWButton +6. `itemSelected` fires when a user taps an item in the itemlist. **objects** itemList -3. `doorhangerItemSelected` fires when a user clicks an item in the doorhanger's itemlist. **objects** doorhanger +7. `itemShow` fires when a user taps to view item details in the itemlist. **objects** itemList -4. `doorhangerItemCopied` fires when a user copies an item's username/password from the doorhanger's entry view. **objects** doorhangerEntryDetails. +8. `settingsTap` fires when a user taps an entry on the settings page. **object** will label the setting that was tapped -5. `doorhangerAddClick` fires when the user clicks to add a new entry from the doorhanger. **objects** doorhanger +9. `settingsChanged` fires when a user toggles a changeable setting. **object** will label the setting that was toggled +10. `feedbackSent` Fires when a user sends feedback through the feedback form. --- diff --git a/docs/release-notes.md b/docs/release-notes.md index 31f60b1f..67ec2e72 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -1,8 +1,36 @@ # Lockbox Release Notes +## 0.1.8-alpha + +_Date: 2018-03-08_ + +### What's New + +- Added support For Telemetry Scalars so we can easily tell how many items are stored in your Lockbox datastore ([#552](https://github.com/mozilla-lockbox/lockbox-extension/pull/552)) +- Made it so the search box is automatically focused so you can start typing to search your entries immediately ([#573](https://github.com/mozilla-lockbox/lockbox-extension/issues/573)) +- The doorhanger also automatically fills the search with the domain of the current page you're viewing to help you quickly see matching entries ([#616](https://github.com/mozilla-lockbox/lockbox-extension/pull/616)) +- Improved contrast and colors of the entry list for accessibility ([#560](https://github.com/mozilla-lockbox/lockbox-extension/pull/560)) +- Improved interface colors and styles for entry list items ([#553](https://github.com/mozilla-lockbox/lockbox-extension/pull/553)) +- Improved search bar interface style with a simpler "Clear" button ([#562](https://github.com/mozilla-lockbox/lockbox-extension/pull/562)) +- Re-ordered the create/edit entry interface with improved spacing and styles ([#567](https://github.com/mozilla-lockbox/lockbox-extension/pull/567)) + +### What's Fixed + +- Item notes with line breaks properly show those separate lines when editing ([#596](https://github.com/mozilla-lockbox/lockbox-extension/pull/596)) +- The "reset Lockbox" settings interface fits better in about:addons ([#603](https://github.com/mozilla-lockbox/lockbox-extension/pull/603)) +- Fixed alignment on the entry detail view so the buttons don't jump when switching between edit and view modes ([#608](https://github.com/mozilla-lockbox/lockbox-extension/pull/608)) + +### Known Issues + +* Profile information about you is only fetched and updated when you sign in; any changes made to your Firefox Accounts display name or avatar will not be displayed in Lockbox until you sign in again. +* Once you link a Firefox Account to Lockbox, you cannot unlink it from that account. +* Once you link a Firefox Account to Lockbox, signing in with a different account can render Lockbox unusable until you quit and restart Firefox. +* Once you link a Firefox Account to Lockbox, resetting your Firefox Account password through "forgot your password" will render all your logins inaccessible; the only recourse is to reset Lockbox and start over. +* Firefox's default prompt to save logins is only disabled on new installs of this extension; updating Lockbox will not change your current Firefox preferences. + ## 0.1.7-alpha1 -_Dtae: 2018-02-23_ +_Date: 2018-02-23_ This release is to address a critical defect from the previous release. @@ -10,6 +38,8 @@ This release is to address a critical defect from the previous release. * If you linked your Firefox Account, Lockbox would stop working when you restart Firefox ([#568](https://github.com/mozilla-lockbox/lockbox-extension/issues/568)) +### Known Issues + * Profile information about you is only fetched and updated when you sign in; any changes made to your Firefox Accounts display name or avatar will not be displayed in Lockbox until you sign in again. * Once you link a Firefox Account to Lockbox, you cannot unlink it from that account. * Once you link a Firefox Account to Lockbox, signing in with a different account can render Lockbox unusable until you quit and restart Firefox. diff --git a/package-lock.json b/package-lock.json index af74f704..dfc547af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lockbox", - "version": "0.1.7-alpha1", + "version": "0.1.8-alpha", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -361,7 +361,7 @@ "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true }, "arr-union": { @@ -1253,6 +1253,90 @@ "babel-core": "6.26.0", "babel-preset-minify": "0.3.0", "webpack-sources": "1.0.1" + }, + "dependencies": { + "babel-plugin-transform-member-expression-literals": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.9.0.tgz", + "integrity": "sha512-bxtac+8w755ctVeDs4vU98RhWY49eW1wO02HAN+eirZYSKk/dVrKONIznXbHmxWKxT4UX1rpTKOCyezuzLpbTw==", + "dev": true + }, + "babel-plugin-transform-merge-sibling-variables": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.9.0.tgz", + "integrity": "sha512-9G1URVEEKoQLDqe0GwqYudECN7kE/q0OCNo5TiD1iwWnnaKi97xY915l5r2KKUvNflXEm9c3faNWknSXYQ7h6Q==", + "dev": true + }, + "babel-plugin-transform-minify-booleans": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.0.tgz", + "integrity": "sha512-JtpyTRyF+wF/r7GSxpRbNCrVve5M/aCC8xoGcnFItaPUDqjxKmFYvBzMc9u+g0lgo8NWjuZLc16MYaIwkHKD/A==", + "dev": true + }, + "babel-plugin-transform-property-literals": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.0.tgz", + "integrity": "sha512-B8s+71+4DPye9+pmZiPGgLPy3YqcmIuvE/9UcZLczPlwL5ALwF6qRUdLC3Fk17NhL6jxp4u33ZVZ8R4kvASPzw==", + "dev": true, + "requires": { + "esutils": "2.0.2" + } + }, + "babel-plugin-transform-remove-console": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.9.0.tgz", + "integrity": "sha512-mck9//yGTwObqqqDzY/sISO88/5/XfIB3ILb4uJLXk2xq124NT4yQVjFSRgVSbLcNq8OyBAn2acxKUqg4W/okQ==", + "dev": true + }, + "babel-plugin-transform-remove-debugger": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.9.0.tgz", + "integrity": "sha512-i/HWGjsmL2d1N2dl+eIzf44XpSP5v7hi1/GXB0xzom9kjrU8js3T8Kadizn95ZxfHK592Vg8P4JJWP/fvimEWw==", + "dev": true + }, + "babel-plugin-transform-simplify-comparison-operators": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.0.tgz", + "integrity": "sha512-EJyfYeph0CSekwQuwWVwJqy2go/bETkR95iaWQ/HTUis7tkCGNYmXngaFzuIXdmoPXfvmXYCvAXR4/93hqHVjw==", + "dev": true + }, + "babel-plugin-transform-undefined-to-void": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.0.tgz", + "integrity": "sha512-AVDVEmp0S9mbF1O8zekWbsOOmqnR08PZah5NRZJqSvJnFgiL0ep4Lwo4EymH8OieJR2QgQdR3q71TNW+wiVn4g==", + "dev": true + }, + "babel-preset-minify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/babel-preset-minify/-/babel-preset-minify-0.3.0.tgz", + "integrity": "sha512-+VV2GWEyak3eDOmzT1DDMuqHrw3VbE9nBNkx2LLVs4pH/Me32ND8DRpVDd8IRvk1xX5p75nygyRPtkMh6GIAbQ==", + "dev": true, + "requires": { + "babel-plugin-minify-builtins": "0.3.0", + "babel-plugin-minify-constant-folding": "0.3.0", + "babel-plugin-minify-dead-code-elimination": "0.3.0", + "babel-plugin-minify-flip-comparisons": "0.3.0", + "babel-plugin-minify-guarded-expressions": "0.3.0", + "babel-plugin-minify-infinity": "0.3.0", + "babel-plugin-minify-mangle-names": "0.3.0", + "babel-plugin-minify-numeric-literals": "0.3.0", + "babel-plugin-minify-replace": "0.3.0", + "babel-plugin-minify-simplify": "0.3.0", + "babel-plugin-minify-type-constructors": "0.3.0", + "babel-plugin-transform-inline-consecutive-adds": "0.3.0", + "babel-plugin-transform-member-expression-literals": "6.9.0", + "babel-plugin-transform-merge-sibling-variables": "6.9.0", + "babel-plugin-transform-minify-booleans": "6.9.0", + "babel-plugin-transform-property-literals": "6.9.0", + "babel-plugin-transform-regexp-constructors": "0.3.0", + "babel-plugin-transform-remove-console": "6.9.0", + "babel-plugin-transform-remove-debugger": "6.9.0", + "babel-plugin-transform-remove-undefined": "0.3.0", + "babel-plugin-transform-simplify-comparison-operators": "6.9.0", + "babel-plugin-transform-undefined-to-void": "6.9.0", + "lodash.isplainobject": "4.0.6" + } + } } }, "babel-plugin-check-es2015-constants": { @@ -1996,24 +2080,6 @@ "integrity": "sha512-iZsYAIjYLLfLK0yN5WVT7Xf7Y3wQ9Z75j9A8q/0IglQSpUt2ppTdHlwl/GeaXnxdaSmsxBu861klbTBbv2n+RA==", "dev": true }, - "babel-plugin-transform-member-expression-literals": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.9.0.tgz", - "integrity": "sha512-bxtac+8w755ctVeDs4vU98RhWY49eW1wO02HAN+eirZYSKk/dVrKONIznXbHmxWKxT4UX1rpTKOCyezuzLpbTw==", - "dev": true - }, - "babel-plugin-transform-merge-sibling-variables": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.9.0.tgz", - "integrity": "sha512-9G1URVEEKoQLDqe0GwqYudECN7kE/q0OCNo5TiD1iwWnnaKi97xY915l5r2KKUvNflXEm9c3faNWknSXYQ7h6Q==", - "dev": true - }, - "babel-plugin-transform-minify-booleans": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.0.tgz", - "integrity": "sha512-JtpyTRyF+wF/r7GSxpRbNCrVve5M/aCC8xoGcnFItaPUDqjxKmFYvBzMc9u+g0lgo8NWjuZLc16MYaIwkHKD/A==", - "dev": true - }, "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", @@ -2036,15 +2102,6 @@ } } }, - "babel-plugin-transform-property-literals": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.0.tgz", - "integrity": "sha512-B8s+71+4DPye9+pmZiPGgLPy3YqcmIuvE/9UcZLczPlwL5ALwF6qRUdLC3Fk17NhL6jxp4u33ZVZ8R4kvASPzw==", - "dev": true, - "requires": { - "esutils": "2.0.2" - } - }, "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", @@ -2100,18 +2157,6 @@ "integrity": "sha512-h92YHzyl042rb0naKO8frTHntpRFwRgKkfWD8602kFHoQingjJNtbvZzvxqHncJ6XmKVyYvfrBpDOSkCTDIIxw==", "dev": true }, - "babel-plugin-transform-remove-console": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.9.0.tgz", - "integrity": "sha512-mck9//yGTwObqqqDzY/sISO88/5/XfIB3ILb4uJLXk2xq124NT4yQVjFSRgVSbLcNq8OyBAn2acxKUqg4W/okQ==", - "dev": true - }, - "babel-plugin-transform-remove-debugger": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.9.0.tgz", - "integrity": "sha512-i/HWGjsmL2d1N2dl+eIzf44XpSP5v7hi1/GXB0xzom9kjrU8js3T8Kadizn95ZxfHK592Vg8P4JJWP/fvimEWw==", - "dev": true - }, "babel-plugin-transform-remove-undefined": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.3.0.tgz", @@ -2130,12 +2175,6 @@ "babel-runtime": "6.23.0" } }, - "babel-plugin-transform-simplify-comparison-operators": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.0.tgz", - "integrity": "sha512-EJyfYeph0CSekwQuwWVwJqy2go/bETkR95iaWQ/HTUis7tkCGNYmXngaFzuIXdmoPXfvmXYCvAXR4/93hqHVjw==", - "dev": true - }, "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", @@ -2146,12 +2185,6 @@ "babel-types": "6.25.0" } }, - "babel-plugin-transform-undefined-to-void": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.0.tgz", - "integrity": "sha512-AVDVEmp0S9mbF1O8zekWbsOOmqnR08PZah5NRZJqSvJnFgiL0ep4Lwo4EymH8OieJR2QgQdR3q71TNW+wiVn4g==", - "dev": true - }, "babel-polyfill": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", @@ -2266,37 +2299,6 @@ "babel-plugin-transform-flow-strip-types": "6.22.0" } }, - "babel-preset-minify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/babel-preset-minify/-/babel-preset-minify-0.3.0.tgz", - "integrity": "sha512-+VV2GWEyak3eDOmzT1DDMuqHrw3VbE9nBNkx2LLVs4pH/Me32ND8DRpVDd8IRvk1xX5p75nygyRPtkMh6GIAbQ==", - "dev": true, - "requires": { - "babel-plugin-minify-builtins": "0.3.0", - "babel-plugin-minify-constant-folding": "0.3.0", - "babel-plugin-minify-dead-code-elimination": "0.3.0", - "babel-plugin-minify-flip-comparisons": "0.3.0", - "babel-plugin-minify-guarded-expressions": "0.3.0", - "babel-plugin-minify-infinity": "0.3.0", - "babel-plugin-minify-mangle-names": "0.3.0", - "babel-plugin-minify-numeric-literals": "0.3.0", - "babel-plugin-minify-replace": "0.3.0", - "babel-plugin-minify-simplify": "0.3.0", - "babel-plugin-minify-type-constructors": "0.3.0", - "babel-plugin-transform-inline-consecutive-adds": "0.3.0", - "babel-plugin-transform-member-expression-literals": "6.9.0", - "babel-plugin-transform-merge-sibling-variables": "6.9.0", - "babel-plugin-transform-minify-booleans": "6.9.0", - "babel-plugin-transform-property-literals": "6.9.0", - "babel-plugin-transform-regexp-constructors": "0.3.0", - "babel-plugin-transform-remove-console": "6.9.0", - "babel-plugin-transform-remove-debugger": "6.9.0", - "babel-plugin-transform-remove-undefined": "0.3.0", - "babel-plugin-transform-simplify-comparison-operators": "6.9.0", - "babel-plugin-transform-undefined-to-void": "6.9.0", - "lodash.isplainobject": "4.0.6" - } - }, "babel-preset-react": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", @@ -2636,10 +2638,16 @@ "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", "dev": true }, + "base64-arraybuffer-es6": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/base64-arraybuffer-es6/-/base64-arraybuffer-es6-0.3.1.tgz", + "integrity": "sha512-TrhBheudYaff9adiTAqjSScjvtmClQ4vF9l4cqkPNkVsA11m4/NRdH4LkZ/tAMmpzzwfI20BXnJ/PTtafECCNA==" + }, "base64-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", - "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==" + "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==", + "dev": true }, "base64id": { "version": "1.0.0", @@ -4280,29 +4288,6 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, - "cosmiconfig": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-3.1.0.tgz", - "integrity": "sha512-zedsBhLSbPBms+kE7AH4vHg6JsKDz6epSv2/+5XHs8ILHlgDciSJfSWf8sX9aQ52Jb7KI7VswUTsLpR/G0cr2Q==", - "dev": true, - "requires": { - "is-directory": "0.3.1", - "js-yaml": "3.10.0", - "parse-json": "3.0.0", - "require-from-string": "2.0.1" - }, - "dependencies": { - "parse-json": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-3.0.0.tgz", - "integrity": "sha1-+m9HsY4jgm6tMvJj50TQ4ehH+xM=", - "dev": true, - "requires": { - "error-ex": "1.3.1" - } - } - } - }, "crc": { "version": "3.4.4", "resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz", @@ -4887,9 +4872,9 @@ } }, "dexie": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/dexie/-/dexie-2.0.1.tgz", - "integrity": "sha1-ptxOYHRhxNpfk0YhkXoqiTmhjpc=" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dexie/-/dexie-2.0.2.tgz", + "integrity": "sha512-WsUVH7nrgAaYc658D8Z4MAN7h13uBUzpLTFITp1GT0kVnnxjfWvquyHUdyZ5HO0a/MuTF1cCdOSuo+PsuHkawg==" }, "di": { "version": "0.0.1", @@ -5397,6 +5382,14 @@ "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", "dev": true }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "requires": { + "webidl-conversions": "4.0.2" + } + }, "domhandler": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", @@ -6317,231 +6310,10 @@ } }, "eslint-plugin-no-unsanitized": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-unsanitized/-/eslint-plugin-no-unsanitized-2.0.2.tgz", - "integrity": "sha1-pCqDybPZOGEB1v1pFcQXWfp6N/c=", - "dev": true, - "requires": { - "eslint": "3.19.0" - }, - "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" - } - }, - "eslint": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", - "dev": true, - "requires": { - "babel-code-frame": "6.22.0", - "chalk": "1.1.3", - "concat-stream": "1.6.0", - "debug": "2.6.8", - "doctrine": "2.1.0", - "escope": "3.6.0", - "espree": "3.5.2", - "esquery": "1.0.0", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "glob": "7.1.2", - "globals": "9.18.0", - "ignore": "3.3.7", - "imurmurhash": "0.1.4", - "inquirer": "0.12.0", - "is-my-json-valid": "2.16.0", - "is-resolvable": "1.0.1", - "js-yaml": "3.10.0", - "json-stable-stringify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.11.1", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "1.2.1", - "progress": "1.1.8", - "require-uncached": "1.0.3", - "shelljs": "0.7.8", - "strip-bom": "3.0.0", - "strip-json-comments": "2.0.1", - "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.0" - } - }, - "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.11.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": "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 - }, - "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 - }, - "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 - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "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.11.1", - "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 - }, - "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" - } - } - } - }, - "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" - } - } - } + "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-node": { "version": "6.0.0", @@ -6735,12 +6507,6 @@ "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=" }, - "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", @@ -6885,12 +6651,12 @@ "dev": true }, "fake-indexeddb": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fake-indexeddb/-/fake-indexeddb-2.0.3.tgz", - "integrity": "sha1-YxmwzBaxxjQ/Ri1c+VKRyxGktYs=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/fake-indexeddb/-/fake-indexeddb-2.0.4.tgz", + "integrity": "sha1-QBcV3rf8lQGGbJ8ym953QlmeLeg=", "requires": { "core-js": "2.4.1", - "realistic-structured-clone": "1.0.1", + "realistic-structured-clone": "2.0.1", "setimmediate": "1.0.5" } }, @@ -8600,7 +8366,7 @@ "globals": { "version": "9.18.0", "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha1-qjiWs+abSH8X4x7SFD1pqOMMLYo=", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", "dev": true }, "globals-docs": { @@ -8984,7 +8750,7 @@ "hosted-git-info": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", - "integrity": "sha1-bWDjSzq7yDEwYsO3mO+NkBoHrzw=", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", "dev": true }, "html": { @@ -9317,7 +9083,8 @@ "ieee754": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", - "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "dev": true }, "iferr": { "version": "0.1.5", @@ -9572,9 +9339,7 @@ "dev": true }, "intl-pluralrules": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/intl-pluralrules/-/intl-pluralrules-0.1.0.tgz", - "integrity": "sha1-0mD7YUxu23nBwYJzq8gH5EquDX8=" + "version": "github:projectfluent/IntlPluralRules#94cb0fa1c23ad943bc5aafef43cea132fa51d68b" }, "invariant": { "version": "2.2.2", @@ -10747,12 +10512,6 @@ "graceful-fs": "4.1.11" } }, - "known-css-properties": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.5.0.tgz", - "integrity": "sha512-LOS0CoS8zcZnB1EjLw4LLqDXw8nvt3AGH5dXLQP3D9O1nLLA+9GC5GnPl5mmF+JiQAtSX4VyZC7KvEtcA4kUtA==", - "dev": true - }, "labeled-stream-splicer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz", @@ -10928,8 +10687,8 @@ "lockbox-datastore": { "version": "github:mozilla-lockbox/lockbox-datastore#0e90e67f122d900bb1871a06f405b682a1cf0954", "requires": { - "dexie": "2.0.1", - "fake-indexeddb": "2.0.3", + "dexie": "2.0.2", + "fake-indexeddb": "2.0.4", "joi": "13.1.2", "joi-browser": "13.0.1", "json-merge-patch": "0.2.3", @@ -10985,11 +10744,6 @@ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.4.tgz", "integrity": "sha1-3MHXVS4VCgZABzupyzHXDwMpUOc=" }, - "lodash._basefor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash._basefor/-/lodash._basefor-3.0.3.tgz", - "integrity": "sha1-dVC06SGO8J+tJDQ7YSAhx5tMIMI=" - }, "lodash.assign": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", @@ -11039,31 +10793,12 @@ "resolved": "https://registry.npmjs.org/lodash.intersection/-/lodash.intersection-4.4.0.tgz", "integrity": "sha1-ChG6Yx0OlcI8fy9Mu5ppLtF45wU=" }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" - }, "lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", "dev": true }, - "lodash.keysin": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/lodash.keysin/-/lodash.keysin-3.0.8.tgz", - "integrity": "sha1-IsRJPrvtsUJ5YqVLRFssinZ/tH8=", - "requires": { - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" - } - }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -11102,6 +10837,11 @@ "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", "dev": true }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -11741,9 +11481,9 @@ "dev": true }, "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.1.tgz", + "integrity": "sha512-SpwyojlnE/WRBNGtvJSNfllfm5PqEDFxcWluSIgLeSBJtXG4DmoX2NNAeEA7rP5kK+79VgtVq8nG6HskaL1ykg==", "dev": true, "requires": { "browser-stdout": "1.3.0", @@ -12337,7 +12077,7 @@ "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "requires": { "hosted-git-info": "2.5.0", @@ -12962,20 +12702,11 @@ "readable-stream": "2.3.3" }, "dependencies": { - "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "requires": { - "base64-js": "1.2.1", - "ieee754": "1.1.8", - "isarray": "1.0.0" - } - }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true }, "readable-stream": { "version": "2.3.3", @@ -14072,81 +13803,6 @@ } } }, - "postcss-sass": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.2.0.tgz", - "integrity": "sha512-cUmYzkP747fPCQE6d+CH2l1L4VSyIlAzZsok3HPjb5Gzsq3jE+VjpAdGlPsnQ310WKWI42sw+ar0UNN59/f3hg==", - "dev": true, - "requires": { - "gonzales-pe": "4.2.3", - "postcss": "6.0.16" - }, - "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.0" - } - }, - "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" - }, - "dependencies": { - "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" - } - } - } - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "postcss": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz", - "integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==", - "dev": true, - "requires": { - "chalk": "2.3.0", - "source-map": "0.6.1", - "supports-color": "5.1.0" - } - }, - "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 - }, - "supports-color": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", - "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } - } - } - }, "postcss-scss": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-1.0.3.tgz", @@ -14327,7 +13983,7 @@ "promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078=", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "requires": { "asap": "2.0.6" } @@ -14548,7 +14204,7 @@ "randomatic": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha1-x6vpzIuHwLqodrGf3oP9RkeX44w=", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", "dev": true, "requires": { "is-number": "3.0.0", @@ -14894,42 +14550,21 @@ } } }, - "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": { - "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 - } - } - }, "realistic-structured-clone": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/realistic-structured-clone/-/realistic-structured-clone-1.0.1.tgz", - "integrity": "sha1-Gr6CrwuAzXsQn9r10pMIAyhS1F0=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/realistic-structured-clone/-/realistic-structured-clone-2.0.1.tgz", + "integrity": "sha1-q5ULxeY4WrjRtDhYj0LlWtsqTGc=", "requires": { - "lodash.isplainobject": "3.2.0" + "core-js": "2.5.3", + "domexception": "1.0.1", + "typeson": "5.8.2", + "typeson-registry": "1.0.0-alpha.21" }, "dependencies": { - "lodash.isplainobject": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-3.2.0.tgz", - "integrity": "sha1-moI4rhayAEMpYM1zRlEtASP79MU=", - "requires": { - "lodash._basefor": "3.0.3", - "lodash.isarguments": "3.1.0", - "lodash.keysin": "3.0.8" - } + "core-js": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz", + "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=" } } }, @@ -15587,7 +15222,7 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "dev": true }, "safe-json-parse": { @@ -16127,7 +15762,7 @@ "source-list-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", - "integrity": "sha1-qqR0A/eyRakvvJfqCPJQ1gh+0IU=", + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", "dev": true }, "source-map": { @@ -16545,6 +16180,11 @@ "requires": { "safe-buffer": "5.1.1" } + }, + "type-detect": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.6.tgz", + "integrity": "sha512-qZ3bAurt2IXGPR3c57PyaSYEnQiLRwPeS60G9TahElBZsdOABo+iKYch/PhRjSTZJ5/DF08x43XMt9qec2g3ig==" } } }, @@ -16796,9 +16436,9 @@ "dev": true }, "style-loader": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.20.2.tgz", - "integrity": "sha512-FrLMGaOLVhS5pvoez3eJyc0ktchT1inEZziBSjBq1hHQBK3GFkF57Qd825DcrUhjaAWQk70MKrIl5bfjadR/Dg==", + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.20.1.tgz", + "integrity": "sha512-NtlwQOHQvUgEKuPs4JoUMQUkML8UNMxLbXM2JAZerIQVVVMgO5VVRjYQA8zzkpBu/X2OnTt+5ZKe8IbGk5TjRA==", "dev": true, "requires": { "loader-utils": "1.1.0", @@ -16841,15 +16481,15 @@ "dev": true }, "stylelint": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-8.4.0.tgz", - "integrity": "sha512-56hPH5mTFnk8LzlEuTWq0epa34fHuS54UFYQidBOFt563RJBNi1nz1F2HK2MoT1X1waq47milvRsRahFCCJs/Q==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-9.1.1.tgz", + "integrity": "sha512-BYhAUd8ZiMcRx9cgVOWhckiixK93zXfYB2IwBZxcH+sFE7fp2nvs6xbx97P/wa3obhRLVukrIOH/1BHiukcuOQ==", "dev": true, "requires": { - "autoprefixer": "7.2.5", + "autoprefixer": "8.1.0", "balanced-match": "1.0.0", - "chalk": "2.3.0", - "cosmiconfig": "3.1.0", + "chalk": "2.3.2", + "cosmiconfig": "4.0.0", "debug": "3.1.0", "execall": "1.0.0", "file-entry-cache": "2.0.0", @@ -16859,26 +16499,27 @@ "html-tags": "2.0.0", "ignore": "3.3.7", "imurmurhash": "0.1.4", - "known-css-properties": "0.5.0", - "lodash": "4.17.4", + "known-css-properties": "0.6.1", + "lodash": "4.17.5", "log-symbols": "2.1.0", "mathml-tag-names": "2.0.1", "meow": "4.0.0", "micromatch": "2.3.11", "normalize-selector": "0.2.0", "pify": "3.0.0", - "postcss": "6.0.16", + "postcss": "6.0.19", "postcss-html": "0.12.0", "postcss-less": "1.1.3", "postcss-media-query-parser": "0.2.3", "postcss-reporter": "5.0.0", "postcss-resolve-nested-selector": "0.1.1", "postcss-safe-parser": "3.0.1", - "postcss-sass": "0.2.0", + "postcss-sass": "0.3.0", "postcss-scss": "1.0.3", "postcss-selector-parser": "3.1.1", "postcss-value-parser": "3.3.0", "resolve-from": "4.0.0", + "signal-exit": "3.0.2", "specificity": "0.3.2", "string-width": "2.1.1", "style-search": "0.1.0", @@ -16894,36 +16535,36 @@ "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==", + "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.0" } }, "autoprefixer": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.5.tgz", - "integrity": "sha512-XqHfo8Ht0VU+T5P+eWEVoXza456KJ4l62BPewu3vpNf3LP9s2+zYXkXBznzYby4XeECXgG3N4i+hGvOhXErZmA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-8.1.0.tgz", + "integrity": "sha512-b6mjq6VZ0guW6evRkKXL5sSSvIXICAE9dyWReZ3l/riidU7bVaJMe5cQ512SmaLA4Pvgnhi5MFsMs/Mvyh9//Q==", "dev": true, "requires": { - "browserslist": "2.11.3", - "caniuse-lite": "1.0.30000792", + "browserslist": "3.1.1", + "caniuse-lite": "1.0.30000812", "normalize-range": "0.1.2", "num2fraction": "1.2.2", - "postcss": "6.0.16", + "postcss": "6.0.19", "postcss-value-parser": "3.3.0" } }, "browserslist": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", - "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.1.1.tgz", + "integrity": "sha512-zHGaPnTt70ywm+glR7uMJFZSl+ADGO67SgD2ae20L+Y3KJUeH4fVa89OkTqKCqAnXFE9mO4LTHBKBqKRlr7VNw==", "dev": true, "requires": { - "caniuse-lite": "1.0.30000792", - "electron-to-chromium": "1.3.31" + "caniuse-lite": "1.0.30000812", + "electron-to-chromium": "1.3.34" } }, "camelcase": { @@ -16944,31 +16585,32 @@ } }, "caniuse-lite": { - "version": "1.0.30000792", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000792.tgz", - "integrity": "sha1-0M6pgfgRjzlhRxr7tDyaHlu/AzI=", + "version": "1.0.30000812", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000812.tgz", + "integrity": "sha512-j+l55ayQ9BO4Sy9iVfbf99+G+4ddAmkXoiEt73WCW4vJ83usrlHzDkFEnNXe5/swkVqE7YBm5i8M2uRXlx9vWg==", "dev": true }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", + "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" - }, - "dependencies": { - "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" - } - } + "supports-color": "5.3.0" + } + }, + "cosmiconfig": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", + "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", + "dev": true, + "requires": { + "is-directory": "0.3.1", + "js-yaml": "3.10.0", + "parse-json": "4.0.0", + "require-from-string": "2.0.1" } }, "debug": { @@ -16980,6 +16622,12 @@ "ms": "2.0.0" } }, + "electron-to-chromium": { + "version": "1.3.34", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.34.tgz", + "integrity": "sha1-2TSY9AORuwwWpgPYJBuZUUBBV+0=", + "dev": true + }, "get-stdin": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", @@ -16987,9 +16635,9 @@ "dev": true }, "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "indent-string": { @@ -17004,6 +16652,12 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "known-css-properties": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.6.1.tgz", + "integrity": "sha512-nQRpMcHm1cQ6gmztdvLcIvxocznSMqH/y6XtERrWrHaymOYdDGroRqetJvJycxGEr1aakXiigDgn7JnzuXlk6A==", + "dev": true + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -17017,9 +16671,9 @@ } }, "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", "dev": true }, "map-obj": { @@ -17077,14 +16731,24 @@ "dev": true }, "postcss": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz", - "integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==", + "version": "6.0.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", + "integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==", "dev": true, "requires": { - "chalk": "2.3.0", + "chalk": "2.3.2", "source-map": "0.6.1", - "supports-color": "5.1.0" + "supports-color": "5.3.0" + } + }, + "postcss-sass": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.3.0.tgz", + "integrity": "sha512-nZJEFS2bT007CmzMjlZfZwcZKpSJ/JeFiVEdgrgvGZtAnORU+5BvN0cioNuDAVxwXHXp3hksCJzbZYPWkuw41Q==", + "dev": true, + "requires": { + "gonzales-pe": "4.2.3", + "postcss": "6.0.19" } }, "postcss-selector-parser": { @@ -17173,12 +16837,12 @@ "dev": true }, "supports-color": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", - "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", + "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", "dev": true, "requires": { - "has-flag": "2.0.0" + "has-flag": "3.0.0" } }, "trim-newlines": { @@ -17190,9 +16854,9 @@ } }, "stylelint-config-recommended": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-2.0.1.tgz", - "integrity": "sha512-FXdgdOEGpaFQoKGhsi8IbsCI6dkxHQPa1CCqIybkN1d8LKtdxrn/A1rgu8DpJ6J+/4L30FOJeVdPttGfxCDHBQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-2.1.0.tgz", + "integrity": "sha512-ajMbivOD7JxdsnlS5945KYhvt7L/HwN6YeYF2BH6kE4UCLJR0YvXMf+2j7nQpJyYLZx9uZzU5G1ZOSBiWAc6yA==", "dev": true }, "subarg": { @@ -17880,6 +17544,21 @@ "punycode": "1.4.1" } }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "requires": { + "punycode": "2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=" + } + } + }, "traverse": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", @@ -17979,6 +17658,29 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typeson": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typeson/-/typeson-5.8.2.tgz", + "integrity": "sha512-AFuyvVdHdkGlVIalOrSFjylmeLeWFtKu77uDjEilP4B9+Jk0DCM1m1A4Q2s3AwROhgiFFVPI8oARaD9S61lOkg==" + }, + "typeson-registry": { + "version": "1.0.0-alpha.21", + "resolved": "https://registry.npmjs.org/typeson-registry/-/typeson-registry-1.0.0-alpha.21.tgz", + "integrity": "sha512-D7aj2KAzOaLvzCAYNhoFW536uWwbmSz5gSaO5fWETERLFheCOEIiMifGI4GDyGatxRvUJMz0ydp/ZEYYzs9iwQ==", + "requires": { + "base64-arraybuffer-es6": "0.3.1", + "typeson": "5.8.2", + "uuid": "3.2.1", + "whatwg-url": "6.4.0" + }, + "dependencies": { + "uuid": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" + } + } + }, "ua-parser-js": { "version": "0.7.13", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.13.tgz", @@ -18725,6 +18427,11 @@ } } }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, "webpack": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.10.0.tgz", @@ -18958,7 +18665,7 @@ "webpack-sources": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.0.1.tgz", - "integrity": "sha1-xzVkNqTRMSO+LiQmoF0drZy+Zc8=", + "integrity": "sha512-05tMxipUCwHqYaVS8xc7sYPTly8PzXayRCB4dTxLhWTqlKUiwH6ezmEe0OSreL1c30LAuA3Zqmc+uEBUGFJDjw==", "dev": true, "requires": { "source-list-map": "2.0.0", @@ -18986,6 +18693,16 @@ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=" }, + "whatwg-url": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.4.0.tgz", + "integrity": "sha512-Z0CVh/YE217Foyb488eo+iBv+r7eAQ0wSTyApi9n06jhcA3z6Nidg/EGvl0UFkg7kMdKxfBzzr+o9JF+cevgMg==", + "requires": { + "lodash.sortby": "4.7.0", + "tr46": "1.0.1", + "webidl-conversions": "4.0.2" + } + }, "when": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/when/-/when-3.7.2.tgz", diff --git a/package.json b/package.json index a395414c..3b264833 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "title": "Lockbox", "name": "lockbox", "id": "lockbox@mozilla.com", - "version": "0.1.7-alpha1", + "version": "0.1.8-alpha", "main": "dist/bootstrap.js", "description": "The simple way to store, retrieve and manage website login info", "author": "Lockbox Team ", @@ -96,14 +96,14 @@ "copy-webpack-plugin": "^4.3.1", "cross-env": "^5.1.3", "css-loader": "^0.28.9", - "documentation": "^5.3.5", + "documentation": "^6.0.0", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", "eslint": "^4.15.0", "eslint-config-standard": "^11.0.0-beta.0", "eslint-plugin-import": "^2.8.0", "eslint-plugin-mozilla": "0.6.0", - "eslint-plugin-no-unsanitized": "^2.0.2", + "eslint-plugin-no-unsanitized": "^3.0.0", "eslint-plugin-node": "^6.0.0", "eslint-plugin-only-warn": "^1.0.1", "eslint-plugin-promise": "^3.6.0", @@ -124,7 +124,7 @@ "karma-mocha-reporter": "^2.2.5", "karma-sourcemap-loader": "^0.3.7", "karma-webpack": "^2.0.9", - "mocha": "^4.1.0", + "mocha": "^5.0.1", "nsp": "^3.1.0", "react-document-title": "^2.0.3", "react-test-renderer": "^16.2.0", @@ -133,8 +133,8 @@ "sinon-chai": "^2.14.0", "source-map-support": "^0.5.1", "style-loader": "^0.20.1", - "stylelint": "8.4.0", - "stylelint-config-recommended": "2.0.1", + "stylelint": "9.1.1", + "stylelint-config-recommended": "2.1.0", "webpack": "^3.10.0", "webpack-combine-loaders": "^2.0.3", "webpack-node-externals": "^1.6.0" diff --git a/requirements/flake8.txt b/requirements/flake8.txt index 29226fd5..42a2c164 100644 --- a/requirements/flake8.txt +++ b/requirements/flake8.txt @@ -1,3 +1,3 @@ flake8==3.5.0 -flake8-isort==2.2.2 -flake8-docstrings==1.1.0 +flake8-isort==2.4 +flake8-docstrings==1.3.0 diff --git a/requirements/tests.txt b/requirements/tests.txt index ad662a78..fa009eb9 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -1,6 +1,6 @@ fxapom==1.10.1 -PyPOM==1.2.0 -pytest==3.3.1 -pytest-selenium==1.11.3 -pytest-xdist==1.20.1 -selenium==3.8.0 +PyPOM==1.3.0 +pytest==3.4.1 +pytest-selenium==1.11.4 +pytest-xdist==1.22.2 +selenium==3.10.0 \ No newline at end of file diff --git a/src/bootstrap.js b/src/bootstrap.js index fa785480..ea808f05 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -162,6 +162,24 @@ function startup({webExtension}, reason) { } } + try { + Services.telemetry.registerScalars(TELEMETRY_CATEGORY, { + "datastoreCount": { + kind: Services.telemetry.SCALAR_TYPE_COUNT, + keyed: false, + record_on_release: false, + expired: false, + }, + }); + } catch (e) { + if (e.message === "Attempt to register scalar that is already registered.") { + // eslint-disable-next-line no-console + console.log("telemetry scalar already registered; skipping registration"); + } else { + throw e; + } + } + webExtension.startup().then(({browser}) => { Services.telemetry.recordEvent(TELEMETRY_CATEGORY, "startup", "webextension"); @@ -173,6 +191,12 @@ function startup({webExtension}, reason) { message.extra || null ); respond({}); + break; + case "telemetry_scalar": + Services.telemetry.scalarSet( + `${TELEMETRY_CATEGORY}.${message.name}`, message.value + ); + respond({}); } }); diff --git a/src/webextension/background/message-ports.js b/src/webextension/background/message-ports.js index c019141a..14e2542d 100644 --- a/src/webextension/background/message-ports.js +++ b/src/webextension/background/message-ports.js @@ -161,8 +161,10 @@ export default function initializeMessagePorts() { case "list_items": return openDataStore().then(async (ds) => { - return {items: Array.from((await ds.list()).values(), - makeItemSummary)}; + var entries = Array.from((await ds.list()).values(), + makeItemSummary); + telemetry.setScalar("datastoreCount", entries.length); + return {items: entries}; }); case "add_item": return openDataStore().then(async (ds) => { @@ -186,7 +188,6 @@ export default function initializeMessagePorts() { return openDataStore().then(async (ds) => { return {item: await ds.get(message.id)}; }); - case "proxy_telemetry_event": return telemetry.recordEvent(message.method, message.object, message.extra); diff --git a/src/webextension/background/telemetry.js b/src/webextension/background/telemetry.js index 1bad78ad..cb66d0b1 100644 --- a/src/webextension/background/telemetry.js +++ b/src/webextension/background/telemetry.js @@ -14,3 +14,9 @@ export async function recordEvent(method, object, extra) { type: "telemetry_event", method, object, extra, }); } + +export async function setScalar(name, value) { + return browser.runtime.sendMessage({ + type: "telemetry_scalar", name, value, + }); +} diff --git a/src/webextension/icons/arrowhead-down-16.svg b/src/webextension/icons/arrowhead-down-16.svg deleted file mode 100644 index a56e6870..00000000 --- a/src/webextension/icons/arrowhead-down-16.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/webextension/icons/arrowhead-right-16.svg b/src/webextension/icons/arrowhead-right-16.svg deleted file mode 100644 index cc6a0285..00000000 --- a/src/webextension/icons/arrowhead-right-16.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/src/webextension/icons/chevron-right.svg b/src/webextension/icons/chevron-right.svg new file mode 100644 index 00000000..b2a2bef8 --- /dev/null +++ b/src/webextension/icons/chevron-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/webextension/icons/clear.svg b/src/webextension/icons/clear.svg new file mode 100644 index 00000000..52782336 --- /dev/null +++ b/src/webextension/icons/clear.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/webextension/icons/hide.svg b/src/webextension/icons/hide.svg new file mode 100644 index 00000000..dbbbbd44 --- /dev/null +++ b/src/webextension/icons/hide.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/webextension/icons/search.svg b/src/webextension/icons/search.svg new file mode 100644 index 00000000..689a5f68 --- /dev/null +++ b/src/webextension/icons/search.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/webextension/icons/show.svg b/src/webextension/icons/show.svg new file mode 100644 index 00000000..4f184003 --- /dev/null +++ b/src/webextension/icons/show.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/webextension/images/nessie_v2.svg b/src/webextension/images/nessie_v2.svg index 8a202723..5999a97a 100644 --- a/src/webextension/images/nessie_v2.svg +++ b/src/webextension/images/nessie_v2.svg @@ -1,367 +1,114 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + Global / Nessie + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/webextension/list/components/item-fields.css b/src/webextension/list/components/item-fields.css index 33d4b63c..171a7a83 100644 --- a/src/webextension/list/components/item-fields.css +++ b/src/webextension/list/components/item-fields.css @@ -5,7 +5,7 @@ .item-fields { display: grid; grid-template-columns: minmax(200px, 1fr); - max-width: 320px; + max-width: 360px; } .item-fields > label, @@ -17,12 +17,24 @@ resize: none; } -.first-label { - margin-top: 0; +.input { + max-width: 242px; +} + +.password { + max-width: 258px; +} + +.notes { + min-height: 60px; +} + +.notes-read-only { + min-height: 73px; } -.copy-button { - color: #0060df; +.first-label { + margin-top: 0; } .inline-button { diff --git a/src/webextension/list/components/item-fields.js b/src/webextension/list/components/item-fields.js index df00ec0a..97b9c1fc 100644 --- a/src/webextension/list/components/item-fields.js +++ b/src/webextension/list/components/item-fields.js @@ -28,26 +28,26 @@ const fieldsPropTypes = PropTypes.shape({ export function ItemFields({fields, onCopy}) { return (
+
+ + tITLe + + {fields.title} +
- oRIGIn + oRIGIn {fields.origin}
-
- - tITLe - - {fields.title} -
uSERNAMe
- + {fields.username} @@ -74,7 +74,7 @@ export function ItemFields({fields, onCopy}) { nOTEs - {fields.notes} + {fields.notes}
); @@ -108,23 +108,23 @@ export class EditItemFields extends React.Component { return (