├── .eslintrc.json ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── TODO ├── data └── cdn.json ├── docs ├── .nojekyll ├── README.md ├── _navbar.md ├── _sidebar.md ├── de │ ├── README.md │ ├── _sidebar.md │ ├── dev-changelog.md │ ├── funktionen.md │ ├── installation.md │ ├── verwendung.md │ └── voraussetzungen.md ├── dev-changelog.md ├── dev-contrib.md ├── features-overview.md ├── index.html ├── installation.md ├── prerequisites.md └── usage.md ├── gdpr-cli-screenshot.png ├── index.js ├── lib ├── helpers.js ├── html-parser.js ├── loader.js ├── modules │ ├── analytics.js │ ├── fonts.js │ ├── info.js │ └── social.js ├── tasks.js └── ui.js ├── package.json ├── test ├── html.js └── normalize.js └── yarn.lock /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": true, 6 | "node": true 7 | }, 8 | "parserOptions": { 9 | "ecmaFeatures": { 10 | "jsx": true 11 | }, 12 | "sourceType": "module" 13 | }, 14 | "rules": { 15 | "no-const-assign": "warn", 16 | "no-this-before-super": "warn", 17 | "no-undef": "warn", 18 | "no-unreachable": "warn", 19 | "no-unused-vars": "warn", 20 | "constructor-super": "warn", 21 | "valid-typeof": "warn" 22 | } 23 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | 19 | 20 | **Screenshots** 21 | 22 | 23 | **Desktop:** 24 | - OS: [e.g. iOS] 25 | - Node Version [e.g. 8.11.2 LTS] 26 | - Version [e.g. 0.3.2] 27 | 28 | **Additional context** 29 | 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | 9 | 10 | **Describe the solution you'd like** 11 | 12 | 13 | **Describe alternatives you've considered** 14 | 15 | 16 | **Additional context** 17 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | website-examples.md 4 | bulk-test.sh 5 | bulk.txt 6 | websites.txt -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8" 4 | - "10" 5 | cache: yarn 6 | git: 7 | depth: 5 -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | Thank you for your interest in contributing to this project! 4 | 5 | The following is a set of guidelines for contributing to **GDPR CLI**. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. 6 | 7 | ## How can I contribute? 8 | 9 | ### Reporting bugs 10 | 11 | Bugs are tracked on [Github Issues](https://github.com/mirkoschubert/gdpr-cli/issues). Before you open a new bug report on this section, please check if the bug already exists. If you find a closed issue with the same thing you're experiencing, open a new issue and include a link to the original issue. 12 | 13 | Explain the problem and include additional details to help maintainers reproduce the problem. You can also use the [Bug Report Template](https://github.com/mirkoschubert/gdpr-cli/blob/master/.github/ISSUE_TEMPLATE/bug_report.md). 14 | 15 | ### Suggesting Enhancements 16 | 17 | You can always suggest new features or other enhancements for this project on [Github Issues](https://github.com/mirkoschubert/gdpr-cli/issues). Before you open a new enhancements report, please check if a similar suggestion already has been made. You should also check the [Road Map](https://github.com/mirkoschubert/gdpr-cli#roadmap) of this project, so you're not proposing any features which are already planned for the future. 18 | 19 | Explain your suggestion as detailed as possible. You can also use the [Feature Request Template](https://github.com/mirkoschubert/gdpr-cli/blob/master/.github/ISSUE_TEMPLATE/feature_request.md). 20 | 21 | ### Your Code Contribution 22 | 23 | Unsure where to begin contributing to **GDPR CLI**? You can start with looking if any [help-wanted](https://github.com/mirkoschubert/gdpr-cli/labels/help%20wanted) issues are open. 24 | 25 | I'm really bad with writing tests, so if you're better with these kind of things, you can definitely help me. I'm using [Ava](https://github.com/avajs/ava) for now, but you can also suggest an alternative. 26 | 27 | ### Pull Requests 28 | 29 | You're always welcome so send pull requests (PRs) for optimizing my code, implementing a existing task, suggesting new enhancements or fixing bugs. Before you do, please read my [Coding Standards] and have the following points in mind: 30 | 31 | * If you're refering to an open issue, include the issue number to the description. 32 | * Send pull requests **only** to the `dev` branch. 33 | * Avoid platform dependant code and code for `node@10` only. 34 | * Please comment new code intelligibly. 35 | * If you don't use `Visual Studio Code` and the extentions `Todo+` and `Projects+ Todo+`, do **not** touch the `TODO.md` file. 36 | 37 | ## Coding Standards 38 | 39 | I code using `Visual Studio Code` with extentions like `prettier`, `eslint`, `Todo+` and `Highlight`, but those extentions aren't mandatory. But you should use an indentation of 2 spaces and only single quotes if possible. 40 | 41 | Please try to be in accordance with the already existing classes and modules. If you would change the basic structure of the software, discuss it with me first. 42 | 43 | As of now there are two main branches: 44 | 45 | * `master` is the official (and hopefully stable) version of the tool, wich is mainly used for [npm](https://www.npmjs.com/package/gdpr-cli) and the [releases](https://github.com/mirkoschubert/gdpr-cli/releases). 46 | * `dev` is the »developer edition« of the software and the main branch to push changes to. 47 | 48 | Since the `dev` branch is usually ahead, please use this one for your development and any PRs. 49 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License (MIT) 2 | 3 | Copyright (c) 2018-present Mirko Schubert (https://mirkoschubert.de) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

GDPR CLI

2 | 3 |

4 | 5 | 6 | 7 | 8 |

9 | 10 |

A command line tool for checking your website for GDPR compliance.

11 |

For more information about the GDPR please visit eugdpr.org!

12 | 13 | --- 14 | 15 |

16 | 17 |

18 | 19 | **Attention!** You are a newbie and don't understand the instructions down below? Visit our **new documentation** in [English](https://mirkoschubert.github.io/gdpr-cli/#/) and [German](https://mirkoschubert.github.io/gdpr-cli/#/de/)! 20 | 21 | **GDPR CLI** is a easy-to-use command line tool for checking any given website for GDPR compliance. Since it is based on Node.js, the application is browser- and OS-independant. For everyone, who hasn't installed Node.js, I have planned to publish a pre-installed Package für macOS and Windows as well. 22 | 23 | This command line tool scrapes a website for HTML-, CSS- and JavaScript-Files and tries to detect code, which is possibly sending personal data to other services, such as Google, Facebook, Instagram, WordPress and many more. 24 | 25 | ### Warning 26 | 27 | This software is still in early alpha, so please use it at your own risk! If you find a bug or software incompability, please report it immediately by opening a ticket in the [Issues Section](https://github.com/mirkoschubert/gdpr-cli/issues). If you are familiar with Node.js and JavaScript programming, feel free to contribute by forking and/ or sending pull requests. 28 | 29 | Neither I nor this program are giving any legal advice. **GDPR CLI** can not assist you with your website administration or the preperation of legal documents such as an imprint or a privacy notice. It simply helps you by (unobtrusively) revealing possible security flaws, which could affect the data securitiy of any visitor of your website. For more information please consult your lawyer. 30 | 31 | ### Installation 32 | 33 | For installing **GDPR CLI** you need to have [node.js](https://nodejs.org/en/) and a package manager such as [npm](https://www.npmjs.com) or [yarn](https://yarnpkg.com/en/) already installed. If you use `npm`, you can install this package with the following command: 34 | 35 | ``` 36 | npm install -g gdpr-cli 37 | ``` 38 | 39 | With `yarn` it is just as easy as that: 40 | 41 | ``` 42 | yarn global add gdpr-cli 43 | ``` 44 | 45 | That's all - have fun! 46 | 47 | ### Usage 48 | 49 | The basic usage for this command line tool is: 50 | 51 | ``` 52 | gdpr scan https://your-website.com 53 | ``` 54 | 55 | There are some options already, but they still need some improvement. I will update these usage instructions frequently. Stay tuned! 56 | 57 | ### Roadmap 58 | 59 | * [x] Create the basic structure with an easy UI and a flexible Task manager 60 | * [x] Get some basic information about the website (Meta Data) 61 | * [x] Check the installed Software 62 | * [x] Detect Theme when WordPress is installed 63 | * [x] Check SSL Certificate 64 | * [ ] Check for Web Fonts 65 | * [x] Google Fonts 66 | * [x] Adobe Typekit 67 | * [ ] FontAwesome 68 | * [x] Local Fonts 69 | * [x] Check for DNS Prefetching 70 | * [x] Check for Analytics Tools 71 | * [x] Google Analytics 72 | * [x] Google Tag Manager 73 | * [x] Matomo / Piwik 74 | * [x] WordPress Stats (Jetpack) 75 | * [ ] Check for Image Embeds 76 | * [ ] Instagram 77 | * [ ] Pinterest 78 | * [ ] Flickr 79 | * [ ] Check for Music Embeds 80 | * [ ] SoundCloud 81 | * [ ] Check for Video Embeds 82 | * [ ] YouTube 83 | * [ ] Vimeo 84 | * [ ] Check for external JavaScript Libraries 85 | * [ ] Check for CDNs (e.g. WordPress, Cloudflase, AWS) 86 | * [ ] Check for Cookies (if it's even possible) 87 | * [ ] Check for advanced Fingerprinting (if possible) 88 | 89 | ### Contribution 90 | 91 | Please report issues/bugs, feature requests and suggestions for improvements to the [issue tracker](https://github.com/mirkoschubert/gdpr-cli/issues). 92 | 93 | You're welcome to fork the project and send me suggestions and new features via pull request. Please read the [contribution guidelines](https://mirkoschubert.github.io/gdpr-cli/#/dev-contrib) and send pull requests only to the newly installed `dev` branch! 94 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | 2 | Todo: 3 | Roadmap: 4 | ✔ Create the basic structure with an easy UI and a flexible Task manager @done(18-05-16 22:27) 5 | ✔ Get some basic information about the website (Meta Data) @done(18-05-19 01:15) 6 | ✔ Check the installed Software @done(18-05-19 01:15) 7 | ✔ Detect Theme when WordPress is installed @done(18-05-19 01:15) 8 | ✔ Check SSL Certificate @done(18-05-20 21:59) 9 | ☐ Check for Web Fonts (e.g. Google Fonts & Adobe Typekit) 10 | ✔ Google Fonts @done(18-05-27 19:22) 11 | ✔ Adobe Typekit @done(18-05-31 22:18) 12 | ☐ FontAwesome 13 | ✔ Local Fonts @done(18-05-27 19:23) 14 | ✔ Check for DNS Prefetching @done(18-05-22 17:45) 15 | ✔ Explain WordPress specific entries @done(18-05-22 18:05) 16 | ☐ Check for Analytics Tools 17 | ✔ Google Analytics @done(18-05-22 20:48) 18 | ✔ Google Tag Manager @done(18-05-22 20:48) 19 | ✔ Matomo/ Piwik @done(18-05-23 12:03) 20 | ✔ WordPress Stats (Jetpack) @done(18-05-23 12:21) 21 | ☐ Check for Opt Out Script 22 | ☐ Check for Media Embeds 23 | ☐ Instagram 24 | ☐ Flickr 25 | ☐ Soundcloud 26 | ☐ YouTube 27 | ☐ Vimeo 28 | ☐ Google Maps 29 | ☐ Check for Social Media Embeds 30 | ☐ FB Social Graph 31 | ☐ FB Connect 32 | ☐ Twitter 33 | ☐ Pinterest 34 | ☐ LinkedIn 35 | ☐ Xing 36 | ☐ Check for CDNs 37 | ☐ WordPress CDN 38 | ✔ AWS @done(18-06-02 13:52) 39 | ✔ Cloudflare @done(18-06-02 13:52) 40 | ✔ Bootstrap @done(18-06-02 13:52) 41 | ✔ Fontawesome @done(18-06-02 13:52) 42 | ☐ Check for Beacons (Facebook Pixel, VG Wort) 43 | ☐ Facebook Pixel 44 | ☐ VG Wort Tracker 45 | ☐ Wordpress.com Pixel (pixel.wp.com) 46 | ☐ Check for WordPress specific entries 47 | ☐ Plugins 48 | ☐ Gravatar 49 | ☐ Jetpack 50 | ☐ WP Emojis 51 | ☐ WP oEmbeds 52 | ☐ WP JSON / XML-RTC 53 | ☐ Check for Cookies (if it's even possible) 54 | ☐ Check for advanced Fingerprinting (if possible) 55 | Specific Todos: 56 | ✔ Check for protocol earlier @done(18-05-21 17:09) 57 | ✔ Generate a SSL task @done(18-05-20 23:04) 58 | ✔ Handle Task Runner better @done(18-05-21 17:09) 59 | ✔ Better Error Handling @done(18-05-21 19:01) 60 | ✔ Continue when a file fails @done(18-05-21 18:43) 61 | ✔ Change URL of CSS and JS to Objects @done(18-05-29 13:57) 62 | ✔ Don't show Certificate when it's empty @done(18-05-21 17:20) 63 | ✔ Find inline CSS and JS @done(18-05-22 14:47) 64 | ☐ Find iframes? 65 | ✔ Handle multipe Generator tags @done(18-05-22 14:43) 66 | ☐ Help pages for every command 67 | ✔ English and German Documentation for Newbies @done(18-05-28 17:52) 68 | Bugs: 69 | ✔ Manual selection of tasks doesn't work anymore @critical @done(18-05-22 16:31) 70 | ✔ CSS and JS files without a protocol can't be loaded @high @done(18-05-22 17:00) 71 | ✔ URL class is not global in nodejs < 10 @critical @done(18-05-27 22:11) 72 | ✔ Inline JS and CSS can't be loaded when there are no external files @high @done(18-05-27 22:12) 73 | ☐ On Google the protocol doesn't upgrade to SSL automatically @low 74 | ✔ On some sites the CSS and JS files can't be loaded when the URI contains a language slug @low @done(18-05-29 13:57) -------------------------------------------------------------------------------- /data/cdn.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "host": "bootstrapcdn.com", 3 | "description": "Bootstrap CDN" 4 | }, { 5 | "host": "s3.amazonaws.com", 6 | "description": "Amazon AWS S3" 7 | }, { 8 | "host": "cdnjs.cloudflare.com", 9 | "description": "Cloudflare CDNJS Javascript Libraries" 10 | }, { 11 | "host": "cloudfront.net", 12 | "description": "Cloudfront CDN" 13 | }, { 14 | "host": "cdn-images.mailchimp.com", 15 | "description": "Mailchimp Images CDN" 16 | }, { 17 | "host": "use.fontawesome.com", 18 | "description": "Fontawesome CDN" 19 | }, { 20 | "host": "staticxx.facebook.com", 21 | "description": "Facebook Connect Libraries" 22 | }, { 23 | "host": "fonts.googleapis.com", 24 | "description": "Google Fonts" 25 | }] -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirkoschubert/gdpr-cli/f9b2dd1e360a9c2a9f1151d324f2dcc6110fdff1/docs/.nojekyll -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # GDPR CLI 2 | 3 | > A command line tool for checking your website for GDPR compliance. 4 | 5 | ## What is it? 6 | 7 | **GDPR CLI** is a easy-to-use command line tool for checking any given website for GDPR compliance. Since it is based on Node.js, the application is browser- and OS-independant. For everyone, who hasn't installed Node.js, I have planned to publish a pre-installed Package für macOS and Windows as well. 8 | 9 | This command line tool scrapes a website for HTML-, CSS- and JavaScript-Files and tries to detect code, which is possibly sending personal data to other services, such as Google, Facebook, Instagram, WordPress and many more. 10 | 11 | !> This software is still in early alpha, so please use it at your own risk! If you find a bug or software incompability, please report it immediately by opening a ticket in the [Issues Section](https://github.com/mirkoschubert/gdpr-cli/issues). If you are familiar with Node.js and JavaScript programming, feel free to contribute by forking and/ or sending pull requests. 12 | 13 | ## Legal Disclaimer 14 | 15 | Neither I nor this program are giving any legal advice. **GDPR CLI** can not assist you with your website administration or the preperation of legal documents such as an imprint or a privacy notice. It simply helps you by (unobtrusively) revealing possible security flaws, which could affect the data securitiy of any visitor of your website. For more information please consult your lawyer. 16 | -------------------------------------------------------------------------------- /docs/_navbar.md: -------------------------------------------------------------------------------- 1 | * Translations 2 | * [:de: Deutsch](/de/) 3 | * [:us: English](/) 4 | -------------------------------------------------------------------------------- /docs/_sidebar.md: -------------------------------------------------------------------------------- 1 | * **Getting Started** 2 | * [Prerequisites](prerequisites.md) 3 | * [Installation](installation.md) 4 | * [Usage](usage.md) 5 | * **Features** 6 | * [Overview](features-overview.md) 7 | * **For Developers** 8 | * [Changelog](dev-changelog.md) 9 | * [Contribution](dev-contrib.md) 10 | -------------------------------------------------------------------------------- /docs/de/README.md: -------------------------------------------------------------------------------- 1 | # GDPR CLI 2 | 3 | > Ein Tool für die Kommandozeile, um Deine Webseite auf DSGVO-Konformität zu prüfen. 4 | 5 | ## Was ist das? 6 | 7 | **GDPR CLI** ist ein einfach zu bedienendes Tool für die Kommandozeile, um eine beliebige Webseite auf DSGVO-Konformität zu überprüfen. Da es auf Node.js basiert, ist die Anwendung browser- und betriebssystem-unabhängig. Für alle, die Node.js nicht installiert haben, plane ich für die Zukunft, ein vorkonfiguriertes Paket für macOS und Windows zu veröffentlichen. 8 | 9 | Das Programm durchsucht eine Webseite nach HTML-, CSS- und JavaScript-Dateien und versucht, Code zu erkennen, der möglicherweise persönliche Daten an andere Dienste wie Google, Facebook, Instagram, WordPress und viele weitere sendet. 10 | 11 | !> Diese Software befindet sich noch in einem frühen Alpha-Status, also benutze sie bitte auf eigene Gefahr! Wenn Du einen Fehler oder eine Inkompatibilität findest, melde sie bitte sofort, indem Du ein Ticket im [Issues-Abschnitt](https://github.com/miroschubert/gdpr-cli/issues) anlegst. Wenn Du Dich mit Node.js und der JavaScript-Programmierung auskennst, kannst Du Dich natürlich gerne durch das Klonen des Projekts und/ oder Senden von Pull-Requests daran beteiligen. 12 | 13 | ## Haftungsausschluss 14 | 15 | Weder ich selbst noch dieses Programm geben eine Rechtsauskunft zur DSGVO. **GDPR CLI** kann Dir nicht bei der Verwaltung Deiner Webseite oder Erstellung von rechtskräftigen Dokumenten wie Impressum oder Datenschutzerklärung behilflich sein. Stattdessen unterstützt es Dich, mögliche Sicherheitslücken in der Webseite aufzudecken, die die Datensicherheit eines Besuchers beeinträchtigen könnten. Für weitere Informationen zur DSGVO wende Dich bitte an Deinen Rechtsanwalt. 16 | -------------------------------------------------------------------------------- /docs/de/_sidebar.md: -------------------------------------------------------------------------------- 1 | * **Anfangen** 2 | * [Voraussetzungen](/de/voraussetzungen.md) 3 | * [Installation](/de/installation.md) 4 | * [Verwendung](/de/verwendung.md) 5 | * **Funktionen** 6 | * [Übersicht](/de/funktionen.md) 7 | * **Für Entwickler** 8 | * [Changelog](/de/dev-changelog.md) 9 | -------------------------------------------------------------------------------- /docs/de/dev-changelog.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ### [v0.3.4] - 2018-06-01 4 | 5 | * Wir haben neue **Mitwirkungs-Richtlinien** im Repository und in der Dokumentation! 6 | * Einige Ergänzungen von unserem neuen Mitwirkenden [Daniel Ruf](https://github.com/DanielRuf) wurden übernommen. 7 | 8 | ### [v0.3.3] - 2018-06-01 9 | 10 | * **BUGFIX:** Wenn die Webseite relative Pfade zu CSS- und JS-Dateien enthält, konnten diese Dateien nicht geladen werden. 11 | * **BUGFIX:** Auf manchen Seiten, die fehlerhaften Code enthalten, konnte der `css`-Parser nicht ordnungsgemäß ausgeführt werden. Ich stelle nun einen eigenen Parser bereit. 12 | * **FEATURE:** Adobe Typekit Fonts werden nun erkannt. 13 | 14 | ### [v0.3.2] - 2018-05-27 15 | 16 | * **BUGFIX:** URL-Klasse konnte nicht global bei Node.js <10 geladen werden 17 | * **BUGFIX:** Inline-JS und -CSS konnte nicht geladen werden, wenn keine externen Dateien vorhanden sind 18 | 19 | ### [v0.3.1] - 2018-05-27 20 | 21 | * Aufgrund der Namenskonventionen in npmjs.com haben wir unseren Namen von `gdpr-check` zu `gdpr-cli` geändert 22 | 23 | ### [v0.3.0] - 2018-05-27 24 | 25 | * Meine erste öffentlich verfügbare Version. Achtung! Es könnte zu einem **Bug**-Aufkommen kommen. :smirk: 26 | -------------------------------------------------------------------------------- /docs/de/funktionen.md: -------------------------------------------------------------------------------- 1 | # Funktionen 2 | 3 | !> Dieser Abschnitt wird bald veröffentlicht! 4 | -------------------------------------------------------------------------------- /docs/de/installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | Nun ist es Zeit für die Installation von **GDPR CLI**. Wenn Du [Node.js](https://nodejs.org/en/) bereits installiert hast, ist dieser Teil ziemlich einfach. Wenn nicht, überprüfe bitte die [Voraussetzungen](/de/voraussetzungen.md)! 4 | 5 | Sobald Node.js korrekt funktioniert, musst Du den folgenden Befehl in Deine bevorzugte `terminal`-Anwendung eingeben (für Windows-Benutzer `Powershell`): 6 | 7 | ```bash 8 | npm install -g gdpr-cli 9 | ``` 10 | 11 | Wenn Du stattdessen den Paket-Manager `yarn` verwendest, müsstest Du den Befehl entsprechend anpassen: 12 | 13 | ```bash 14 | yarn global add gdpr-cli 15 | ``` 16 | 17 | Sobald die Installation beendet ist, kannst Du **GDPR CLI** verwenden! 18 | 19 | !> Da sich die Software noch einem frühen Alpha-Status befindet, funktioniert der Befehl `help` noch nicht korrekt. Bitte schaue Dir stattdessen die [Verwendungs](/de/verwendung.md)-Seite an. 20 | -------------------------------------------------------------------------------- /docs/de/verwendung.md: -------------------------------------------------------------------------------- 1 | # Verwendung 2 | 3 | Wenn Du Node.js und **GDPR CLI** installiert hast, kannst Du nun endlich loslegen! Öffne dazu einfach Deine bevorzugte `terminal`-Anwendung oder die `Windows Powershell` und gebe Folgendes ein: 4 | 5 | ```bash 6 | gdpr scan deinewebseite.de 7 | ``` 8 | 9 | Das Tool sollte die von Dir eingegebene Website scannen und Dir einige Informationen zu ihr anzeigen. Du kannst damit überprüfen, ob ein Element der Webseite Daten an nicht-europäische Server sendet, um Deine Datenschutzhinweise entsprechend anzupassen. 10 | 11 | Für die grundlegende Verwendung von **GDPR CLI** gilt: 12 | 13 | ```bash 14 | gdpr [befehl] [optionen] [URL] 15 | ``` 16 | 17 | ## Befehle 18 | 19 | | Befehl | Bedeutung | 20 | | :------ | :------------------------------------------------------------- | 21 | | scan, s | Scan-Kommando - scannt und analysiert eine festgelegte Website | 22 | | help | Hilfe - **noch nicht fertig** | 23 | 24 | ## Optionen 25 | 26 | Es sind bereits einige Optionen verfügbar, um Deine Bedürfnisse zu spezifizieren. 27 | 28 | #### Globale Optionen 29 | 30 | | Option | Bedeutung | 31 | | :------------ | :------------------------------------------------------------ | 32 | | -v, --verbose | Ausführlicher Modus - gibt einfach alles aus, was möglich ist | 33 | | -m, --mute | Stummer Modus - gibt nur die Ergebnisse der Analyse aus | 34 | | -V, --version | Version - zeigt die Version von **GDPR CLI** an | 35 | | -h, --help | Hilfe - die grundlegende globale Hilfe | 36 | 37 | #### Optionen für den `scan`-Befehl 38 | 39 | | Option | Bedeutung | 40 | | :---------------- | :------------------------------------------ | 41 | | -f, --fonts | Zeigt nur die Ergebnisse zu den Fonts | 42 | | -s, --ssl | Zeigt nur das SSL-Zertifikat an | 43 | | -p, --prefetching | Zeigt nur die DNS-Prefetching-Ergebnisse an | 44 | | -a, --analytics | Zeigt nur die Analytics-Ergebnisse an | 45 | 46 | ## Kombination 47 | 48 | Du kannst viele dieser Optionen frei kombinieren. Hier ein Beispiel: 49 | 50 | ```bash 51 | gdpr scan -vfa deinewebseite.de 52 | ``` 53 | 54 | In diesem Fall wird **GDPR CLI** im ausführlichen Modus gestartet und nur nach Fonts und Analytics-Tools scannen. 55 | -------------------------------------------------------------------------------- /docs/de/voraussetzungen.md: -------------------------------------------------------------------------------- 1 | # Voraussetzungen 2 | 3 | Diese Software basiert auf Node.js, daher ist es zwingend erforderlich, dass `node` und ein Paket-Manager wie `npm` oder `yarn` installiert ist. Wenn dies noch nicht der Fall ist, folge bitte diesen Anweisungen. 4 | 5 | ## Installieren von Node.js 6 | 7 | Node.js ist eine JavaScript-Laufzeitumgebung, die auf der V8-Engine von Google Chrome basiert. Da **GDPR CLI** in JavaScript geschrieben ist, wird diese Software vorausgesetzt. 8 | 9 | Um sie herunterzuladen, besuche bitte [nodejs.org](https://nodejs.org/en/). Du kannst entweder den LTS oder die aktuelle Version wählen. Klicke einfach auf eine der beiden Schaltflächen auf der Startseite. Damit solltest Du die richtige Version für Dein Betriebssystem erhalten. 10 | 11 | ### Windows 12 | 13 | !> Node.js benötigt Windows 7 oder höher. Wenn Du noch immer eine ältere Version von Windows verwendest, aktualisiere zuerst Dein Betriebssystem. 14 | 15 | Um Node.js zu installieren, musst Du lediglich die zuvor heruntergeladene Datei öffnen und den Anweisungen des Installationsprogramms folgen. Sobald dies abgeschlossen ist, suche nach der `Windows Powershell` und öffne dieses Programm. 16 | 17 | ### macOS 18 | 19 | Um Node.js auf macOS zu installieren, musst Du lediglich die zuvor heruntergeladene Datei öffnen und den Anweisungen des Installationsprogramms folgen. Sobald dies abgeschlossen ist, suche nach der Anwendung `terminal` und öffne sie. 20 | 21 | ?> Wenn Du `homebrew` installiert hast, gib stattdessen `brew install node` in Deine Kommandozeile ein. 22 | 23 | ### Linux 24 | 25 | Um Node.js unter Linux zu installieren, musst Du lediglich die zuvor heruntergeladene Datei öffnen und den Anweisungen des Installationsprogramms folgen. Sobald dies abgeschlossen ist, öffne einfach Deine bevorzugte `terminal`-Anwendung. 26 | 27 | ?> Wenn ein Installationsprogramm oder eine Binärdatei für Deine Linux-Distrobution nicht verfügbar ist, kannst Du stattdessen einen Paket-Manager verwenden. Bitte lese dazu diese [detaillierten Anweisungen](https://nodejs.org/en/download/package-manager/)! 28 | 29 | ## Überprüfung der Installation 30 | 31 | Unabhängig davon, welches Betriebssystem Du verwendest, solltest Du immer überprüfen, ob Node.js korrekt installiert ist. Öffne dazu einfach Deine `Windows PowerShell` oder `terminal`-Anwendung und gebe die folgenden Befehle ein: 32 | 33 | ```bash 34 | node -v 35 | ``` 36 | 37 | ```bash 38 | npm -v 39 | ``` 40 | 41 | Wenn beide Kommandos eine Versionsnummer anzeigen, ist alles in Ordnung und Du hast Node.js erfolgreich installiert! 42 | 43 | ## Fehlerbehebung 44 | 45 | **node: command not found** 46 | 47 | Unter Mac OS und Linux ist es möglich, dass Du manuell die $PATH-Variable in Deiner Shell-Konfigurationsdatei erweitern musst. Um zu überprüfen, ob diese Variable unvollständig ist, gib bitte den folgenden Befehl im `terminal` ein: 48 | 49 | ```bash 50 | echo $PATH | grep -c /usr/local/bin 51 | ``` 52 | 53 | Wenn dies eine `0` ausgibt, kannst Du dies mit dem folgenden Kommando beheben: 54 | 55 | ```bash 56 | echo "export PATH=$PATH:/usr/local/git/bin:/usr/local/bin" >> ~/.bashrc 57 | ``` 58 | 59 | Und schon bist Du fertig! 60 | 61 | !> Wenn Du eine andere Shell wie etwa `zsh` verwendst, solltest Du diesen Befehl entsprechend anpassen. 62 | -------------------------------------------------------------------------------- /docs/dev-changelog.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ### [v0.3.4] - 2018-06-01 4 | 5 | * There are new **Contribution Guidelines** in the repository and the docs! 6 | * Some additions from our new contributor [Daniel Ruf](https://github.com/DanielRuf) were merged. 7 | 8 | ### [v0.3.3] - 2018-06-01 9 | 10 | * **BUGFIX:** When the site contains relative paths to CSS and JS files, those files won't load. 11 | * **BUGFIX:** On certain sites with inaccurate code the `css` parser broke the script. I now provide an own parser. 12 | * **FEATURE:** Adobe Typekit fonts can now be detected. 13 | 14 | ### [v0.3.2] - 2018-05-27 15 | 16 | * **BUGFIX:** URL class couldn't be loaded globally at nodejs < 10 17 | * **BUGFIX:** Inline JS and CSS couldn't be loaded when there are no external files 18 | 19 | ### [v0.3.1] - 2018-05-27 20 | 21 | * Due to naming conventions in npmjs.com we changed our name from `gdpr-check` to `gdpr-cli` 22 | 23 | ### [v0.3.0] - 2018-05-27 24 | 25 | * My first publicly available release. Beware! There may be **BUGS**. :smirk: 26 | -------------------------------------------------------------------------------- /docs/dev-contrib.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | Thank you for your interest in contributing to this project! 4 | 5 | The following is a set of guidelines for contributing to **GDPR CLI**. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. 6 | 7 | ## How can I contribute? 8 | 9 | ### Reporting bugs 10 | 11 | Bugs are tracked on [Github Issues](https://github.com/mirkoschubert/gdpr-cli/issues). Before you open a new bug report on this section, please check if the bug already exists. If you find a closed issue with the same thing you're experiencing, open a new issue and include a link to the original issue. 12 | 13 | Explain the problem and include additional details to help maintainers reproduce the problem. You can also use the [Bug Report Template](https://github.com/mirkoschubert/gdpr-cli/blob/master/.github/ISSUE_TEMPLATE/bug_report.md). 14 | 15 | ### Suggesting Enhancements 16 | 17 | You can always suggest new features or other enhancements for this project on [Github Issues](https://github.com/mirkoschubert/gdpr-cli/issues). Before you open a new enhancements report, please check if a similar suggestion already has been made. You should also check the [Road Map](https://github.com/mirkoschubert/gdpr-cli#roadmap) of this project, so you're not proposing any features which are already planned for the future. 18 | 19 | Explain your suggestion as detailed as possible. You can also use the [Feature Request Template](https://github.com/mirkoschubert/gdpr-cli/blob/master/.github/ISSUE_TEMPLATE/feature_request.md). 20 | 21 | ### Your Code Contribution 22 | 23 | Unsure where to begin contributing to **GDPR CLI**? You can start with looking if any [help-wanted](https://github.com/mirkoschubert/gdpr-cli/labels/help%20wanted) issues are open. 24 | 25 | I'm really bad with writing tests, so if you're better with these kind of things, you can definitely help me. I'm using [Ava](https://github.com/avajs/ava) for now, but you can also suggest an alternative. 26 | 27 | ### Pull Requests 28 | 29 | You're always welcome so send pull requests (PRs) for optimizing my code, implementing a existing task, suggesting new enhancements or fixing bugs. Before you do, please read my [Coding Standards] and have the following points in mind: 30 | 31 | * If you're refering to an open issue, include the issue number to the description. 32 | * Send pull requests **only** to the `dev` branch. 33 | * Avoid platform dependant code and code for `node@10` only. 34 | * Please comment new code intelligibly. 35 | * If you don't use `Visual Studio Code` and the extentions `Todo+` and `Projects+ Todo+`, do **not** touch the `TODO.md` file. 36 | 37 | ## Coding Standards 38 | 39 | I code using `Visual Studio Code` with extentions like `prettier`, `eslint`, `Todo+` and `Highlight`, but those extentions aren't mandatory. But you should use an indentation of 2 spaces and only single quotes if possible. 40 | 41 | Please try to be in accordance with the already existing classes and modules. If you would change the basic structure of the software, discuss it with me first. 42 | 43 | As of now there are two main branches: 44 | 45 | * `master` is the official (and hopefully stable) version of the tool, wich is mainly used for [npm](https://www.npmjs.com/package/gdpr-cli) and the [releases](https://github.com/mirkoschubert/gdpr-cli/releases). 46 | * `dev` is the »developer edition« of the software and the main branch to push changes to. 47 | 48 | Since the `dev` branch is usually ahead, please use this one for your development and any PRs. 49 | -------------------------------------------------------------------------------- /docs/features-overview.md: -------------------------------------------------------------------------------- 1 | # Features 2 | 3 | !> This section is coming soon! 4 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /docs/installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | Now it's time for installing **GDPR CLI**. If you already installed [Node.js](https://nodejs.org/en/) this part is pretty easy. If you don't, please check the [Prerequisites](prerequisites.md)! 4 | 5 | If Node.js is working correctly, you simply have to type the following command in your preferred `terminal` application (for Windows Users `Powershell`): 6 | 7 | ```bash 8 | npm install -g gdpr-cli 9 | ``` 10 | 11 | If your package manager is `yarn`, you have to change the command accordingly: 12 | 13 | ```bash 14 | yarn global add gdpr-cli 15 | ``` 16 | 17 | Once it is run through, you're ready to use the **GDPR CLI**! 18 | 19 | !> Since it's pre alpha, the help command isn't working correctly for now. Please check the [Usage](usage.md) page instead. 20 | -------------------------------------------------------------------------------- /docs/prerequisites.md: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | 3 | This software is based on Node.js, so it is mandatory to have `node` and a package manager such as `npm` or `yarn` installed. If you don't, please follow the instructions. 4 | 5 | ## Installing Node.js 6 | 7 | Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine. Since **GDPR CLI** is written in JavaScript, it depends on this software. 8 | 9 | To download it, please visit [nodejs.org](https://nodejs.org/en/). You can either choose the LTS or current version. Just click on one of the buttons on their home page. You should get the right version for your operating system. 10 | 11 | ### Windows 12 | 13 | !> Node.js requires Windows 7 or later. If you still have an older version of Windows, please update your OS first. 14 | 15 | To install Node.js, you just have to open the previously downloaded file and follow the instructions of the installer. Once it's finished, just look for the `Windows Powershell` and open it. 16 | 17 | ### macOS 18 | 19 | To install Node.js on macOS, you just have to open the previously downloaded file and follow the instructions of the installer. Once it's finished, just look for the `terminal` application and open it. 20 | 21 | ?> If you have `homebrew` installed, just type `brew install node` instead. 22 | 23 | ### Linux 24 | 25 | To install Node.js on Linux, you just have to open the previously downloaded file and follow the instructions of the installer. Once it's finished, just open your preferred `terminal` application. 26 | 27 | ?> If an installer or binary for your Linux Distrobution isn't available, you can use your package installer instead. Please read those [detailed instructions](https://nodejs.org/en/download/package-manager/)! 28 | 29 | ## Checking the Installation 30 | 31 | Whatever operating system you're using, you should always check if Node.js is installed correctly. Simply open `Windows Powershell` or your `terminal` application and type the following commands: 32 | 33 | ```bash 34 | node -v 35 | ``` 36 | 37 | ```bash 38 | npm -v 39 | ``` 40 | 41 | If both commands display a version number, everything is okay and you have successfully installed Node.js! 42 | 43 | ## Troubleshooting 44 | 45 | **node: command not found** 46 | 47 | On macOS and Linux it is possible that you have to insert a path variable in your shell configuration file manually. To check if this path variable is missing, please type the following command in your `terminal` application: 48 | 49 | ```bash 50 | echo $PATH | grep -c /usr/local/bin 51 | ``` 52 | 53 | If it outputs a `0`, you have to fix this with the command: 54 | 55 | ```bash 56 | echo "export PATH=$PATH:/usr/local/git/bin:/usr/local/bin" >> ~/.bashrc 57 | ``` 58 | 59 | That's it, you're done! 60 | 61 | !> If you use another shell, such as `zsh`, you should change this command accordingly. 62 | -------------------------------------------------------------------------------- /docs/usage.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | If you have Node.js and **GDPR CLI** installed, you're ready to go! Just open your preferred `terminal` application or `Windows Powershell` and type: 4 | 5 | ```bash 6 | gdpr scan yourwebsite.com 7 | ``` 8 | 9 | The tool should scan the website you entered and show you some information about this site. You can use it to check if any element of the website is sending data to non-European servers and to adjust your privacy notice accordingly. 10 | 11 | The basic usage of **GDPR CLI** is: 12 | 13 | ```bash 14 | gdpr [command] [options] [URL] 15 | ``` 16 | 17 | ## Commands 18 | 19 | | Command | Meaning | 20 | | :------ | :------------------------------------------------ | 21 | | scan, s | Scan Command - scans and analyses a given website | 22 | | help | Help - **not finished yet** | 23 | 24 | 25 | ## Options 26 | 27 | There are already some Options available to specify your needs. 28 | 29 | #### Global Options 30 | 31 | | Option | Meaning | 32 | | :------------ | :---------------------------------------------------- | 33 | | -v, --verbose | Verbose Mode - outputs everything there is | 34 | | -m, --mute | Muted Mode - outputs only the results of the analysis | 35 | | -V, --version | Version - shows the version of **GDPR CLI** | 36 | | -h, --help | Help - the basic global help | 37 | 38 | #### Options for the `scan` Command 39 | 40 | | Option | Meaning | 41 | | :---------------- | :------------------------------------- | 42 | | -f, --fonts | Shows only the Fonts results | 43 | | -s, --ssl | Shows only the SSL Certificate | 44 | | -p, --prefetching | Shows only the DNS Prefetching results | 45 | | -a, --analytics | Shows only the Analytics results | 46 | 47 | 48 | ## Combination 49 | 50 | You can combine those options freely. For example: 51 | 52 | ```bash 53 | gdpr scan -vfa yourwebsite.com 54 | ``` 55 | 56 | In this case **GDPR CLI** will start in Verbose Mode and only scan for Fonts and Analytics tools. -------------------------------------------------------------------------------- /gdpr-cli-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirkoschubert/gdpr-cli/f9b2dd1e360a9c2a9f1151d324f2dcc6110fdff1/gdpr-cli-screenshot.png -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node --harmony 2 | 3 | 'use strict' 4 | 5 | const app = require('commander'); 6 | const chalk = require('chalk'); 7 | const Tasks = require('./lib/tasks'); 8 | const UI = require('./lib/ui'); 9 | 10 | 11 | const ui = new UI(); // initialize the UI 12 | 13 | app 14 | .version(require('./package.json').version, '-V, --version') 15 | .option('-v, --verbose', 'shows you every single step') 16 | .option('-m, --mute', 'shows only the results of the analysis'); 17 | 18 | app 19 | .command('scan [url]') 20 | .alias('s') 21 | .description('Scans an url') 22 | .option('-f, --fonts', 'checks if any font is loading externally', true) 23 | .option('-s, --ssl', 'checks for SSL certificate', true) 24 | .option('-p, --prefetching', 'checks for DNS prefetching') 25 | .option('-a, --analytics', 'checks for Google Analytics & Piwik') 26 | .option('-t, --tracking', 'checks for Social Media tracking & embeds') 27 | .option('-c, --cdn', 'checks for Content Delivery Networks') 28 | //.option('-r, --recursive', 'tries to follow links to check every internal site', false) 29 | .action((url, args) => { 30 | // Error Handling 31 | if (typeof url === 'undefined') { 32 | ui.error('\nYou have to set an URL.\n', false); 33 | process.exit(1); 34 | } 35 | if (url.match(/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/) === null) { 36 | ui.error('\nYou have to set a valid URL.', false); 37 | ui.info(chalk.dim('e.g. https://example.com or example.com\n')); 38 | process.exit(1); 39 | } 40 | if (args.parent.verbose && args.parent.mute) { 41 | ui.error('\nYou have to choose between silent or verbose mode!\n', false); 42 | process.exit(1); 43 | } 44 | 45 | if (args.parent.verbose) ui.set('verbose'); 46 | if (args.parent.mute) ui.set('silent'); 47 | 48 | // initialize the task runner 49 | const tasks = new Tasks(url, ui); 50 | 51 | if (args.ssl) tasks.new('ssl'); 52 | if (args.fonts) tasks.new('fonts'); 53 | if (args.prefetching) tasks.new('prefetching'); 54 | if (args.analytics) tasks.new('analytics'); 55 | if (args.cdn) tasks.new('cdn'); 56 | if (args.tracking) tasks.new('social'); 57 | 58 | tasks.run(); 59 | }); 60 | 61 | app 62 | .command('help [command]') 63 | .description('shows the help for a specific command') 64 | .action(command => { 65 | if (!command) { 66 | app.help(); 67 | } else { 68 | // specific help 69 | //app.help(command); 70 | } 71 | }); 72 | 73 | app.parse(process.argv); 74 | 75 | //if (!app.args.length) app.help(); -------------------------------------------------------------------------------- /lib/helpers.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const URL = require('url').URL; 4 | const sslCert = require('get-ssl-certificate'); 5 | 6 | 7 | function normalizeURL(Url) { 8 | 9 | if (Url.href.protocol !== '') { 10 | 11 | } else { 12 | 13 | } 14 | 15 | } 16 | 17 | 18 | function getSSLCertificate(url) { 19 | return new Promise((resolve, reject) => { 20 | sslCert.get(url).then(cert => { 21 | resolve(cert); 22 | }).catch(e => { 23 | reject(e); 24 | }); 25 | }); 26 | } 27 | 28 | module.exports = { 29 | getSSLCertificate, 30 | normalizeURL 31 | }; -------------------------------------------------------------------------------- /lib/html-parser.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const URL = require('url').URL; // for backwards compability (node < 10) 4 | const cheerio = require('cheerio'); 5 | 6 | class HTMLParser { 7 | 8 | constructor(html) { 9 | this.html = html; 10 | this.$ = cheerio.load(this.html); 11 | } 12 | 13 | getInlineCSS() { 14 | let inlineCSS = []; 15 | this.$('style').each((id, el) => { 16 | if (typeof el.attribs.src === 'undefined') { 17 | el.children.forEach(child => { 18 | inlineCSS.push(child.data); 19 | }); 20 | } 21 | }); 22 | return inlineCSS; 23 | } 24 | 25 | getInlineJS() { 26 | let inlineJS = []; 27 | this.$('script').each((id, el) => { 28 | if (typeof el.attribs.src === 'undefined') { 29 | el.children.forEach(child => { 30 | inlineJS.push(child.data); 31 | }); 32 | } 33 | }); 34 | return inlineJS; 35 | } 36 | 37 | getStylesheetURLs(url) { 38 | const Url = new URL(url); 39 | let stylesheets = []; 40 | 41 | this.$('link').each((id, el) => { 42 | if (el.attribs.rel === 'stylesheet' && typeof el.attribs.href !== 'undefined') { 43 | let style = {}; 44 | let res = el.attribs.href; 45 | if (res.match(/https?:\/\//) === null) { // protocol is not available 46 | if (!res.startsWith('//')) { // relative 47 | res = Url.protocol + '//' + Url.host + ((!res.startsWith('/')) ? '/' : '') + res; 48 | } else res = Url.protocol + res; // without protocol, but still not relative 49 | } 50 | style.url = new URL(res); 51 | stylesheets.push(style); 52 | } 53 | }); 54 | return stylesheets; 55 | } 56 | 57 | getJavascriptURLs(url) { 58 | const Url = new URL(url); 59 | let javascripts = []; 60 | 61 | this.$('script').each((id, el) => { 62 | if (typeof el.attribs.src !== 'undefined') { 63 | let js = {}; 64 | let res = el.attribs.src; 65 | if (res.match(/https?:\/\//) === null) { // protocol is not available 66 | if (!res.startsWith('//')) { // relative 67 | res = Url.protocol + '//' + Url.host + ((!res.startsWith('/')) ? '/' : '') + res; 68 | } else res = Url.protocol + res; // without protocol, but still not relative 69 | } 70 | js.url = new URL(res); 71 | javascripts.push(js); 72 | } 73 | }); 74 | return javascripts; 75 | } 76 | 77 | getImageURLs(url) { 78 | const Url = new URL(url); 79 | let images = []; 80 | this.$('img').each((id, el) => { 81 | if (typeof el.attribs.src !== 'undefined') { 82 | let img = {}; 83 | let res = el.attribs.src; 84 | if (res.match(/https?:\/\//) === null) { 85 | res = (!res.startsWith('//')) ? res = Url.protocol + '//' + Url.host + ((!res.startsWith('/')) ? '/' : '') + res : Url.protocol + res; 86 | } 87 | img.url = new URL(res); 88 | images.push(img); 89 | } 90 | }); 91 | return images; 92 | } 93 | 94 | getiFrames() { 95 | let iframes = []; 96 | this.$('iframe').each((id, el) => { 97 | if (typeof el.attribs.src !== 'undefined') iframes.push(el.attribs.src); 98 | }); 99 | return iframes; 100 | } 101 | 102 | getMetaData() { 103 | let metatags = {}; 104 | this.$('meta').each((id, el) => { 105 | const key = Object.keys(el.attribs).find((attr) => ['name', 'property', 'itemprop', 'http-equiv'].indexOf(attr) !== -1); 106 | const name = el.attribs[key]; 107 | const value = el.attribs['content']; 108 | if (!metatags[name]) { 109 | metatags[name] = []; 110 | } 111 | metatags[name].push(value); 112 | }); 113 | return metatags; 114 | } 115 | 116 | checkPrefetching() { 117 | let prefetching = []; 118 | this.$('link').each((id, el) => { 119 | if (el.attribs.rel === 'dns-prefetch') prefetching.push(el.attribs.href); 120 | }); 121 | return prefetching; 122 | } 123 | 124 | } 125 | 126 | module.exports = HTMLParser; -------------------------------------------------------------------------------- /lib/loader.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const URL = require('url').URL; // for backwards compability (node < 10) 4 | const cheerio = require('cheerio'); 5 | 6 | class Loader { 7 | 8 | constructor() { 9 | this.html = {}; 10 | this.css = {}; 11 | this.js = {}; 12 | this.img = {}; 13 | } 14 | 15 | 16 | 17 | 18 | 19 | } 20 | 21 | module.exports = Loader; -------------------------------------------------------------------------------- /lib/modules/analytics.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // INFO: Check feature 4 | 5 | /** 6 | * Checks if Google Analytics is installed 7 | * @returns boolean 8 | */ 9 | function hasGoogleAnalytics(js) { 10 | let ga = false; 11 | js.inline.forEach(el => { 12 | if (el.indexOf('google-analytics.com/analytics.js') !== -1 && el.match(/(\(\'create)(.*)(\))/) !== null) ga = true; 13 | if (el.indexOf('google-analytics.com/ga.js') !== -1 && el.indexOf('_gaq.push') !== -1) ga = true; 14 | }); 15 | return ga; 16 | } 17 | 18 | /** 19 | * Checks if the Google Tag Manager is installed 20 | * @returns boolean 21 | */ 22 | function hasGoogleTagManager(js) { 23 | // Example desireekeunecke.com 24 | let gtag = false; 25 | js.forEach(el => { 26 | if (el.url.href.match(/googletagmanager\.com\/gtag/) !== null) gtag = true; 27 | }); 28 | return gtag; 29 | } 30 | 31 | 32 | /** 33 | * Checks if the Matomo/ Piwik analytics tool is installed 34 | * @returns boolean 35 | */ 36 | function hasPiwik(js) { 37 | // Example riamarleen.de 38 | let pw = false; 39 | js.inline.forEach(el => { 40 | if (el.match(/u\+\'piwik.php\'/) !== null) pw = true; 41 | }); 42 | return pw; 43 | } 44 | 45 | 46 | function hasWordPressStats(js) { 47 | // Example sandratetznerfotodesign.com 48 | // TODO: pixel.wp.com Image e.g. t3n.de 49 | let ws = false; 50 | js.forEach(el => { 51 | if (el.url.href.indexOf('stats.wp.com') !== -1) ws = true; 52 | }); 53 | return ws; 54 | } 55 | 56 | // INFO: Details Functions 57 | 58 | 59 | /** 60 | * Reads Property ID and Features of Google Analytics 61 | * @class JSParser 62 | */ 63 | function getGoogleAnalyticsDetails(js) { 64 | 65 | let entry = {}; 66 | 67 | // TODO: more than one Snippet 68 | 69 | js.inline.forEach(el => { 70 | const hasStandardGA = el.indexOf('google-analytics.com/analytics.js') !== -1 && el.match(/(\(\'create)(.*)(\))/) !== null; 71 | const hasLegacyGA = el.indexOf('google-analytics.com/ga.js') !== -1 && el.indexOf('_gaq.push') !== -1; 72 | //if (hasStandardGA || hasLegacyGA) console.log(el); 73 | 74 | if (hasStandardGA) { 75 | entry.property_id = el.match(/UA\-[0-9]*\-[0-9]/)[0]; 76 | entry.anonymize_ip = el.indexOf('\'anonymizeIp\', true') !== -1; 77 | entry.force_ssl = el.indexOf('\'forceSSL\', true') !== -1; 78 | entry.type = 'standard'; 79 | } else if (hasLegacyGA) { 80 | entry.property_id = el.match(/UA\-[0-9]*\-[0-9]/)[0]; 81 | entry.anonymize_ip = el.indexOf('_gat._anonymizeIp') !== -1; 82 | entry.force_ssl = el.indexOf('_gat._forceSSL') !== -1; 83 | entry.type = 'legacy'; 84 | } 85 | }); 86 | return (Object.keys(entry).length > 0) ? entry : undefined; 87 | } 88 | 89 | 90 | /** 91 | * Reads Property ID and Features of Google Tag Manager 92 | * @class JSParser 93 | */ 94 | function getGoogleTagManagerDetails(js) { 95 | 96 | let entry = {}; 97 | 98 | if (hasGoogleTagManager(js)) { 99 | js.inline.forEach(el => { 100 | 101 | const config = el.match(/(gtag\(\'config\')(.*)(\))/); 102 | if (config !== null) { 103 | entry.property_id = config[0].match(/UA\-[0-9]*\-[0-9]/)[0]; 104 | entry.anonymize_ip = config[0].indexOf('\'anonymize_ip\': true') !== -1; 105 | } 106 | }); 107 | return entry; 108 | } else return; 109 | } 110 | 111 | 112 | /** 113 | * Reads URL and additional features of Piwik 114 | */ 115 | function getPiwikDetails(js) { 116 | let entry = {}; 117 | if (hasPiwik(js)) { 118 | js.inline.forEach(el => { 119 | 120 | const config = el.match(/(_paq.push\()(.*)(\))/); 121 | if (config !== null) { 122 | entry.url = config.input.match(/(var\su\=[\"\'])(.*)([\"\'])/)[2]; 123 | entry.site_id = config.input.match(/(_paq.push\(\[\'setSiteId\',\s\')(.*)(\'\]\))/)[2]; 124 | } 125 | }); 126 | return entry; 127 | } else return; 128 | } 129 | 130 | 131 | module.exports = { 132 | hasGoogleAnalytics, 133 | hasGoogleTagManager, 134 | hasPiwik, 135 | hasWordPressStats, 136 | getGoogleAnalyticsDetails, 137 | getGoogleTagManagerDetails, 138 | getPiwikDetails 139 | }; -------------------------------------------------------------------------------- /lib/modules/fonts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const URL = require('url').URL; 4 | 5 | class FontsParser { 6 | 7 | constructor(css, js, localUrl) { 8 | this.localUrl = localUrl; 9 | this.css = css || []; 10 | this.js = js || []; 11 | 12 | this.fonts = {}; 13 | } 14 | 15 | /** 16 | * Main Function, returns an Fonts Object 17 | * @class FontsParser 18 | */ 19 | getFonts() { 20 | if (this.hasAutoptimize()) this.fonts = this.getAutoptimizeFonts() 21 | 22 | if (this.hasLocalFonts()) this.fonts.local = this.getLocalFonts(); 23 | if (this.hasWordPressFonts()) this.fonts.wordpress = this.getWordPressFonts(); 24 | if (this.hasGoogleFonts()) this.fonts.google = this.getGoogleFonts(); 25 | 26 | if (this.hasTypekitJS() || this.hasTypekitCSS()) this.fonts.typekit = []; 27 | if (this.hasTypekitJS()) this.getTypekitJSFonts().forEach(f => this.fonts.typekit.push(f)); 28 | if (this.hasTypekitCSS()) this.getTypekitCSSFonts().forEach(f => this.fonts.typekit.push(f)); 29 | 30 | return this.fonts; 31 | } 32 | 33 | // INFO: Features 34 | 35 | hasAutoptimize() { 36 | let ao = false; 37 | this.css.forEach(el => { 38 | if (el.url.href.indexOf('/wp-content/cache/autoptimize/css/') !== -1) ao = true; 39 | }); 40 | return ao; 41 | } 42 | 43 | getAutoptimizeFonts() { 44 | let fonts = []; 45 | 46 | this.css.forEach(el => { 47 | if (el.url.href.indexOf('/wp-content/cache/autoptimize/css/') !== -1) { 48 | let fontfaces = el.content.match(/\@font-face\s?{([^}]*)/gm); 49 | if (fontfaces !== null) { 50 | fontfaces.forEach(ff => { 51 | let font = {}; 52 | font.font = this.getFontName(ff); 53 | if (this.getFontStyle(ff) !== '') font.style = this.getFontStyle(ff); 54 | if (this.getFontWeight(ff) !== '') font.weight = this.getFontWeight(ff); 55 | font.type = this.getFontType(ff, this.localUrl); 56 | 57 | fonts.push(font); 58 | }); 59 | } 60 | } 61 | }); 62 | return this.sortFonts(this.removeDuplicates(fonts)); 63 | } 64 | 65 | hasLocalFonts() { 66 | let lf = false; 67 | this.css.forEach(el => { 68 | if (el.url.host === this.localUrl.host && el.content.indexOf('@font-face') !== -1) lf = true; 69 | }); 70 | this.css.inline.forEach(el => { 71 | if (el.indexOf('@font-face') !== -1) { 72 | let fontfaces = el.match(/\@font-face\s?{([^}]*)/gm); 73 | if (fontfaces !== null) { 74 | fontfaces.forEach(ff => { 75 | if (this.getFontType(ff) === 'local') lf = true; 76 | }); 77 | } 78 | } 79 | }); 80 | return lf; 81 | } 82 | 83 | getLocalFonts() { 84 | let fonts = []; 85 | 86 | this.css.forEach(el => { 87 | if (el.url.host === this.localUrl.host) { 88 | let fontfaces = el.content.match(/\@font-face\s?{([^}]*)/gm); 89 | if (fontfaces !== null) { 90 | fontfaces.forEach(ff => { 91 | if (this.getFontType(ff) === 'local') { 92 | let font = {}; 93 | font.font = this.getFontName(ff); 94 | if (this.getFontStyle(ff) !== '') font.style = this.getFontStyle(ff); 95 | if (this.getFontWeight(ff) !== '') font.weight = this.getFontWeight(ff); 96 | font.type = 'local'; 97 | fonts.push(font); 98 | } 99 | }); 100 | } 101 | } 102 | }); 103 | this.css.inline.forEach(el => { 104 | let fontfaces = el.match(/\@font-face\s?{([^}]*)/gm); 105 | if (fontfaces !== null) { 106 | fontfaces.forEach(ff => { 107 | if (this.getFontType(ff) === 'local') { 108 | let font = {}; 109 | font.font = this.getFontName(ff); 110 | if (this.getFontStyle(ff) !== '') font.style = this.getFontStyle(ff); 111 | if (this.getFontWeight(ff) !== '') font.weight = this.getFontWeight(ff); 112 | font.type = 'local'; 113 | fonts.push(font); 114 | } 115 | }); 116 | } 117 | }); 118 | return this.removeDuplicates(fonts); 119 | } 120 | 121 | hasWordPressFonts() { 122 | let wf = false; 123 | this.css.forEach(el => { 124 | if (el.url.href.match(/s[0-9]?\.wp\.com/) !== null && 125 | el.content.match(/\@font\-face/)) 126 | wf = true; 127 | }); 128 | return wf; 129 | } 130 | 131 | getWordPressFonts() { 132 | let fonts = []; 133 | this.css.forEach(el => { 134 | if (el.url.href.match(/s[0-9]?\.wp\.com/)) { 135 | let fontfaces = el.content.match(/\@font-face\s?{([^}]*)/gm); 136 | if (fontfaces !== null) { 137 | fontfaces.forEach(ff => { 138 | ['Noticons', 'Genericons', 'social-logos'].forEach(f => { 139 | if (ff.indexOf(f) !== -1 && 140 | JSON.stringify(fonts).indexOf(f) === -1) 141 | fonts.push({ 142 | font: f, 143 | source: 'wordpress' 144 | }); 145 | }); 146 | }); 147 | } 148 | } 149 | }); 150 | return this.removeDuplicates(fonts); 151 | } 152 | 153 | hasGoogleFonts() { 154 | let gf = false; 155 | this.css.forEach(el => { 156 | if (el.url.href.indexOf('fonts.googleapis.com') !== -1) gf = true; 157 | }); 158 | return gf; 159 | } 160 | 161 | getGoogleFonts() { 162 | let fonts = []; 163 | this.css.forEach(el => { 164 | if (el.url.href.indexOf('fonts.googleapis.com') !== -1) { 165 | let fontfaces = el.content.match(/\@font-face\s?{([^}]*)/gm); 166 | if (fontfaces !== null) { 167 | fontfaces.forEach(ff => { 168 | let font = {}; 169 | font.font = this.getFontName(ff); 170 | if (this.getFontStyle(ff) !== '') font.style = this.getFontStyle(ff); 171 | if (this.getFontWeight(ff) !== '') font.weight = this.getFontWeight(ff); 172 | font.type = 'google'; 173 | fonts.push(font); 174 | }); 175 | } 176 | } 177 | }); 178 | return this.removeDuplicates(fonts); 179 | } 180 | 181 | hasTypekitCSS() { 182 | let tk = false; 183 | this.css.forEach(el => { 184 | if (el.url.href.indexOf('use.typekit.net') !== -1) tk = true; 185 | }); 186 | return tk; 187 | } 188 | 189 | getTypekitCSSFonts() { 190 | let fonts = []; 191 | this.css.forEach(el => { 192 | if (el.url.href.indexOf('use.typekit.net') !== -1) { 193 | let fontfaces = el.content.match(/\@font-face\s?{([^}]*)/gm); 194 | if (fontfaces !== null) { 195 | fontfaces.forEach(ff => { 196 | let font = {}; 197 | font.font = this.getFontName(ff); 198 | if (this.getFontStyle(ff) !== '') font.style = this.getFontStyle(ff); 199 | if (this.getFontWeight(ff) !== '') font.weight = this.getFontWeight(ff); 200 | font.type = 'typekit'; 201 | fonts.push(font); 202 | }); 203 | } 204 | } 205 | }); 206 | return this.removeDuplicates(fonts); 207 | } 208 | 209 | hasTypekitJS() { 210 | let tk = false; 211 | this.js.forEach(js => { 212 | if (js.url.href.indexOf('use.typekit.net') !== -1) tk = true; 213 | }); 214 | return tk; 215 | } 216 | 217 | getTypekitJSFonts() { 218 | let fonts = []; 219 | this.js.forEach(js => { 220 | if (js.url.href.indexOf('use.typekit.net') !== -1) { 221 | let conf = JSON.parse(js.content.match(/window.Typekit.config\s?\=\s?([^;]*)/)[1]); 222 | conf.fc.forEach(f => { 223 | let font = {}; 224 | font.font = f.family; 225 | font.style = f.descriptors.style; 226 | font.weight = f.descriptors.weight; 227 | font.source = 'typekit' 228 | fonts.push(font); 229 | }); 230 | } 231 | }); 232 | return this.removeDuplicates(fonts); 233 | } 234 | 235 | 236 | // INFO: RegEx functions 237 | 238 | /** 239 | * Gets the name of the font 240 | * @param {string} fontface 241 | * @class FontsParser 242 | */ 243 | getFontName(fontface) { 244 | return fontface.match(/font\-family\:\s?['"]?([^'";]*)/)[1]; 245 | } 246 | 247 | 248 | /** 249 | * Gets the style of the font 250 | * @param {string} fontface 251 | * @class FontsParser 252 | */ 253 | getFontStyle(fontface) { 254 | let style = ''; 255 | if (fontface.match(/font\-style\:\s?['"]?([^'";]*)/) !== null) 256 | style = fontface.match(/font\-style\:\s?['"]?([^'";]*)/)[1]; 257 | return style; 258 | } 259 | 260 | 261 | /** 262 | * Gets the weight of the font 263 | * @param {string} fontface 264 | * @class FontsParser 265 | */ 266 | getFontWeight(fontface) { 267 | let weight = ''; 268 | if (fontface.match(/font\-weight\:\s?['"]?([^'";]*)/) !== null) 269 | weight = fontface.match(/font\-weight\:\s?['"]?([^'";]*)/)[1]; 270 | if (weight === 'normal') weight = '400'; 271 | if (weight === 'bold') weight = '700'; 272 | return weight; 273 | } 274 | 275 | 276 | /** 277 | * Gets the font type 278 | * @param {string} fontface 279 | * @param {URL} localUrl 280 | * @class FontsParser 281 | */ 282 | getFontType(fontface) { 283 | let type = ''; 284 | let url = fontface.match(/url\(['"]?([^'"\)]*)/)[1]; 285 | url = (url.startsWith('//')) ? this.localUrl.protocol + url : url; 286 | if (url.startsWith('http')) { 287 | let Url = new URL(url); 288 | if (Url.host === this.localUrl.host) type = 'local'; 289 | if (Url.host.indexOf('wordpress.com') !== -1) type = 'wordpress'; 290 | if (Url.host.indexOf('fonts.gstatic.com') !== -1) type = 'google'; 291 | if (Url.host.indexOf('use.typekit.net') !== -1) type = 'typekit'; 292 | if (Url.host.indexOf('use.fontawesome.com') !== -1) type = 'awesome'; 293 | } else type = 'local'; // relative url 294 | 295 | return type; 296 | } 297 | 298 | // INFO: Visual functions 299 | 300 | 301 | /** 302 | * Shortcut to search for a specific font in a section 303 | * @param {array} section 304 | * @param {string} font 305 | */ 306 | getFontStyles(section, font) { 307 | let styles = {}; 308 | let output = ''; 309 | 310 | section.forEach(f => { 311 | if (f.font === font) { 312 | if (typeof f.style !== 'undefined') { 313 | if (typeof styles[f.style] === 'undefined') styles[f.style] = []; 314 | styles[f.style].push(f.weight); 315 | } 316 | } 317 | }); 318 | for (let style in styles) { 319 | output += style + ' (' + styles[style].join(', ') + ') '; 320 | } 321 | return output; 322 | } 323 | 324 | 325 | // INFO: helper functions 326 | 327 | /** 328 | * Counts and lists all fonts of a specific section 329 | * @param {array} section 330 | */ 331 | countFonts(section) { 332 | let fonts = []; 333 | section.forEach(f => { 334 | if (fonts.indexOf(f.font) === -1) fonts.push(f.font); 335 | }); 336 | return fonts; 337 | } 338 | 339 | 340 | /** 341 | * Sorts fonts by type 342 | * @param {array} fonts 343 | * @returns {object} sorted 344 | * @class FontsParser 345 | */ 346 | sortFonts(fonts) { 347 | const types = ['local', 'wordpress', 'google', 'typekit', 'awesome']; 348 | let sorted = {}; 349 | fonts.forEach(font => { 350 | if (types.indexOf(font.type) !== -1) { 351 | if (typeof sorted[font.type] === 'undefined') { 352 | sorted[font.type] = []; 353 | sorted[font.type].push(font); 354 | } else sorted[font.type].push(font); 355 | } 356 | }); 357 | return sorted; 358 | } 359 | 360 | 361 | /** 362 | * Revove duplicates from an Fonts-Array 363 | * @param {array} arr 364 | * @class FontsParser 365 | */ 366 | removeDuplicates(arr) { 367 | return arr 368 | .reduce( 369 | function (p, c) { 370 | var id = [c.font, c.style, c.weight, c.type].join('|'); 371 | 372 | if (p.temp.indexOf(id) === -1) { 373 | p.out.push(c); 374 | p.temp.push(id); 375 | } 376 | return p; 377 | }, { 378 | temp: [], 379 | out: [] 380 | }) 381 | .out; 382 | } 383 | 384 | } 385 | 386 | module.exports = FontsParser; -------------------------------------------------------------------------------- /lib/modules/info.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const cheerio = require('cheerio'); 4 | 5 | 6 | function isWordPress(info) { 7 | return info.generators.some(gen => { 8 | return gen.toLowerCase().indexOf('wordpress') !== -1 || gen.toLowerCase().indexOf('wpml') !== -1; 9 | }); 10 | } 11 | 12 | 13 | function getInfo(data) { 14 | 15 | const $ = cheerio.load(data.html.content); 16 | let info = {}; 17 | 18 | // Title 19 | info.title = ($('title').length > 1) ? $('title').first().text() : $('title').text(); 20 | if (typeof info.title !== 'string' || info.title === '') { 21 | $('meta').each((i, el) => { 22 | if (el.attribs.property === 'og:title') info.title = el.attribs.content; 23 | }); 24 | } 25 | 26 | // Description 27 | info.description = ''; 28 | $('meta').each((i, el) => { 29 | if (el.attribs.name === 'description') info.description = el.attribs.content; 30 | if (info.description === '' && el.attribs.property === 'og:description') info.description = el.attribs.content; 31 | }); 32 | 33 | // URL 34 | info.url = data.html.url.href; 35 | 36 | // Software / Generator 37 | let generators = []; 38 | $('meta').each((i, el) => { 39 | if (el.attribs.name === 'generator') generators.push(el.attribs.content); 40 | }); 41 | if (generators.length === 0) { 42 | for (const css of data.css) { 43 | if (css.url.href.indexOf('wp-content') !== -1 || css.url.href.indexOf('wp-includes') !== -1) { 44 | generators.push('WordPress'); 45 | break; 46 | } 47 | } 48 | } 49 | info.generators = generators; 50 | 51 | // Optional: WordPress Theme 52 | if (isWordPress(info)) { 53 | 54 | // Theme 55 | data.css.forEach(css => { 56 | const match = css.url.href.match(/themes\/([^\/]*)(.*)\/style\.css/); 57 | if (match !== null) { 58 | info.theme = match[1]; 59 | info.theme = info.theme.charAt(0).toUpperCase() + info.theme.slice(1); // Capitalize 60 | }; 61 | }); 62 | 63 | // Plugins 64 | let pl = []; 65 | data.css.forEach(css => { 66 | const match = css.url.href.match(/plugins\/([^\/]*)/); 67 | if (match !== null) pl.push(match[1]); 68 | }); 69 | data.js.forEach(js => { 70 | const match = js.url.href.match(/plugins\/([^\/]*)/); 71 | if (match !== null) pl.push(match[1]); 72 | }); 73 | if (pl.length > 0) { 74 | // remove duplicates 75 | pl = pl.filter((el, i) => { 76 | return pl.indexOf(el) === i; 77 | }); 78 | // convert to readable names 79 | pl.forEach((el, i) => { 80 | let words = el.split('-'); 81 | words.forEach((word, j) => { 82 | words[j] = word.charAt(0).toUpperCase() + word.slice(1); // Capitalize 83 | }); 84 | pl[i] = words.join(' '); 85 | }); 86 | info.plugins = pl; 87 | } 88 | } 89 | return info; 90 | } 91 | 92 | module.exports = { 93 | isWordPress, 94 | getInfo 95 | }; -------------------------------------------------------------------------------- /lib/modules/social.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // connext.facebook.net 4 | function hasFacebookConnect(js) { 5 | let fc = false; 6 | js.inline.forEach(js => { 7 | if (js.indexOf('connect.facebook.net') !== -1) fc = true; 8 | }); 9 | return fc; 10 | } 11 | 12 | // graph.facebook.com 13 | function hasFacebookSocialGraph(js) { 14 | let sg = false; 15 | js.forEach(el => { 16 | if (el.url.host === 'graph.facebook.com') sg = true; 17 | if (el.content.indexOf('graph.facebook.com') !== -1) sg = true; 18 | }); 19 | return sg; 20 | } 21 | 22 | // api.pinterest.com 23 | function hasPinterest(js) { 24 | let pi = false; 25 | js.forEach(el => { 26 | if (el.url.host === 'api.pinterest.com') pi = true; 27 | if (el.content.indexOf('api.pinterest.com') !== -1) pi = true; 28 | }); 29 | return pi; 30 | } 31 | 32 | module.exports = { 33 | hasFacebookConnect, 34 | hasFacebookSocialGraph, 35 | hasPinterest 36 | }; -------------------------------------------------------------------------------- /lib/tasks.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const URL = require('url').URL; // for backwards compability (node < 10) 4 | const got = require('got'); 5 | const chalk = require('chalk'); 6 | const sslCert = require('get-ssl-certificate'); 7 | const Loader = require('./loader'); 8 | const HTMLParser = require('./html-parser'); 9 | // const tools = require('./tools'); 10 | const UI = require('./ui'); 11 | 12 | class Tasks { 13 | constructor(url, uiInstance) { 14 | this.default_tasks = { 15 | normalize: { 16 | dependencies: [], 17 | mandatory: true 18 | }, 19 | html: { 20 | dependencies: [] 21 | }, 22 | css: { 23 | dependencies: ['html'] 24 | }, 25 | js: { 26 | dependencies: ['html'] 27 | }, 28 | img: { 29 | dependencies: ['html'] 30 | }, 31 | general: { 32 | dependencies: ['html', 'css', 'js'], 33 | mandatory: true 34 | }, 35 | ssl: { 36 | dependencies: ['html', 'css'] 37 | }, 38 | fonts: { 39 | dependencies: ['html', 'css'] 40 | }, 41 | prefetching: { 42 | dependencies: ['html', 'css'] 43 | }, 44 | analytics: { 45 | dependencies: ['html', 'css', 'js', 'img'] 46 | }, 47 | cdn: { 48 | dependencies: ['html', 'css', 'js'] 49 | }, 50 | social: { 51 | dependencies: ['html', 'css', 'js'] 52 | } 53 | }; 54 | 55 | this.default_headers = { 56 | 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36' 57 | } 58 | 59 | // Classes implementation 60 | this.ui = (!uiInstance) ? new UI() : uiInstance; 61 | this.loader = new Loader(); 62 | this.hp; 63 | 64 | this.url = url; 65 | this.tasks = []; 66 | this.data = {}; 67 | 68 | // Put mandatory tasks already in the task list 69 | this.tasks = this.tasks.concat(this.getMandatoryTasks()); 70 | } 71 | 72 | 73 | /** 74 | * Adds a new Task to the list 75 | * @param {string} task 76 | * @class Tasks 77 | */ 78 | new(task) { 79 | this.default_tasks[task].dependencies.forEach(dep => { 80 | if (this.tasks.indexOf(dep) === -1) this.tasks.push(dep); 81 | }); 82 | if (this.tasks.indexOf(task) === -1) this.tasks.push(task); 83 | } 84 | 85 | 86 | /** 87 | * Revoves a Task from the list 88 | * @param {string} task 89 | * @class Tasks 90 | */ 91 | remove(task) { 92 | if (this.tasks.indexOf(task) !== -1) { 93 | this.tasks.splice(this.tasks.indexOf(task), 1); 94 | } 95 | } 96 | 97 | 98 | /** 99 | * Checks if the task list has a specifig task 100 | * @param {string} task 101 | * @class Tasks 102 | */ 103 | hasTask(task) { 104 | return this.tasks.indexOf(task) !== -1; 105 | } 106 | 107 | 108 | /** 109 | * Gets all Tasks, which are mandatory - even with Task Selectors 110 | * @class Tasks 111 | */ 112 | getMandatoryTasks() { 113 | let t = []; 114 | for (const task in this.default_tasks) { 115 | if (this.default_tasks[task].mandatory) { 116 | this.default_tasks[task].dependencies.forEach(dep => { 117 | if (t.indexOf(dep) === -1) t.push(dep); 118 | }); 119 | t.push(task); 120 | } 121 | } 122 | return t; 123 | } 124 | 125 | 126 | /** 127 | * Prepare Task Runner Array 128 | * @class Tasks 129 | */ 130 | prepareTasks() { 131 | // if no tasks specified do them all 132 | if (this.tasks.length === this.getMandatoryTasks().length) { 133 | for (const t in this.default_tasks) this.new(t); 134 | } 135 | this.tasks.forEach(t => { 136 | this.data[t] = {}; 137 | }); 138 | } 139 | 140 | 141 | /** 142 | * Runs the Task Manager 143 | * @class Tasks 144 | */ 145 | run() { 146 | console.log(''); 147 | this.prepareTasks(); 148 | // console.log('Tasks: ', this.tasks); 149 | 150 | if (this.tasks.indexOf('html') !== -1) { 151 | this.normalizeURL() 152 | .then(() => this.processHTML()) 153 | .then(() => this.processCSS()) 154 | .then(() => this.processJS()) 155 | .then(() => this.processSSL()) 156 | .then(() => { 157 | // console.log('Remaining: ', this.tasks); 158 | 159 | this.getGeneralInformation(); 160 | this.getSSLInformation(); 161 | this.getFontInformation(); 162 | this.getSocialMediaInformation(); 163 | this.getPrefetchingInformation(); 164 | this.getAnalyticsInformation(); 165 | this.getCDNInformation(); 166 | 167 | console.log(''); 168 | // console.log('Remaining: ', this.tasks); 169 | }) 170 | .catch(e => console.log(e.message)); 171 | } 172 | } 173 | 174 | 175 | // INFO: Content Creation 176 | 177 | 178 | getSocialMediaInformation() { 179 | 180 | if (this.hasTask('social')) { 181 | 182 | const social = require('./modules/social'); 183 | this.data.social.fb_connect = social.hasFacebookConnect(this.data.js); 184 | this.data.social.fb_graph = social.hasFacebookSocialGraph(this.data.js); 185 | this.data.social.pinterest = social.hasPinterest(this.data.js); 186 | 187 | //console.log('FB CONNECT:', this.data.social.fb_connect); 188 | //console.log('FB SOCIAL GRAPH:', this.data.social.fb_graph); 189 | //console.log('PINTEREST:', this.data.social.pinterest); 190 | 191 | 192 | this.remove('social'); 193 | } 194 | } 195 | 196 | 197 | getCDNInformation() { 198 | if (this.hasTask('cdn')) { 199 | const cdns = require('../data/cdn.json'); 200 | // gather information 201 | let found = []; 202 | cdns.forEach(cdn => { 203 | this.data.css.forEach(css => { 204 | if (css.url.href.indexOf(cdn.host) !== -1) found.push(cdn); 205 | }); 206 | this.data.js.forEach(js => { 207 | if (js.url.href.indexOf(cdn.host) !== -1) found.push(cdn); 208 | }); 209 | }); 210 | // Remove Duplicates 211 | found = found.filter((el, i) => { 212 | return found.indexOf(el) === i; 213 | }); 214 | // Formatted Output 215 | this.ui.headline('Content Delivery Networks'); 216 | this.ui.settable({ 217 | cells: 3, 218 | widths: [5, 30, 0] 219 | }); 220 | if (found.length > 0) { 221 | this.ui.info(chalk.yellow(this.data.html.url.hostname) + ' uses ' + chalk.red(found.length) + ' Content Delivery Networks.\n'); 222 | found.forEach((cdn, i) => { 223 | this.ui.tableitem( 224 | [chalk.yellow(String(i + 1) + '.'), cdn.host, chalk.dim(cdn.description)]); 225 | }); 226 | } else this.ui.info('No Content Delivery Networks have been found.'); 227 | this.remove('cdn'); 228 | } 229 | } 230 | 231 | 232 | getAnalyticsInformation() { 233 | if (this.hasTask('analytics')) { 234 | const analytics = require('./modules/analytics'); 235 | if (analytics.hasGoogleAnalytics(this.data.js)) this.data.analytics.ga = analytics.getGoogleAnalyticsDetails(this.data.js); 236 | if (analytics.hasGoogleTagManager(this.data.js)) this.data.analytics.gtag = analytics.getGoogleTagManagerDetails(this.data.js); 237 | if (analytics.hasPiwik(this.data.js)) this.data.analytics.piwik = analytics.getPiwikDetails(this.data.js); 238 | if (analytics.hasWordPressStats(this.data.js)) this.data.analytics.wordpress = true; 239 | //console.log(this.data.analytics); 240 | 241 | this.ui.headline('Analytics'); 242 | if (typeof this.data.analytics.ga === 'undefined' && typeof this.data.analytics.gtag === 'undefined' && 243 | typeof this.data.analytics.piwik === 'undefined' && typeof this.data.analytics.wordpress === 'undefined') 244 | this.ui.info('No Analytics Tool has been found.'); 245 | 246 | if (typeof this.data.analytics.ga !== 'undefined') { 247 | this.ui.info(chalk.red('Google Analytics') + ' has been found.\n'); 248 | this.ui.listitem('Property ID', this.data.analytics.ga.property_id); 249 | this.ui.listitem('Anonymized IP', (this.data.analytics.ga.anonymize_ip) ? 'Yes' : 'No'); 250 | this.ui.listitem('Force SSL', (this.data.analytics.ga.force_ssl) ? 'Yes' : 'No'); 251 | 252 | if (this.data.analytics.ga.type === 'legacy') this.ui.info('\n' + chalk.red('Warning!') + ' ' + chalk.yellow(this.data.html.url.host) + ' uses the legacy ga.js code snippet (deprecated).'); 253 | } 254 | if (typeof this.data.analytics.gtag !== 'undefined') { 255 | this.ui.info( 256 | 'The ' + chalk.red('Google Tag Manager') + ' has been found.\n'); 257 | this.ui.listitem('Property ID', this.data.analytics.gtag.property_id); 258 | this.ui.listitem('Anonymized IP', (this.data.analytics.gtag.anonymize_ip) ? 'Yes' : 'No'); 259 | } 260 | if (typeof this.data.analytics.piwik !== 'undefined') { 261 | this.ui.info(chalk.red('Matomo') + ' has been found.\n'); 262 | this.ui.listitem('Matomo URL', this.data.analytics.piwik.url); 263 | this.ui.listitem('Site ID', this.data.analytics.piwik.site_id); 264 | } 265 | if (typeof this.data.analytics.wordpress !== 'undefined') { 266 | this.ui.info( 267 | 'The ' + chalk.red('WordPress Stats') + 268 | ' (Jetpack) has been found.'); 269 | } 270 | 271 | this.remove('analytics'); 272 | } 273 | } 274 | 275 | getPrefetchingInformation() { 276 | if (this.hasTask('prefetching')) { 277 | const dns = this.hp.checkPrefetching(); 278 | 279 | this.ui.headline('DNS Prefetching'); 280 | 281 | if (dns.length === 0) { 282 | this.ui.info( 283 | chalk.yellow(this.data.html.url.hostname) + 284 | ' supports no DNS prefetching.') 285 | } else { 286 | this.ui.info( 287 | chalk.yellow(this.data.html.url.hostname) + ' has ' + 288 | chalk.red(dns.length) + ' DNS prefetching elements.\n'); 289 | this.ui.settable({ 290 | cells: 3, 291 | widths: [5, 30, 0] 292 | }); 293 | 294 | dns.forEach((url, i) => { 295 | let u = (url.startsWith('//')) ? url.replace('//', '') : url; 296 | let explanation = ''; 297 | 298 | if (u.indexOf('fonts.googleapis.com') >= 0) explanation = 'Google Fonts'; 299 | if (u.indexOf('gravatar.com') >= 0) explanation = 'Automattic Gravatar Service'; 300 | if (u.indexOf('s.w.org') >= 0) explanation = 'WordPress Emojis CDN'; 301 | if (u.match(/s[0-9]\.wp\.com/)) explanation = 'WordPress Styles CDN'; 302 | if (u.match(/i[0-9]\.wp\.com/)) explanation = 'WordPress Images CDN'; 303 | if (u.match(/v[0-9]\.wordpress\.com/)) explanation = 'WordPress Videos CDN'; 304 | if (u.indexOf('maxcdn.bootstrapcdn.com') >= 0) explanation = 'Bootstrap CDN'; 305 | if (u.indexOf('checkout.stripe.com') >= 0) explanation = 'Stripe Online Payments'; 306 | if (u.indexOf('code.jquery.com') >= 0) explanation = 'jQuery CDN'; 307 | if (u.indexOf('translate.google.com') >= 0) explanation = 'Google Translate'; 308 | if (u.indexOf('use.typekit.net') >= 0) explanation = 'Adobe Typekit Web Fonts'; 309 | if (u.indexOf('use.fontawesome.com') >= 0) explanation = 'Font Awesome CDN'; 310 | 311 | this.ui.tableitem( 312 | [chalk.yellow(String(i + 1) + '.'), u, chalk.dim(explanation)]) 313 | }); 314 | } 315 | 316 | this.remove('prefetching'); 317 | } 318 | } 319 | 320 | getFontInformation() { 321 | if (this.hasTask('fonts')) { 322 | const default_types = [{ 323 | type: 'google', 324 | decription: 'Google Fonts' 325 | }, 326 | { 327 | type: 'typekit', 328 | decription: 'Adobe Typekit Fonts' 329 | }, 330 | { 331 | type: 'wordpress', 332 | decription: 'Fonts from wordpress.com' 333 | }, 334 | { 335 | type: 'local', 336 | decription: 'Fonts directly from the site' 337 | } 338 | ]; 339 | this.data.fonts = {}; 340 | const FontsParser = require('./modules/fonts'); 341 | const Fonts = new FontsParser(this.data.css, this.data.js, this.data.html.url); 342 | this.data.fonts = Fonts.getFonts(); 343 | //console.log(this.data.fonts); 344 | 345 | let todo = []; 346 | default_types.forEach(el => { 347 | if (typeof this.data.fonts[el.type] !== 'undefined') todo.push(el); 348 | }); 349 | 350 | this.ui.headline('Fonts Implementation'); 351 | this.ui.settable({ 352 | cells: 3, 353 | widths: [5, 30, 0] 354 | }); 355 | 356 | if (todo.length !== 0) { 357 | todo.forEach((el, i) => { 358 | let count = Fonts.countFonts(this.data.fonts[el.type]); 359 | if (i > 0) console.log(''); 360 | this.ui.info(el.decription + ': ' + chalk.red(count.length) + '\n'); 361 | count.forEach((f, j) => { 362 | this.ui.tableitem([chalk.yellow(String(j + 1) + '.'), f, chalk.dim(Fonts.getFontStyles(this.data.fonts[el.type], f))]); 363 | }); 364 | }); 365 | } else this.ui.info('There were no Fonts found.'); 366 | 367 | this.remove('fonts'); 368 | } 369 | } 370 | 371 | /** 372 | * Gathers SSL Information 373 | * @class Tasks 374 | */ 375 | getSSLInformation() { 376 | if (this.hasTask('ssl')) { 377 | if (Object.keys(this.data.ssl).length === 0 && 378 | this.data.ssl.constructor === Object) { 379 | this.ui.headline('SSL Certificate'); 380 | this.ui.error('There is no SSL/TLS available.', false); 381 | this.remove('ssl'); 382 | return; 383 | } else { 384 | this.ui.headline('SSL Certificate'); 385 | 386 | this.ui.listitem('Common Name', this.data.ssl.common_name); 387 | this.ui.listitem('Country', this.data.ssl.country); 388 | this.ui.listitem('Organization', this.data.ssl.organization); 389 | this.ui.listitem('Organization CN', this.data.ssl.org_cn + '\n'); 390 | 391 | this.ui.listitem('Valid from', this.data.ssl.valid_from); 392 | this.ui.listitem('Valid to', this.data.ssl.valid_to); 393 | this.ui.listitem('Serial Number', this.data.ssl.serial_nr); 394 | this.ui.listitem('FP SHA-1', this.data.ssl.fingerprint); 395 | this.ui.listitem('FP SHA-256', this.data.ssl.fingerprint256); 396 | //this.ui.message('SSL FINISHED'); 397 | this.remove('ssl'); 398 | } 399 | } 400 | } 401 | 402 | 403 | /** 404 | * Gathes General Information (meta data) of the Website 405 | * @class Tasks 406 | */ 407 | getGeneralInformation() { 408 | 409 | if (this.hasTask('general')) { 410 | const info = require('./modules/info'); 411 | this.data.general = info.getInfo(this.data); 412 | //console.log(this.data.general); 413 | 414 | this.ui.headline('General Information'); 415 | 416 | this.ui.listitem('Title', this.data.general.title); 417 | if (this.data.general.description !== '') this.ui.listitem('Description', this.data.general.description); 418 | this.ui.listitem('URL', this.data.general.url); 419 | this.ui.listitem('Software', (this.data.general.generators.length > 0) ? this.data.general.generators.join(', ') : 'Unknown'); 420 | 421 | if (info.isWordPress(this.data.general)) { 422 | if (typeof this.data.general.theme !== 'undefined' && this.data.general.theme !== '') this.ui.listitem('Theme', this.data.general.theme); 423 | if (typeof this.data.general.plugins !== 'undefined' && this.data.general.plugins.length > 0) this.ui.listitem('Plugins', this.data.general.plugins.join(', ')); 424 | } 425 | 426 | this.remove('general'); 427 | } 428 | 429 | } 430 | 431 | /** 432 | * Finds CSS and JS references in the HTML file 433 | * @class Tasks 434 | */ 435 | setupAdditionalContent() { 436 | if (this.hasTask('html')) { 437 | if (this.tasks.indexOf('css') !== -1 || this.tasks.indexOf('js') !== -1) { 438 | this.ui.message({ 439 | normal: 'Setup additional content', 440 | verbose: 'Setup additional content' 441 | }); 442 | } 443 | if (this.hasTask('css')) { 444 | this.ui.message({ 445 | verbose: chalk.dim('-> CSS files') 446 | }, '', false); 447 | this.data.css = this.hp.getStylesheetURLs(this.data.html.url.href); 448 | // console.log(this.data.css); 449 | } 450 | if (this.hasTask('js')) { 451 | this.ui.message({ 452 | verbose: chalk.dim('-> JavaScript files') 453 | }, '', false); 454 | this.data.js = this.hp.getJavascriptURLs(this.data.html.url.href); 455 | // console.log(this.data.js); 456 | } 457 | if (this.hasTask('img')) { 458 | this.ui.message({ 459 | verbose: chalk.dim('-> Image files') 460 | }, '', false); 461 | this.data.img = this.hp.getImageURLs(this.data.html.url.href); 462 | /* this.data.img.forEach(el => { 463 | console.log(el.url.host); 464 | }); 465 | console.log(this.data.img.length); 466 | console.log(this.hp.getiFrames()); 467 | this.data.js.forEach(el => { 468 | console.log(el.url.href); 469 | }) */ 470 | //console.log(this.data.html.content); 471 | } 472 | // this.ui.message('ADDITIONAL CONTENT FINISHED'); 473 | this.remove('html'); 474 | return Promise.resolve(this.urls); 475 | } else 476 | return Promise.resolve(100); // Status 100 CONTINUE 477 | } 478 | 479 | 480 | // INFO: PROCESSING 481 | 482 | 483 | /** 484 | * Gets the SSL Certificate 485 | * @class Tasks 486 | */ 487 | processSSL() { 488 | if (this.hasTask('ssl')) { 489 | this.ui.message({ 490 | normal: 'Loading SSL Certificate', 491 | verbose: 'Loading SSL Certificate' 492 | }); 493 | return new Promise((resolve, reject) => { 494 | if (this.data.html.url.protocol !== 'https:') { 495 | this.ui.error('Can\'t establish SSL/TLS connection!'); 496 | resolve(); 497 | } else { 498 | sslCert.get(this.data.html.url.hostname) 499 | .then(cert => { 500 | this.data.ssl.common_name = cert.subject.CN; 501 | this.data.ssl.country = cert.issuer.C; 502 | this.data.ssl.organization = cert.issuer.O; 503 | this.data.ssl.org_cn = cert.issuer.CN; 504 | this.data.ssl.valid_from = cert.valid_from; 505 | this.data.ssl.valid_to = cert.valid_to; 506 | this.data.ssl.serial_nr = cert.serialNumber; 507 | this.data.ssl.fingerprint = cert.fingerprint; 508 | this.data.ssl.fingerprint256 = cert.fingerprint256; 509 | 510 | // this.ui.message('SSL FINISHED'); 511 | resolve(cert); 512 | }) 513 | .catch(e => reject(e)); 514 | } 515 | }); 516 | } else 517 | return Promise.resolve(100); // Status 100 CONTINUE 518 | } 519 | 520 | 521 | /** 522 | * Gets any external JS content 523 | * @class Tasks 524 | */ 525 | processJS() { 526 | if (this.hasTask('js')) { 527 | this.ui.message({ 528 | normal: 'Loading JS files', 529 | verbose: 'Loading JS files' 530 | }); 531 | return this.processMultipleItems(this.data.js, this.loadExternalItem) 532 | .then(res => { 533 | this.data.js = (res !== 404) ? res : []; 534 | this.ui.message({ 535 | verbose: chalk.dim('-> Looking for Inline JavaScript') 536 | }, { 537 | code: 200, 538 | msg: 'OK' 539 | }, false); 540 | this.data.js.inline = this.hp.getInlineJS(); 541 | // this.ui.message('JS FINISHED'); 542 | this.remove('js'); 543 | return res; 544 | }); 545 | } else 546 | return Promise.resolve(100); // Status 100 CONTINUE 547 | } 548 | 549 | 550 | /** 551 | * Gets any external CSS content 552 | * @class Tasks 553 | */ 554 | processCSS() { 555 | if (this.hasTask('css')) { 556 | this.ui.message({ 557 | normal: 'Loading CSS files', 558 | verbose: 'Loading CSS files' 559 | }); 560 | return this.processMultipleItems(this.data.css, this.loadExternalItem) 561 | .then(res => { 562 | this.data.css = (res !== 404) ? res : []; 563 | this.ui.message({ 564 | verbose: chalk.dim('-> Looking for Inline CSS') 565 | }, { 566 | code: 200, 567 | msg: 'OK' 568 | }, false); 569 | this.data.css.inline = this.hp.getInlineCSS(); 570 | // this.ui.message('CSS FINISHED'); 571 | this.remove('css'); 572 | return res; 573 | }); 574 | } else 575 | return Promise.resolve(100); // Status 100 CONTINUE 576 | } 577 | 578 | 579 | /** 580 | * Gets the main HTML file 581 | * @class Tasks 582 | */ 583 | processHTML() { 584 | if (this.hasTask('html')) { 585 | this.ui.message({ 586 | normal: 'Loading HTML file', 587 | verbose: 'Loading ' + chalk.yellow(this.data.html.url.href) 588 | }); 589 | return this.loadExternalItem(this.data.html).then(res => { 590 | this.data.html = res; 591 | // console.log(this.data.html); 592 | this.hp = new HTMLParser(this.data.html.content); 593 | // this.ui.message('HTML FINISHED'); 594 | 595 | return this.setupAdditionalContent(); 596 | }); 597 | } else 598 | return Promise.resolve(100); // Status 100 CONTINUE 599 | } 600 | 601 | 602 | // INFO: HELPERS 603 | 604 | 605 | /** 606 | * Iterator function to synchronize Promises 607 | * @param {Array} array 608 | * @param {Function} fn 609 | */ 610 | processMultipleItems(array, fn) { 611 | const self = this; 612 | var results = []; 613 | if (array.length !== 0) { 614 | return array.reduce((p, item) => { 615 | return p.then(() => { 616 | return fn(item).then((data) => { 617 | self.ui.message({ 618 | verbose: chalk.dim('-> ' + item.url) 619 | }, { 620 | code: data.statusCode, 621 | msg: data.statusMessage 622 | }, false); 623 | results.push(data); 624 | return results; 625 | }); 626 | }); 627 | }, Promise.resolve()); 628 | } else 629 | return Promise.resolve(404); 630 | } 631 | 632 | 633 | /** 634 | * Loads an external (CSS or JS) file 635 | * @param {URL} item 636 | */ 637 | loadExternalItem(item) { 638 | return new Promise(resolve => { 639 | const Obj = {}; 640 | Obj.url = item.url; 641 | got(item.url).then( 642 | res => { 643 | Obj.headers = res.headers; 644 | Obj.content = res.body; 645 | Obj.statusCode = res.statusCode; 646 | Obj.statusMessage = res.statusMessage; 647 | resolve(Obj); 648 | }, 649 | reason => { 650 | Obj.statusCode = reason.statusCode; 651 | Obj.statusMessage = reason.statusMessage; 652 | resolve(Obj); 653 | }); 654 | }); 655 | } 656 | 657 | 658 | /** 659 | * Checks if the URL is valid and upgrades the protocol if needed 660 | * @class Tasks 661 | */ 662 | normalizeURL() { 663 | let url = this.url; 664 | 665 | this.ui.message({ 666 | normal: 'Checking the URL ...', 667 | verbose: 'Checking the URL ' + chalk.yellow(url) 668 | }); 669 | 670 | url = url.replace(/(https?:)?\/\//, ''); // delete the protocol 671 | url = (url.startsWith('/')) ? url.substr(1) : 672 | url; // get rid of trailing slash 673 | url = (url.endsWith('/')) ? url : 674 | url + '/'; // ensure that it ends with a slash 675 | // upgrade protocol if needed 676 | return got('http://' + url, this.default_headers).then(res => { 677 | url = (url != res.url) ? res.url : url; 678 | this.data.html = { 679 | url: new URL(url) 680 | }; 681 | if (this.url !== this.data.html.url.href) { 682 | this.ui.message({ 683 | verbose: 'URL ' + chalk.yellow(this.url) + ' was adjusted to ' + 684 | chalk.yellow(this.data.html.url.href) + '.' 685 | }); 686 | } 687 | this.remove('normalize'); 688 | Promise.resolve(200); 689 | }); 690 | } 691 | } 692 | 693 | module.exports = Tasks; -------------------------------------------------------------------------------- /lib/ui.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const chalk = require('chalk'); 4 | const moment = require('moment'); 5 | const cui = require('cliui')(); 6 | 7 | class UI { 8 | 9 | constructor() { 10 | this.mode = 'normal'; 11 | this.tableOptions = {}; 12 | } 13 | 14 | /** 15 | * Sets the Mode (mute|normal|verbose) 16 | * @param {string} mode 17 | */ 18 | set(mode) { 19 | this.mode = (typeof mode !== 'undefined' && ['mute', 'normal', 'verbose'].indexOf(mode) !== -1) ? mode : 'normal'; 20 | } 21 | 22 | headline(str) { 23 | console.log('\n' + chalk.green(str.toUpperCase()) + '\n'); 24 | } 25 | 26 | listitem(term, definition) { 27 | cui.div({ 28 | text: chalk.yellow(term + ':'), 29 | width: 20, 30 | padding: [0, 2, 0, 0] 31 | }, { 32 | text: definition, 33 | padding: [0, 2, 0, 0] 34 | }); 35 | console.log(cui.toString()); 36 | cui.resetOutput() 37 | } 38 | 39 | settable(options) { 40 | const opt = { 41 | cells: options.cells || 0, 42 | widths: options.widths || [], 43 | padding: options.padding || [0, 2, 0, 0] 44 | } 45 | this.tableOptions = opt; 46 | } 47 | 48 | tableitem(row) { 49 | if (row.length !== this.tableOptions.cells) return; 50 | let data = []; 51 | row.forEach((entry, i) => { 52 | data.push({ 53 | text: entry, 54 | width: this.tableOptions.widths[i], 55 | padding: this.tableOptions.padding 56 | }); 57 | }); 58 | //console.log(data); 59 | cui.div(...data); 60 | console.log(cui.toString()); 61 | cui.resetOutput(); 62 | } 63 | 64 | message(msg, state, showTime) { 65 | 66 | // Check if UI Mode exists and the message has the right format 67 | if (typeof msg !== 'string' && typeof msg !== 'object') return; 68 | if (typeof msg === 'object' && typeof msg[this.mode] === 'undefined') return; 69 | 70 | // Check if msg is a string and turn it into an object 71 | if (typeof msg === 'string') msg = { 72 | mute: msg, 73 | normal: msg, 74 | verbose: msg 75 | }; 76 | // fill in the blanks 77 | ['mute', 'normal', 'verbose'].forEach(mode => { 78 | if (typeof msg[mode] === 'undefined') msg[mode] = ''; 79 | }); 80 | 81 | let _state = ''; 82 | if (state && typeof state === 'object') { 83 | _state = (state.code === 200) ? chalk.green('[' + state.msg + ']') : chalk.red('[' + state.msg + ']'); 84 | } else if (state && typeof state === 'string') { 85 | _state = (state !== '') ? chalk.dim('[' + state.toUpperCase() + ']') : ''; 86 | } 87 | const _time = (typeof showTime !== 'undefined' && showTime === false) ? ' ' : chalk.dim('[' + moment().format('HH:mm:ss') + ']'); 88 | const _message = msg[this.mode]; 89 | 90 | console.log(_time + ' ' + _message + ' ' + _state); 91 | } 92 | 93 | info(msg) { 94 | console.log(msg); 95 | } 96 | 97 | error(msg, showTime) { 98 | 99 | const _message = chalk.red(msg); 100 | const _time = (typeof showTime !== 'undefined' && showTime === false) ? '' : chalk.dim('[' + moment().format('HH:mm:ss') + '] '); 101 | console.log(_time + _message); 102 | } 103 | } 104 | 105 | module.exports = UI; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gdpr-cli", 3 | "version": "0.3.4", 4 | "description": "Checks websites for GDPR compliance", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "ava test/*.js", 8 | "test:verbose": "ava test/*.js --verbose", 9 | "test:watch": "ava test/*.js --verbose --watch" 10 | }, 11 | "bin": { 12 | "gdpr": "index.js" 13 | }, 14 | "repository": "https://github.com/mirkoschubert/gdpr-check.git", 15 | "author": "Mirko Schubert ", 16 | "license": "MIT", 17 | "dependencies": { 18 | "chalk": "^2.4.1", 19 | "cheerio": "^1.0.0-rc.2", 20 | "cliui": "^4.1.0", 21 | "commander": "^2.15.1", 22 | "css": "^2.2.3", 23 | "fs-extra": "^6.0.1", 24 | "get-ssl-certificate": "^2.1.2", 25 | "got": "^8.3.1", 26 | "moment": "^2.22.1", 27 | "rootpath": "^0.1.2" 28 | }, 29 | "devDependencies": { 30 | "ava": "^0.25.0" 31 | } 32 | } -------------------------------------------------------------------------------- /test/html.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const test = require('ava'); 4 | const chalk = require('chalk'); 5 | const Tasks = require('../lib/tasks'); 6 | 7 | console.log = function () {} // suppress all logs 8 | 9 | const sites = { 10 | 'small static site': 'mirkoschubert.de', 11 | 'wordpress site': 'freesendeern.de' 12 | } 13 | 14 | for (let site in sites) { 15 | const tasks = new Tasks(sites[site]); 16 | tasks.new('html'); 17 | tasks.new('css'); 18 | tasks.new('js'); 19 | tasks.prepareTasks(); 20 | 21 | test(chalk.yellow('get HTML code') + ' off of a ' + site, t => { 22 | return tasks.normalizeURL().then(() => tasks.processHTML()).then(res => { 23 | t.not(typeof tasks.data.html.headers, 'undefined'); 24 | t.not(typeof tasks.data.html.content, 'undefined'); 25 | t.not(tasks.data.html.content, ''); 26 | }); 27 | }); 28 | 29 | test(chalk.yellow('parse CSS and JS files') + ' of a ' + site, t => { 30 | return tasks.normalizeURL().then(() => tasks.processHTML()).then(res => { 31 | t.not(typeof tasks.data.html.content, 'undefined'); 32 | t.not(typeof tasks.data.css, 'undefined'); 33 | }); 34 | }); 35 | 36 | } -------------------------------------------------------------------------------- /test/normalize.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const test = require('ava'); 4 | const chalk = require('chalk'); 5 | const Tasks = require('../lib/tasks'); 6 | 7 | console.log = function () {} // suppress all logs 8 | 9 | const sites = { 10 | 'url with the wrong protocol': { 11 | url: 'http://mirkoschubert.de', 12 | expected: 'https://mirkoschubert.de/' 13 | }, 14 | 'url with the right protocol': { 15 | url: 'https://mirkoschubert.de', 16 | expected: 'https://mirkoschubert.de/' 17 | }, 18 | 'url without any specific protocol': { 19 | url: '//mirkoschubert.de', 20 | expected: 'https://mirkoschubert.de/' 21 | }, 22 | 'url without any protocol': { 23 | url: 'mirkoschubert.de', 24 | expected: 'https://mirkoschubert.de/' 25 | }, 26 | /* 'non existant url': { 27 | url: 'http://aslkfjhans.com', 28 | expected: '' 29 | }, 30 | 'google.de (known issue)': { 31 | url: 'https://google.de', 32 | expected: 'https://www.google.de/' 33 | } */ 34 | }; 35 | 36 | 37 | for (let site in sites) { 38 | 39 | test(chalk.yellow('normalize ') + site, t => { 40 | const tasks = new Tasks(sites[site].url); 41 | 42 | t.is(tasks.tasks[0], 'normalize'); 43 | return tasks.normalizeURL().then(() => { 44 | t.is(tasks.data.html.url.href, sites[site].expected); 45 | }); 46 | }); 47 | } -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@ava/babel-plugin-throws-helper@^2.0.0": 6 | version "2.0.0" 7 | resolved "https://registry.yarnpkg.com/@ava/babel-plugin-throws-helper/-/babel-plugin-throws-helper-2.0.0.tgz#2fc1fe3c211a71071a4eca7b8f7af5842cd1ae7c" 8 | 9 | "@ava/babel-preset-stage-4@^1.1.0": 10 | version "1.1.0" 11 | resolved "https://registry.yarnpkg.com/@ava/babel-preset-stage-4/-/babel-preset-stage-4-1.1.0.tgz#ae60be881a0babf7d35f52aba770d1f6194f76bd" 12 | dependencies: 13 | babel-plugin-check-es2015-constants "^6.8.0" 14 | babel-plugin-syntax-trailing-function-commas "^6.20.0" 15 | babel-plugin-transform-async-to-generator "^6.16.0" 16 | babel-plugin-transform-es2015-destructuring "^6.19.0" 17 | babel-plugin-transform-es2015-function-name "^6.9.0" 18 | babel-plugin-transform-es2015-modules-commonjs "^6.18.0" 19 | babel-plugin-transform-es2015-parameters "^6.21.0" 20 | babel-plugin-transform-es2015-spread "^6.8.0" 21 | babel-plugin-transform-es2015-sticky-regex "^6.8.0" 22 | babel-plugin-transform-es2015-unicode-regex "^6.11.0" 23 | babel-plugin-transform-exponentiation-operator "^6.8.0" 24 | package-hash "^1.2.0" 25 | 26 | "@ava/babel-preset-transform-test-files@^3.0.0": 27 | version "3.0.0" 28 | resolved "https://registry.yarnpkg.com/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-3.0.0.tgz#cded1196a8d8d9381a509240ab92e91a5ec069f7" 29 | dependencies: 30 | "@ava/babel-plugin-throws-helper" "^2.0.0" 31 | babel-plugin-espower "^2.3.2" 32 | 33 | "@ava/write-file-atomic@^2.2.0": 34 | version "2.2.0" 35 | resolved "https://registry.yarnpkg.com/@ava/write-file-atomic/-/write-file-atomic-2.2.0.tgz#d625046f3495f1f5e372135f473909684b429247" 36 | dependencies: 37 | graceful-fs "^4.1.11" 38 | imurmurhash "^0.1.4" 39 | slide "^1.1.5" 40 | 41 | "@concordance/react@^1.0.0": 42 | version "1.0.0" 43 | resolved "https://registry.yarnpkg.com/@concordance/react/-/react-1.0.0.tgz#fcf3cad020e5121bfd1c61d05bc3516aac25f734" 44 | dependencies: 45 | arrify "^1.0.1" 46 | 47 | "@ladjs/time-require@^0.1.4": 48 | version "0.1.4" 49 | resolved "https://registry.yarnpkg.com/@ladjs/time-require/-/time-require-0.1.4.tgz#5c615d75fd647ddd5de9cf6922649558856b21a1" 50 | dependencies: 51 | chalk "^0.4.0" 52 | date-time "^0.1.1" 53 | pretty-ms "^0.2.1" 54 | text-table "^0.2.0" 55 | 56 | "@sindresorhus/is@^0.7.0": 57 | version "0.7.0" 58 | resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" 59 | 60 | "@types/node@*": 61 | version "10.1.4" 62 | resolved "https://registry.yarnpkg.com/@types/node/-/node-10.1.4.tgz#606651d3f8a8bec08b8cb262161aab9209f4a29d" 63 | 64 | abbrev@1: 65 | version "1.1.1" 66 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 67 | 68 | amdefine@>=0.0.4: 69 | version "1.0.1" 70 | resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" 71 | 72 | ansi-align@^2.0.0: 73 | version "2.0.0" 74 | resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" 75 | dependencies: 76 | string-width "^2.0.0" 77 | 78 | ansi-escapes@^3.0.0: 79 | version "3.1.0" 80 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" 81 | 82 | ansi-regex@^2.0.0: 83 | version "2.1.1" 84 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 85 | 86 | ansi-regex@^3.0.0: 87 | version "3.0.0" 88 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" 89 | 90 | ansi-styles@^2.2.1: 91 | version "2.2.1" 92 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 93 | 94 | ansi-styles@^3.1.0, ansi-styles@^3.2.1: 95 | version "3.2.1" 96 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 97 | dependencies: 98 | color-convert "^1.9.0" 99 | 100 | ansi-styles@~1.0.0: 101 | version "1.0.0" 102 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" 103 | 104 | anymatch@^1.3.0: 105 | version "1.3.2" 106 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" 107 | dependencies: 108 | micromatch "^2.1.5" 109 | normalize-path "^2.0.0" 110 | 111 | aproba@^1.0.3: 112 | version "1.2.0" 113 | resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" 114 | 115 | are-we-there-yet@~1.1.2: 116 | version "1.1.5" 117 | resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" 118 | dependencies: 119 | delegates "^1.0.0" 120 | readable-stream "^2.0.6" 121 | 122 | argparse@^1.0.7: 123 | version "1.0.10" 124 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 125 | dependencies: 126 | sprintf-js "~1.0.2" 127 | 128 | arr-diff@^2.0.0: 129 | version "2.0.0" 130 | resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" 131 | dependencies: 132 | arr-flatten "^1.0.1" 133 | 134 | arr-exclude@^1.0.0: 135 | version "1.0.0" 136 | resolved "https://registry.yarnpkg.com/arr-exclude/-/arr-exclude-1.0.0.tgz#dfc7c2e552a270723ccda04cf3128c8cbfe5c631" 137 | 138 | arr-flatten@^1.0.1: 139 | version "1.1.0" 140 | resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" 141 | 142 | array-differ@^1.0.0: 143 | version "1.0.0" 144 | resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" 145 | 146 | array-find-index@^1.0.1: 147 | version "1.0.2" 148 | resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" 149 | 150 | array-union@^1.0.1: 151 | version "1.0.2" 152 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" 153 | dependencies: 154 | array-uniq "^1.0.1" 155 | 156 | array-uniq@^1.0.1, array-uniq@^1.0.2: 157 | version "1.0.3" 158 | resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" 159 | 160 | array-unique@^0.2.1: 161 | version "0.2.1" 162 | resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" 163 | 164 | arrify@^1.0.0, arrify@^1.0.1: 165 | version "1.0.1" 166 | resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" 167 | 168 | async-each@^1.0.0: 169 | version "1.0.1" 170 | resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" 171 | 172 | atob@^2.1.1: 173 | version "2.1.1" 174 | resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a" 175 | 176 | auto-bind@^1.1.0: 177 | version "1.2.0" 178 | resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-1.2.0.tgz#8b7e318aad53d43ba8a8ecaf0066d85d5f798cd6" 179 | 180 | ava-init@^0.2.0: 181 | version "0.2.1" 182 | resolved "https://registry.yarnpkg.com/ava-init/-/ava-init-0.2.1.tgz#75ac4c8553326290d2866e63b62fa7035684bd58" 183 | dependencies: 184 | arr-exclude "^1.0.0" 185 | execa "^0.7.0" 186 | has-yarn "^1.0.0" 187 | read-pkg-up "^2.0.0" 188 | write-pkg "^3.1.0" 189 | 190 | ava@^0.25.0: 191 | version "0.25.0" 192 | resolved "https://registry.yarnpkg.com/ava/-/ava-0.25.0.tgz#8ac87780514f96a6fd42e1306eaa0752ce3a407f" 193 | dependencies: 194 | "@ava/babel-preset-stage-4" "^1.1.0" 195 | "@ava/babel-preset-transform-test-files" "^3.0.0" 196 | "@ava/write-file-atomic" "^2.2.0" 197 | "@concordance/react" "^1.0.0" 198 | "@ladjs/time-require" "^0.1.4" 199 | ansi-escapes "^3.0.0" 200 | ansi-styles "^3.1.0" 201 | arr-flatten "^1.0.1" 202 | array-union "^1.0.1" 203 | array-uniq "^1.0.2" 204 | arrify "^1.0.0" 205 | auto-bind "^1.1.0" 206 | ava-init "^0.2.0" 207 | babel-core "^6.17.0" 208 | babel-generator "^6.26.0" 209 | babel-plugin-syntax-object-rest-spread "^6.13.0" 210 | bluebird "^3.0.0" 211 | caching-transform "^1.0.0" 212 | chalk "^2.0.1" 213 | chokidar "^1.4.2" 214 | clean-stack "^1.1.1" 215 | clean-yaml-object "^0.1.0" 216 | cli-cursor "^2.1.0" 217 | cli-spinners "^1.0.0" 218 | cli-truncate "^1.0.0" 219 | co-with-promise "^4.6.0" 220 | code-excerpt "^2.1.1" 221 | common-path-prefix "^1.0.0" 222 | concordance "^3.0.0" 223 | convert-source-map "^1.5.1" 224 | core-assert "^0.2.0" 225 | currently-unhandled "^0.4.1" 226 | debug "^3.0.1" 227 | dot-prop "^4.1.0" 228 | empower-core "^0.6.1" 229 | equal-length "^1.0.0" 230 | figures "^2.0.0" 231 | find-cache-dir "^1.0.0" 232 | fn-name "^2.0.0" 233 | get-port "^3.0.0" 234 | globby "^6.0.0" 235 | has-flag "^2.0.0" 236 | hullabaloo-config-manager "^1.1.0" 237 | ignore-by-default "^1.0.0" 238 | import-local "^0.1.1" 239 | indent-string "^3.0.0" 240 | is-ci "^1.0.7" 241 | is-generator-fn "^1.0.0" 242 | is-obj "^1.0.0" 243 | is-observable "^1.0.0" 244 | is-promise "^2.1.0" 245 | last-line-stream "^1.0.0" 246 | lodash.clonedeepwith "^4.5.0" 247 | lodash.debounce "^4.0.3" 248 | lodash.difference "^4.3.0" 249 | lodash.flatten "^4.2.0" 250 | loud-rejection "^1.2.0" 251 | make-dir "^1.0.0" 252 | matcher "^1.0.0" 253 | md5-hex "^2.0.0" 254 | meow "^3.7.0" 255 | ms "^2.0.0" 256 | multimatch "^2.1.0" 257 | observable-to-promise "^0.5.0" 258 | option-chain "^1.0.0" 259 | package-hash "^2.0.0" 260 | pkg-conf "^2.0.0" 261 | plur "^2.0.0" 262 | pretty-ms "^3.0.0" 263 | require-precompiled "^0.1.0" 264 | resolve-cwd "^2.0.0" 265 | safe-buffer "^5.1.1" 266 | semver "^5.4.1" 267 | slash "^1.0.0" 268 | source-map-support "^0.5.0" 269 | stack-utils "^1.0.1" 270 | strip-ansi "^4.0.0" 271 | strip-bom-buf "^1.0.0" 272 | supertap "^1.0.0" 273 | supports-color "^5.0.0" 274 | trim-off-newlines "^1.0.1" 275 | unique-temp-dir "^1.0.0" 276 | update-notifier "^2.3.0" 277 | 278 | babel-code-frame@^6.26.0: 279 | version "6.26.0" 280 | resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" 281 | dependencies: 282 | chalk "^1.1.3" 283 | esutils "^2.0.2" 284 | js-tokens "^3.0.2" 285 | 286 | babel-core@^6.17.0, babel-core@^6.26.0: 287 | version "6.26.3" 288 | resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" 289 | dependencies: 290 | babel-code-frame "^6.26.0" 291 | babel-generator "^6.26.0" 292 | babel-helpers "^6.24.1" 293 | babel-messages "^6.23.0" 294 | babel-register "^6.26.0" 295 | babel-runtime "^6.26.0" 296 | babel-template "^6.26.0" 297 | babel-traverse "^6.26.0" 298 | babel-types "^6.26.0" 299 | babylon "^6.18.0" 300 | convert-source-map "^1.5.1" 301 | debug "^2.6.9" 302 | json5 "^0.5.1" 303 | lodash "^4.17.4" 304 | minimatch "^3.0.4" 305 | path-is-absolute "^1.0.1" 306 | private "^0.1.8" 307 | slash "^1.0.0" 308 | source-map "^0.5.7" 309 | 310 | babel-generator@^6.1.0, babel-generator@^6.26.0: 311 | version "6.26.1" 312 | resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" 313 | dependencies: 314 | babel-messages "^6.23.0" 315 | babel-runtime "^6.26.0" 316 | babel-types "^6.26.0" 317 | detect-indent "^4.0.0" 318 | jsesc "^1.3.0" 319 | lodash "^4.17.4" 320 | source-map "^0.5.7" 321 | trim-right "^1.0.1" 322 | 323 | babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: 324 | version "6.24.1" 325 | resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" 326 | dependencies: 327 | babel-helper-explode-assignable-expression "^6.24.1" 328 | babel-runtime "^6.22.0" 329 | babel-types "^6.24.1" 330 | 331 | babel-helper-call-delegate@^6.24.1: 332 | version "6.24.1" 333 | resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" 334 | dependencies: 335 | babel-helper-hoist-variables "^6.24.1" 336 | babel-runtime "^6.22.0" 337 | babel-traverse "^6.24.1" 338 | babel-types "^6.24.1" 339 | 340 | babel-helper-explode-assignable-expression@^6.24.1: 341 | version "6.24.1" 342 | resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" 343 | dependencies: 344 | babel-runtime "^6.22.0" 345 | babel-traverse "^6.24.1" 346 | babel-types "^6.24.1" 347 | 348 | babel-helper-function-name@^6.24.1: 349 | version "6.24.1" 350 | resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" 351 | dependencies: 352 | babel-helper-get-function-arity "^6.24.1" 353 | babel-runtime "^6.22.0" 354 | babel-template "^6.24.1" 355 | babel-traverse "^6.24.1" 356 | babel-types "^6.24.1" 357 | 358 | babel-helper-get-function-arity@^6.24.1: 359 | version "6.24.1" 360 | resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" 361 | dependencies: 362 | babel-runtime "^6.22.0" 363 | babel-types "^6.24.1" 364 | 365 | babel-helper-hoist-variables@^6.24.1: 366 | version "6.24.1" 367 | resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" 368 | dependencies: 369 | babel-runtime "^6.22.0" 370 | babel-types "^6.24.1" 371 | 372 | babel-helper-regex@^6.24.1: 373 | version "6.26.0" 374 | resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" 375 | dependencies: 376 | babel-runtime "^6.26.0" 377 | babel-types "^6.26.0" 378 | lodash "^4.17.4" 379 | 380 | babel-helper-remap-async-to-generator@^6.24.1: 381 | version "6.24.1" 382 | resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" 383 | dependencies: 384 | babel-helper-function-name "^6.24.1" 385 | babel-runtime "^6.22.0" 386 | babel-template "^6.24.1" 387 | babel-traverse "^6.24.1" 388 | babel-types "^6.24.1" 389 | 390 | babel-helpers@^6.24.1: 391 | version "6.24.1" 392 | resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" 393 | dependencies: 394 | babel-runtime "^6.22.0" 395 | babel-template "^6.24.1" 396 | 397 | babel-messages@^6.23.0: 398 | version "6.23.0" 399 | resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" 400 | dependencies: 401 | babel-runtime "^6.22.0" 402 | 403 | babel-plugin-check-es2015-constants@^6.8.0: 404 | version "6.22.0" 405 | resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" 406 | dependencies: 407 | babel-runtime "^6.22.0" 408 | 409 | babel-plugin-espower@^2.3.2: 410 | version "2.4.0" 411 | resolved "https://registry.yarnpkg.com/babel-plugin-espower/-/babel-plugin-espower-2.4.0.tgz#9f92c080e9adfe73f69baed7ab3e24f649009373" 412 | dependencies: 413 | babel-generator "^6.1.0" 414 | babylon "^6.1.0" 415 | call-matcher "^1.0.0" 416 | core-js "^2.0.0" 417 | espower-location-detector "^1.0.0" 418 | espurify "^1.6.0" 419 | estraverse "^4.1.1" 420 | 421 | babel-plugin-syntax-async-functions@^6.8.0: 422 | version "6.13.0" 423 | resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" 424 | 425 | babel-plugin-syntax-exponentiation-operator@^6.8.0: 426 | version "6.13.0" 427 | resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" 428 | 429 | babel-plugin-syntax-object-rest-spread@^6.13.0: 430 | version "6.13.0" 431 | resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" 432 | 433 | babel-plugin-syntax-trailing-function-commas@^6.20.0: 434 | version "6.22.0" 435 | resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" 436 | 437 | babel-plugin-transform-async-to-generator@^6.16.0: 438 | version "6.24.1" 439 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" 440 | dependencies: 441 | babel-helper-remap-async-to-generator "^6.24.1" 442 | babel-plugin-syntax-async-functions "^6.8.0" 443 | babel-runtime "^6.22.0" 444 | 445 | babel-plugin-transform-es2015-destructuring@^6.19.0: 446 | version "6.23.0" 447 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" 448 | dependencies: 449 | babel-runtime "^6.22.0" 450 | 451 | babel-plugin-transform-es2015-function-name@^6.9.0: 452 | version "6.24.1" 453 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" 454 | dependencies: 455 | babel-helper-function-name "^6.24.1" 456 | babel-runtime "^6.22.0" 457 | babel-types "^6.24.1" 458 | 459 | babel-plugin-transform-es2015-modules-commonjs@^6.18.0: 460 | version "6.26.2" 461 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" 462 | dependencies: 463 | babel-plugin-transform-strict-mode "^6.24.1" 464 | babel-runtime "^6.26.0" 465 | babel-template "^6.26.0" 466 | babel-types "^6.26.0" 467 | 468 | babel-plugin-transform-es2015-parameters@^6.21.0: 469 | version "6.24.1" 470 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" 471 | dependencies: 472 | babel-helper-call-delegate "^6.24.1" 473 | babel-helper-get-function-arity "^6.24.1" 474 | babel-runtime "^6.22.0" 475 | babel-template "^6.24.1" 476 | babel-traverse "^6.24.1" 477 | babel-types "^6.24.1" 478 | 479 | babel-plugin-transform-es2015-spread@^6.8.0: 480 | version "6.22.0" 481 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" 482 | dependencies: 483 | babel-runtime "^6.22.0" 484 | 485 | babel-plugin-transform-es2015-sticky-regex@^6.8.0: 486 | version "6.24.1" 487 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" 488 | dependencies: 489 | babel-helper-regex "^6.24.1" 490 | babel-runtime "^6.22.0" 491 | babel-types "^6.24.1" 492 | 493 | babel-plugin-transform-es2015-unicode-regex@^6.11.0: 494 | version "6.24.1" 495 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" 496 | dependencies: 497 | babel-helper-regex "^6.24.1" 498 | babel-runtime "^6.22.0" 499 | regexpu-core "^2.0.0" 500 | 501 | babel-plugin-transform-exponentiation-operator@^6.8.0: 502 | version "6.24.1" 503 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" 504 | dependencies: 505 | babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" 506 | babel-plugin-syntax-exponentiation-operator "^6.8.0" 507 | babel-runtime "^6.22.0" 508 | 509 | babel-plugin-transform-strict-mode@^6.24.1: 510 | version "6.24.1" 511 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" 512 | dependencies: 513 | babel-runtime "^6.22.0" 514 | babel-types "^6.24.1" 515 | 516 | babel-register@^6.26.0: 517 | version "6.26.0" 518 | resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" 519 | dependencies: 520 | babel-core "^6.26.0" 521 | babel-runtime "^6.26.0" 522 | core-js "^2.5.0" 523 | home-or-tmp "^2.0.0" 524 | lodash "^4.17.4" 525 | mkdirp "^0.5.1" 526 | source-map-support "^0.4.15" 527 | 528 | babel-runtime@^6.22.0, babel-runtime@^6.26.0: 529 | version "6.26.0" 530 | resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" 531 | dependencies: 532 | core-js "^2.4.0" 533 | regenerator-runtime "^0.11.0" 534 | 535 | babel-template@^6.24.1, babel-template@^6.26.0: 536 | version "6.26.0" 537 | resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" 538 | dependencies: 539 | babel-runtime "^6.26.0" 540 | babel-traverse "^6.26.0" 541 | babel-types "^6.26.0" 542 | babylon "^6.18.0" 543 | lodash "^4.17.4" 544 | 545 | babel-traverse@^6.24.1, babel-traverse@^6.26.0: 546 | version "6.26.0" 547 | resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" 548 | dependencies: 549 | babel-code-frame "^6.26.0" 550 | babel-messages "^6.23.0" 551 | babel-runtime "^6.26.0" 552 | babel-types "^6.26.0" 553 | babylon "^6.18.0" 554 | debug "^2.6.8" 555 | globals "^9.18.0" 556 | invariant "^2.2.2" 557 | lodash "^4.17.4" 558 | 559 | babel-types@^6.24.1, babel-types@^6.26.0: 560 | version "6.26.0" 561 | resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" 562 | dependencies: 563 | babel-runtime "^6.26.0" 564 | esutils "^2.0.2" 565 | lodash "^4.17.4" 566 | to-fast-properties "^1.0.3" 567 | 568 | babylon@^6.1.0, babylon@^6.18.0: 569 | version "6.18.0" 570 | resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" 571 | 572 | balanced-match@^1.0.0: 573 | version "1.0.0" 574 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 575 | 576 | binary-extensions@^1.0.0: 577 | version "1.11.0" 578 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" 579 | 580 | bluebird@^3.0.0: 581 | version "3.5.1" 582 | resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" 583 | 584 | boolbase@~1.0.0: 585 | version "1.0.0" 586 | resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" 587 | 588 | boxen@^1.2.1: 589 | version "1.3.0" 590 | resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" 591 | dependencies: 592 | ansi-align "^2.0.0" 593 | camelcase "^4.0.0" 594 | chalk "^2.0.1" 595 | cli-boxes "^1.0.0" 596 | string-width "^2.0.0" 597 | term-size "^1.2.0" 598 | widest-line "^2.0.0" 599 | 600 | brace-expansion@^1.1.7: 601 | version "1.1.11" 602 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 603 | dependencies: 604 | balanced-match "^1.0.0" 605 | concat-map "0.0.1" 606 | 607 | braces@^1.8.2: 608 | version "1.8.5" 609 | resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" 610 | dependencies: 611 | expand-range "^1.8.1" 612 | preserve "^0.2.0" 613 | repeat-element "^1.1.2" 614 | 615 | buf-compare@^1.0.0: 616 | version "1.0.1" 617 | resolved "https://registry.yarnpkg.com/buf-compare/-/buf-compare-1.0.1.tgz#fef28da8b8113a0a0db4430b0b6467b69730b34a" 618 | 619 | buffer-from@^1.0.0: 620 | version "1.1.0" 621 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.0.tgz#87fcaa3a298358e0ade6e442cfce840740d1ad04" 622 | 623 | builtin-modules@^1.0.0: 624 | version "1.1.1" 625 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" 626 | 627 | cacheable-request@^2.1.1: 628 | version "2.1.4" 629 | resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" 630 | dependencies: 631 | clone-response "1.0.2" 632 | get-stream "3.0.0" 633 | http-cache-semantics "3.8.1" 634 | keyv "3.0.0" 635 | lowercase-keys "1.0.0" 636 | normalize-url "2.0.1" 637 | responselike "1.0.2" 638 | 639 | caching-transform@^1.0.0: 640 | version "1.0.1" 641 | resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" 642 | dependencies: 643 | md5-hex "^1.2.0" 644 | mkdirp "^0.5.1" 645 | write-file-atomic "^1.1.4" 646 | 647 | call-matcher@^1.0.0: 648 | version "1.0.1" 649 | resolved "https://registry.yarnpkg.com/call-matcher/-/call-matcher-1.0.1.tgz#5134d077984f712a54dad3cbf62de28dce416ca8" 650 | dependencies: 651 | core-js "^2.0.0" 652 | deep-equal "^1.0.0" 653 | espurify "^1.6.0" 654 | estraverse "^4.0.0" 655 | 656 | call-signature@0.0.2: 657 | version "0.0.2" 658 | resolved "https://registry.yarnpkg.com/call-signature/-/call-signature-0.0.2.tgz#a84abc825a55ef4cb2b028bd74e205a65b9a4996" 659 | 660 | camelcase-keys@^2.0.0: 661 | version "2.1.0" 662 | resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" 663 | dependencies: 664 | camelcase "^2.0.0" 665 | map-obj "^1.0.0" 666 | 667 | camelcase@^2.0.0: 668 | version "2.1.1" 669 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" 670 | 671 | camelcase@^4.0.0: 672 | version "4.1.0" 673 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" 674 | 675 | capture-stack-trace@^1.0.0: 676 | version "1.0.0" 677 | resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" 678 | 679 | chalk@^0.4.0: 680 | version "0.4.0" 681 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" 682 | dependencies: 683 | ansi-styles "~1.0.0" 684 | has-color "~0.1.0" 685 | strip-ansi "~0.1.0" 686 | 687 | chalk@^1.1.3: 688 | version "1.1.3" 689 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 690 | dependencies: 691 | ansi-styles "^2.2.1" 692 | escape-string-regexp "^1.0.2" 693 | has-ansi "^2.0.0" 694 | strip-ansi "^3.0.0" 695 | supports-color "^2.0.0" 696 | 697 | chalk@^2.0.1, chalk@^2.4.1: 698 | version "2.4.1" 699 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" 700 | dependencies: 701 | ansi-styles "^3.2.1" 702 | escape-string-regexp "^1.0.5" 703 | supports-color "^5.3.0" 704 | 705 | cheerio@^1.0.0-rc.2: 706 | version "1.0.0-rc.2" 707 | resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db" 708 | dependencies: 709 | css-select "~1.2.0" 710 | dom-serializer "~0.1.0" 711 | entities "~1.1.1" 712 | htmlparser2 "^3.9.1" 713 | lodash "^4.15.0" 714 | parse5 "^3.0.1" 715 | 716 | chokidar@^1.4.2: 717 | version "1.7.0" 718 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" 719 | dependencies: 720 | anymatch "^1.3.0" 721 | async-each "^1.0.0" 722 | glob-parent "^2.0.0" 723 | inherits "^2.0.1" 724 | is-binary-path "^1.0.0" 725 | is-glob "^2.0.0" 726 | path-is-absolute "^1.0.0" 727 | readdirp "^2.0.0" 728 | optionalDependencies: 729 | fsevents "^1.0.0" 730 | 731 | chownr@^1.0.1: 732 | version "1.0.1" 733 | resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" 734 | 735 | ci-info@^1.0.0: 736 | version "1.1.3" 737 | resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.3.tgz#710193264bb05c77b8c90d02f5aaf22216a667b2" 738 | 739 | clean-stack@^1.1.1: 740 | version "1.3.0" 741 | resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-1.3.0.tgz#9e821501ae979986c46b1d66d2d432db2fd4ae31" 742 | 743 | clean-yaml-object@^0.1.0: 744 | version "0.1.0" 745 | resolved "https://registry.yarnpkg.com/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz#63fb110dc2ce1a84dc21f6d9334876d010ae8b68" 746 | 747 | cli-boxes@^1.0.0: 748 | version "1.0.0" 749 | resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" 750 | 751 | cli-cursor@^2.1.0: 752 | version "2.1.0" 753 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" 754 | dependencies: 755 | restore-cursor "^2.0.0" 756 | 757 | cli-spinners@^1.0.0: 758 | version "1.3.1" 759 | resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.3.1.tgz#002c1990912d0d59580c93bd36c056de99e4259a" 760 | 761 | cli-truncate@^1.0.0: 762 | version "1.1.0" 763 | resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-1.1.0.tgz#2b2dfd83c53cfd3572b87fc4d430a808afb04086" 764 | dependencies: 765 | slice-ansi "^1.0.0" 766 | string-width "^2.0.0" 767 | 768 | cliui@^4.1.0: 769 | version "4.1.0" 770 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" 771 | dependencies: 772 | string-width "^2.1.1" 773 | strip-ansi "^4.0.0" 774 | wrap-ansi "^2.0.0" 775 | 776 | clone-response@1.0.2: 777 | version "1.0.2" 778 | resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" 779 | dependencies: 780 | mimic-response "^1.0.0" 781 | 782 | co-with-promise@^4.6.0: 783 | version "4.6.0" 784 | resolved "https://registry.yarnpkg.com/co-with-promise/-/co-with-promise-4.6.0.tgz#413e7db6f5893a60b942cf492c4bec93db415ab7" 785 | dependencies: 786 | pinkie-promise "^1.0.0" 787 | 788 | code-excerpt@^2.1.1: 789 | version "2.1.1" 790 | resolved "https://registry.yarnpkg.com/code-excerpt/-/code-excerpt-2.1.1.tgz#5fe3057bfbb71a5f300f659ef2cc0a47651ba77c" 791 | dependencies: 792 | convert-to-spaces "^1.0.1" 793 | 794 | code-point-at@^1.0.0: 795 | version "1.1.0" 796 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" 797 | 798 | color-convert@^1.9.0: 799 | version "1.9.1" 800 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" 801 | dependencies: 802 | color-name "^1.1.1" 803 | 804 | color-name@^1.1.1: 805 | version "1.1.3" 806 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 807 | 808 | commander@^2.15.1: 809 | version "2.15.1" 810 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" 811 | 812 | common-path-prefix@^1.0.0: 813 | version "1.0.0" 814 | resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-1.0.0.tgz#cd52f6f0712e0baab97d6f9732874f22f47752c0" 815 | 816 | commondir@^1.0.1: 817 | version "1.0.1" 818 | resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" 819 | 820 | concat-map@0.0.1: 821 | version "0.0.1" 822 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 823 | 824 | concordance@^3.0.0: 825 | version "3.0.0" 826 | resolved "https://registry.yarnpkg.com/concordance/-/concordance-3.0.0.tgz#b2286af54405fc995fc7345b0b106d8dd073cb29" 827 | dependencies: 828 | date-time "^2.1.0" 829 | esutils "^2.0.2" 830 | fast-diff "^1.1.1" 831 | function-name-support "^0.2.0" 832 | js-string-escape "^1.0.1" 833 | lodash.clonedeep "^4.5.0" 834 | lodash.flattendeep "^4.4.0" 835 | lodash.merge "^4.6.0" 836 | md5-hex "^2.0.0" 837 | semver "^5.3.0" 838 | well-known-symbols "^1.0.0" 839 | 840 | configstore@^3.0.0: 841 | version "3.1.2" 842 | resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" 843 | dependencies: 844 | dot-prop "^4.1.0" 845 | graceful-fs "^4.1.2" 846 | make-dir "^1.0.0" 847 | unique-string "^1.0.0" 848 | write-file-atomic "^2.0.0" 849 | xdg-basedir "^3.0.0" 850 | 851 | console-control-strings@^1.0.0, console-control-strings@~1.1.0: 852 | version "1.1.0" 853 | resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" 854 | 855 | convert-source-map@^1.5.1: 856 | version "1.5.1" 857 | resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" 858 | 859 | convert-to-spaces@^1.0.1: 860 | version "1.0.2" 861 | resolved "https://registry.yarnpkg.com/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz#7e3e48bbe6d997b1417ddca2868204b4d3d85715" 862 | 863 | core-assert@^0.2.0: 864 | version "0.2.1" 865 | resolved "https://registry.yarnpkg.com/core-assert/-/core-assert-0.2.1.tgz#f85e2cf9bfed28f773cc8b3fa5c5b69bdc02fe3f" 866 | dependencies: 867 | buf-compare "^1.0.0" 868 | is-error "^2.2.0" 869 | 870 | core-js@^2.0.0, core-js@^2.4.0, core-js@^2.5.0: 871 | version "2.5.7" 872 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" 873 | 874 | core-util-is@~1.0.0: 875 | version "1.0.2" 876 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 877 | 878 | create-error-class@^3.0.0: 879 | version "3.0.2" 880 | resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" 881 | dependencies: 882 | capture-stack-trace "^1.0.0" 883 | 884 | cross-spawn@^5.0.1: 885 | version "5.1.0" 886 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" 887 | dependencies: 888 | lru-cache "^4.0.1" 889 | shebang-command "^1.2.0" 890 | which "^1.2.9" 891 | 892 | crypto-random-string@^1.0.0: 893 | version "1.0.0" 894 | resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" 895 | 896 | css-select@~1.2.0: 897 | version "1.2.0" 898 | resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" 899 | dependencies: 900 | boolbase "~1.0.0" 901 | css-what "2.1" 902 | domutils "1.5.1" 903 | nth-check "~1.0.1" 904 | 905 | css-what@2.1: 906 | version "2.1.0" 907 | resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd" 908 | 909 | css@^2.2.3: 910 | version "2.2.3" 911 | resolved "https://registry.yarnpkg.com/css/-/css-2.2.3.tgz#f861f4ba61e79bedc962aa548e5780fd95cbc6be" 912 | dependencies: 913 | inherits "^2.0.1" 914 | source-map "^0.1.38" 915 | source-map-resolve "^0.5.1" 916 | urix "^0.1.0" 917 | 918 | currently-unhandled@^0.4.1: 919 | version "0.4.1" 920 | resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" 921 | dependencies: 922 | array-find-index "^1.0.1" 923 | 924 | date-time@^0.1.1: 925 | version "0.1.1" 926 | resolved "https://registry.yarnpkg.com/date-time/-/date-time-0.1.1.tgz#ed2f6d93d9790ce2fd66d5b5ff3edd5bbcbf3b07" 927 | 928 | date-time@^2.1.0: 929 | version "2.1.0" 930 | resolved "https://registry.yarnpkg.com/date-time/-/date-time-2.1.0.tgz#0286d1b4c769633b3ca13e1e62558d2dbdc2eba2" 931 | dependencies: 932 | time-zone "^1.0.0" 933 | 934 | debug@^2.1.2, debug@^2.6.8, debug@^2.6.9: 935 | version "2.6.9" 936 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 937 | dependencies: 938 | ms "2.0.0" 939 | 940 | debug@^3.0.1: 941 | version "3.1.0" 942 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 943 | dependencies: 944 | ms "2.0.0" 945 | 946 | decamelize@^1.1.2: 947 | version "1.2.0" 948 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 949 | 950 | decode-uri-component@^0.2.0: 951 | version "0.2.0" 952 | resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" 953 | 954 | decompress-response@^3.3.0: 955 | version "3.3.0" 956 | resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" 957 | dependencies: 958 | mimic-response "^1.0.0" 959 | 960 | deep-equal@^1.0.0: 961 | version "1.0.1" 962 | resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" 963 | 964 | deep-extend@^0.6.0: 965 | version "0.6.0" 966 | resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" 967 | 968 | delegates@^1.0.0: 969 | version "1.0.0" 970 | resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" 971 | 972 | detect-indent@^4.0.0: 973 | version "4.0.0" 974 | resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" 975 | dependencies: 976 | repeating "^2.0.0" 977 | 978 | detect-indent@^5.0.0: 979 | version "5.0.0" 980 | resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" 981 | 982 | detect-libc@^1.0.2: 983 | version "1.0.3" 984 | resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" 985 | 986 | dom-serializer@0, dom-serializer@~0.1.0: 987 | version "0.1.0" 988 | resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" 989 | dependencies: 990 | domelementtype "~1.1.1" 991 | entities "~1.1.1" 992 | 993 | domelementtype@1, domelementtype@^1.3.0: 994 | version "1.3.0" 995 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" 996 | 997 | domelementtype@~1.1.1: 998 | version "1.1.3" 999 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" 1000 | 1001 | domhandler@^2.3.0: 1002 | version "2.4.2" 1003 | resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" 1004 | dependencies: 1005 | domelementtype "1" 1006 | 1007 | domutils@1.5.1: 1008 | version "1.5.1" 1009 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" 1010 | dependencies: 1011 | dom-serializer "0" 1012 | domelementtype "1" 1013 | 1014 | domutils@^1.5.1: 1015 | version "1.7.0" 1016 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" 1017 | dependencies: 1018 | dom-serializer "0" 1019 | domelementtype "1" 1020 | 1021 | dot-prop@^4.1.0: 1022 | version "4.2.0" 1023 | resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" 1024 | dependencies: 1025 | is-obj "^1.0.0" 1026 | 1027 | duplexer3@^0.1.4: 1028 | version "0.1.4" 1029 | resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" 1030 | 1031 | empower-core@^0.6.1: 1032 | version "0.6.2" 1033 | resolved "https://registry.yarnpkg.com/empower-core/-/empower-core-0.6.2.tgz#5adef566088e31fba80ba0a36df47d7094169144" 1034 | dependencies: 1035 | call-signature "0.0.2" 1036 | core-js "^2.0.0" 1037 | 1038 | entities@^1.1.1, entities@~1.1.1: 1039 | version "1.1.1" 1040 | resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" 1041 | 1042 | equal-length@^1.0.0: 1043 | version "1.0.1" 1044 | resolved "https://registry.yarnpkg.com/equal-length/-/equal-length-1.0.1.tgz#21ca112d48ab24b4e1e7ffc0e5339d31fdfc274c" 1045 | 1046 | error-ex@^1.2.0, error-ex@^1.3.1: 1047 | version "1.3.1" 1048 | resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" 1049 | dependencies: 1050 | is-arrayish "^0.2.1" 1051 | 1052 | es6-error@^4.0.1, es6-error@^4.0.2: 1053 | version "4.1.1" 1054 | resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" 1055 | 1056 | escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: 1057 | version "1.0.5" 1058 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 1059 | 1060 | espower-location-detector@^1.0.0: 1061 | version "1.0.0" 1062 | resolved "https://registry.yarnpkg.com/espower-location-detector/-/espower-location-detector-1.0.0.tgz#a17b7ecc59d30e179e2bef73fb4137704cb331b5" 1063 | dependencies: 1064 | is-url "^1.2.1" 1065 | path-is-absolute "^1.0.0" 1066 | source-map "^0.5.0" 1067 | xtend "^4.0.0" 1068 | 1069 | esprima@^4.0.0: 1070 | version "4.0.0" 1071 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" 1072 | 1073 | espurify@^1.6.0: 1074 | version "1.8.0" 1075 | resolved "https://registry.yarnpkg.com/espurify/-/espurify-1.8.0.tgz#270d8046e4e47e923d75bc8a87357c7112ca8485" 1076 | dependencies: 1077 | core-js "^2.0.0" 1078 | 1079 | estraverse@^4.0.0, estraverse@^4.1.1: 1080 | version "4.2.0" 1081 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" 1082 | 1083 | esutils@^2.0.2: 1084 | version "2.0.2" 1085 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" 1086 | 1087 | execa@^0.7.0: 1088 | version "0.7.0" 1089 | resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" 1090 | dependencies: 1091 | cross-spawn "^5.0.1" 1092 | get-stream "^3.0.0" 1093 | is-stream "^1.1.0" 1094 | npm-run-path "^2.0.0" 1095 | p-finally "^1.0.0" 1096 | signal-exit "^3.0.0" 1097 | strip-eof "^1.0.0" 1098 | 1099 | expand-brackets@^0.1.4: 1100 | version "0.1.5" 1101 | resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" 1102 | dependencies: 1103 | is-posix-bracket "^0.1.0" 1104 | 1105 | expand-range@^1.8.1: 1106 | version "1.8.2" 1107 | resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" 1108 | dependencies: 1109 | fill-range "^2.1.0" 1110 | 1111 | extglob@^0.3.1: 1112 | version "0.3.2" 1113 | resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" 1114 | dependencies: 1115 | is-extglob "^1.0.0" 1116 | 1117 | fast-diff@^1.1.1: 1118 | version "1.1.2" 1119 | resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154" 1120 | 1121 | figures@^2.0.0: 1122 | version "2.0.0" 1123 | resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" 1124 | dependencies: 1125 | escape-string-regexp "^1.0.5" 1126 | 1127 | filename-regex@^2.0.0: 1128 | version "2.0.1" 1129 | resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" 1130 | 1131 | fill-range@^2.1.0: 1132 | version "2.2.4" 1133 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" 1134 | dependencies: 1135 | is-number "^2.1.0" 1136 | isobject "^2.0.0" 1137 | randomatic "^3.0.0" 1138 | repeat-element "^1.1.2" 1139 | repeat-string "^1.5.2" 1140 | 1141 | find-cache-dir@^1.0.0: 1142 | version "1.0.0" 1143 | resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" 1144 | dependencies: 1145 | commondir "^1.0.1" 1146 | make-dir "^1.0.0" 1147 | pkg-dir "^2.0.0" 1148 | 1149 | find-up@^1.0.0: 1150 | version "1.1.2" 1151 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" 1152 | dependencies: 1153 | path-exists "^2.0.0" 1154 | pinkie-promise "^2.0.0" 1155 | 1156 | find-up@^2.0.0, find-up@^2.1.0: 1157 | version "2.1.0" 1158 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" 1159 | dependencies: 1160 | locate-path "^2.0.0" 1161 | 1162 | fn-name@^2.0.0: 1163 | version "2.0.1" 1164 | resolved "https://registry.yarnpkg.com/fn-name/-/fn-name-2.0.1.tgz#5214d7537a4d06a4a301c0cc262feb84188002e7" 1165 | 1166 | for-in@^1.0.1: 1167 | version "1.0.2" 1168 | resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" 1169 | 1170 | for-own@^0.1.4: 1171 | version "0.1.5" 1172 | resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" 1173 | dependencies: 1174 | for-in "^1.0.1" 1175 | 1176 | from2@^2.1.1: 1177 | version "2.3.0" 1178 | resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" 1179 | dependencies: 1180 | inherits "^2.0.1" 1181 | readable-stream "^2.0.0" 1182 | 1183 | fs-extra@^6.0.1: 1184 | version "6.0.1" 1185 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b" 1186 | dependencies: 1187 | graceful-fs "^4.1.2" 1188 | jsonfile "^4.0.0" 1189 | universalify "^0.1.0" 1190 | 1191 | fs-minipass@^1.2.5: 1192 | version "1.2.5" 1193 | resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" 1194 | dependencies: 1195 | minipass "^2.2.1" 1196 | 1197 | fs.realpath@^1.0.0: 1198 | version "1.0.0" 1199 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 1200 | 1201 | fsevents@^1.0.0: 1202 | version "1.2.4" 1203 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" 1204 | dependencies: 1205 | nan "^2.9.2" 1206 | node-pre-gyp "^0.10.0" 1207 | 1208 | function-name-support@^0.2.0: 1209 | version "0.2.0" 1210 | resolved "https://registry.yarnpkg.com/function-name-support/-/function-name-support-0.2.0.tgz#55d3bfaa6eafd505a50f9bc81fdf57564a0bb071" 1211 | 1212 | gauge@~2.7.3: 1213 | version "2.7.4" 1214 | resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" 1215 | dependencies: 1216 | aproba "^1.0.3" 1217 | console-control-strings "^1.0.0" 1218 | has-unicode "^2.0.0" 1219 | object-assign "^4.1.0" 1220 | signal-exit "^3.0.0" 1221 | string-width "^1.0.1" 1222 | strip-ansi "^3.0.1" 1223 | wide-align "^1.1.0" 1224 | 1225 | get-port@^3.0.0: 1226 | version "3.2.0" 1227 | resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" 1228 | 1229 | get-ssl-certificate@^2.1.2: 1230 | version "2.1.2" 1231 | resolved "https://registry.yarnpkg.com/get-ssl-certificate/-/get-ssl-certificate-2.1.2.tgz#c66d99c9c60384cfa8090250a268bbc347138b5e" 1232 | 1233 | get-stdin@^4.0.1: 1234 | version "4.0.1" 1235 | resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" 1236 | 1237 | get-stream@3.0.0, get-stream@^3.0.0: 1238 | version "3.0.0" 1239 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" 1240 | 1241 | glob-base@^0.3.0: 1242 | version "0.3.0" 1243 | resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" 1244 | dependencies: 1245 | glob-parent "^2.0.0" 1246 | is-glob "^2.0.0" 1247 | 1248 | glob-parent@^2.0.0: 1249 | version "2.0.0" 1250 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" 1251 | dependencies: 1252 | is-glob "^2.0.0" 1253 | 1254 | glob@^7.0.3, glob@^7.0.5: 1255 | version "7.1.2" 1256 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" 1257 | dependencies: 1258 | fs.realpath "^1.0.0" 1259 | inflight "^1.0.4" 1260 | inherits "2" 1261 | minimatch "^3.0.4" 1262 | once "^1.3.0" 1263 | path-is-absolute "^1.0.0" 1264 | 1265 | global-dirs@^0.1.0: 1266 | version "0.1.1" 1267 | resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" 1268 | dependencies: 1269 | ini "^1.3.4" 1270 | 1271 | globals@^9.18.0: 1272 | version "9.18.0" 1273 | resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" 1274 | 1275 | globby@^6.0.0: 1276 | version "6.1.0" 1277 | resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" 1278 | dependencies: 1279 | array-union "^1.0.1" 1280 | glob "^7.0.3" 1281 | object-assign "^4.0.1" 1282 | pify "^2.0.0" 1283 | pinkie-promise "^2.0.0" 1284 | 1285 | got@^6.7.1: 1286 | version "6.7.1" 1287 | resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" 1288 | dependencies: 1289 | create-error-class "^3.0.0" 1290 | duplexer3 "^0.1.4" 1291 | get-stream "^3.0.0" 1292 | is-redirect "^1.0.0" 1293 | is-retry-allowed "^1.0.0" 1294 | is-stream "^1.0.0" 1295 | lowercase-keys "^1.0.0" 1296 | safe-buffer "^5.0.1" 1297 | timed-out "^4.0.0" 1298 | unzip-response "^2.0.1" 1299 | url-parse-lax "^1.0.0" 1300 | 1301 | got@^8.3.1: 1302 | version "8.3.1" 1303 | resolved "https://registry.yarnpkg.com/got/-/got-8.3.1.tgz#093324403d4d955f5a16a7a8d39955d055ae10ed" 1304 | dependencies: 1305 | "@sindresorhus/is" "^0.7.0" 1306 | cacheable-request "^2.1.1" 1307 | decompress-response "^3.3.0" 1308 | duplexer3 "^0.1.4" 1309 | get-stream "^3.0.0" 1310 | into-stream "^3.1.0" 1311 | is-retry-allowed "^1.1.0" 1312 | isurl "^1.0.0-alpha5" 1313 | lowercase-keys "^1.0.0" 1314 | mimic-response "^1.0.0" 1315 | p-cancelable "^0.4.0" 1316 | p-timeout "^2.0.1" 1317 | pify "^3.0.0" 1318 | safe-buffer "^5.1.1" 1319 | timed-out "^4.0.1" 1320 | url-parse-lax "^3.0.0" 1321 | url-to-options "^1.0.1" 1322 | 1323 | graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: 1324 | version "4.1.11" 1325 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" 1326 | 1327 | has-ansi@^2.0.0: 1328 | version "2.0.0" 1329 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 1330 | dependencies: 1331 | ansi-regex "^2.0.0" 1332 | 1333 | has-color@~0.1.0: 1334 | version "0.1.7" 1335 | resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" 1336 | 1337 | has-flag@^2.0.0: 1338 | version "2.0.0" 1339 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" 1340 | 1341 | has-flag@^3.0.0: 1342 | version "3.0.0" 1343 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 1344 | 1345 | has-symbol-support-x@^1.4.1: 1346 | version "1.4.2" 1347 | resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" 1348 | 1349 | has-to-string-tag-x@^1.2.0: 1350 | version "1.4.1" 1351 | resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" 1352 | dependencies: 1353 | has-symbol-support-x "^1.4.1" 1354 | 1355 | has-unicode@^2.0.0: 1356 | version "2.0.1" 1357 | resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" 1358 | 1359 | has-yarn@^1.0.0: 1360 | version "1.0.0" 1361 | resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-1.0.0.tgz#89e25db604b725c8f5976fff0addc921b828a5a7" 1362 | 1363 | home-or-tmp@^2.0.0: 1364 | version "2.0.0" 1365 | resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" 1366 | dependencies: 1367 | os-homedir "^1.0.0" 1368 | os-tmpdir "^1.0.1" 1369 | 1370 | hosted-git-info@^2.1.4: 1371 | version "2.6.0" 1372 | resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.6.0.tgz#23235b29ab230c576aab0d4f13fc046b0b038222" 1373 | 1374 | htmlparser2@^3.9.1: 1375 | version "3.9.2" 1376 | resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338" 1377 | dependencies: 1378 | domelementtype "^1.3.0" 1379 | domhandler "^2.3.0" 1380 | domutils "^1.5.1" 1381 | entities "^1.1.1" 1382 | inherits "^2.0.1" 1383 | readable-stream "^2.0.2" 1384 | 1385 | http-cache-semantics@3.8.1: 1386 | version "3.8.1" 1387 | resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" 1388 | 1389 | hullabaloo-config-manager@^1.1.0: 1390 | version "1.1.1" 1391 | resolved "https://registry.yarnpkg.com/hullabaloo-config-manager/-/hullabaloo-config-manager-1.1.1.tgz#1d9117813129ad035fd9e8477eaf066911269fe3" 1392 | dependencies: 1393 | dot-prop "^4.1.0" 1394 | es6-error "^4.0.2" 1395 | graceful-fs "^4.1.11" 1396 | indent-string "^3.1.0" 1397 | json5 "^0.5.1" 1398 | lodash.clonedeep "^4.5.0" 1399 | lodash.clonedeepwith "^4.5.0" 1400 | lodash.isequal "^4.5.0" 1401 | lodash.merge "^4.6.0" 1402 | md5-hex "^2.0.0" 1403 | package-hash "^2.0.0" 1404 | pkg-dir "^2.0.0" 1405 | resolve-from "^3.0.0" 1406 | safe-buffer "^5.0.1" 1407 | 1408 | iconv-lite@^0.4.4: 1409 | version "0.4.23" 1410 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" 1411 | dependencies: 1412 | safer-buffer ">= 2.1.2 < 3" 1413 | 1414 | ignore-by-default@^1.0.0: 1415 | version "1.0.1" 1416 | resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" 1417 | 1418 | ignore-walk@^3.0.1: 1419 | version "3.0.1" 1420 | resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" 1421 | dependencies: 1422 | minimatch "^3.0.4" 1423 | 1424 | import-lazy@^2.1.0: 1425 | version "2.1.0" 1426 | resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" 1427 | 1428 | import-local@^0.1.1: 1429 | version "0.1.1" 1430 | resolved "https://registry.yarnpkg.com/import-local/-/import-local-0.1.1.tgz#b1179572aacdc11c6a91009fb430dbcab5f668a8" 1431 | dependencies: 1432 | pkg-dir "^2.0.0" 1433 | resolve-cwd "^2.0.0" 1434 | 1435 | imurmurhash@^0.1.4: 1436 | version "0.1.4" 1437 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 1438 | 1439 | indent-string@^2.1.0: 1440 | version "2.1.0" 1441 | resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" 1442 | dependencies: 1443 | repeating "^2.0.0" 1444 | 1445 | indent-string@^3.0.0, indent-string@^3.1.0, indent-string@^3.2.0: 1446 | version "3.2.0" 1447 | resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" 1448 | 1449 | inflight@^1.0.4: 1450 | version "1.0.6" 1451 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 1452 | dependencies: 1453 | once "^1.3.0" 1454 | wrappy "1" 1455 | 1456 | inherits@2, inherits@^2.0.1, inherits@~2.0.3: 1457 | version "2.0.3" 1458 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 1459 | 1460 | ini@^1.3.4, ini@~1.3.0: 1461 | version "1.3.5" 1462 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" 1463 | 1464 | into-stream@^3.1.0: 1465 | version "3.1.0" 1466 | resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" 1467 | dependencies: 1468 | from2 "^2.1.1" 1469 | p-is-promise "^1.1.0" 1470 | 1471 | invariant@^2.2.2: 1472 | version "2.2.4" 1473 | resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" 1474 | dependencies: 1475 | loose-envify "^1.0.0" 1476 | 1477 | irregular-plurals@^1.0.0: 1478 | version "1.4.0" 1479 | resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.4.0.tgz#2ca9b033651111855412f16be5d77c62a458a766" 1480 | 1481 | is-arrayish@^0.2.1: 1482 | version "0.2.1" 1483 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" 1484 | 1485 | is-binary-path@^1.0.0: 1486 | version "1.0.1" 1487 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" 1488 | dependencies: 1489 | binary-extensions "^1.0.0" 1490 | 1491 | is-buffer@^1.1.5: 1492 | version "1.1.6" 1493 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" 1494 | 1495 | is-builtin-module@^1.0.0: 1496 | version "1.0.0" 1497 | resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" 1498 | dependencies: 1499 | builtin-modules "^1.0.0" 1500 | 1501 | is-ci@^1.0.10, is-ci@^1.0.7: 1502 | version "1.1.0" 1503 | resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5" 1504 | dependencies: 1505 | ci-info "^1.0.0" 1506 | 1507 | is-dotfile@^1.0.0: 1508 | version "1.0.3" 1509 | resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" 1510 | 1511 | is-equal-shallow@^0.1.3: 1512 | version "0.1.3" 1513 | resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" 1514 | dependencies: 1515 | is-primitive "^2.0.0" 1516 | 1517 | is-error@^2.2.0: 1518 | version "2.2.1" 1519 | resolved "https://registry.yarnpkg.com/is-error/-/is-error-2.2.1.tgz#684a96d84076577c98f4cdb40c6d26a5123bf19c" 1520 | 1521 | is-extendable@^0.1.1: 1522 | version "0.1.1" 1523 | resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" 1524 | 1525 | is-extglob@^1.0.0: 1526 | version "1.0.0" 1527 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" 1528 | 1529 | is-finite@^1.0.0: 1530 | version "1.0.2" 1531 | resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" 1532 | dependencies: 1533 | number-is-nan "^1.0.0" 1534 | 1535 | is-fullwidth-code-point@^1.0.0: 1536 | version "1.0.0" 1537 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" 1538 | dependencies: 1539 | number-is-nan "^1.0.0" 1540 | 1541 | is-fullwidth-code-point@^2.0.0: 1542 | version "2.0.0" 1543 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 1544 | 1545 | is-generator-fn@^1.0.0: 1546 | version "1.0.0" 1547 | resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" 1548 | 1549 | is-glob@^2.0.0, is-glob@^2.0.1: 1550 | version "2.0.1" 1551 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" 1552 | dependencies: 1553 | is-extglob "^1.0.0" 1554 | 1555 | is-installed-globally@^0.1.0: 1556 | version "0.1.0" 1557 | resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" 1558 | dependencies: 1559 | global-dirs "^0.1.0" 1560 | is-path-inside "^1.0.0" 1561 | 1562 | is-npm@^1.0.0: 1563 | version "1.0.0" 1564 | resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" 1565 | 1566 | is-number@^2.1.0: 1567 | version "2.1.0" 1568 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" 1569 | dependencies: 1570 | kind-of "^3.0.2" 1571 | 1572 | is-number@^4.0.0: 1573 | version "4.0.0" 1574 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" 1575 | 1576 | is-obj@^1.0.0: 1577 | version "1.0.1" 1578 | resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" 1579 | 1580 | is-object@^1.0.1: 1581 | version "1.0.1" 1582 | resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" 1583 | 1584 | is-observable@^0.2.0: 1585 | version "0.2.0" 1586 | resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.2.0.tgz#b361311d83c6e5d726cabf5e250b0237106f5ae2" 1587 | dependencies: 1588 | symbol-observable "^0.2.2" 1589 | 1590 | is-observable@^1.0.0: 1591 | version "1.1.0" 1592 | resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" 1593 | dependencies: 1594 | symbol-observable "^1.1.0" 1595 | 1596 | is-path-inside@^1.0.0: 1597 | version "1.0.1" 1598 | resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" 1599 | dependencies: 1600 | path-is-inside "^1.0.1" 1601 | 1602 | is-plain-obj@^1.0.0: 1603 | version "1.1.0" 1604 | resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" 1605 | 1606 | is-posix-bracket@^0.1.0: 1607 | version "0.1.1" 1608 | resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" 1609 | 1610 | is-primitive@^2.0.0: 1611 | version "2.0.0" 1612 | resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" 1613 | 1614 | is-promise@^2.1.0: 1615 | version "2.1.0" 1616 | resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" 1617 | 1618 | is-redirect@^1.0.0: 1619 | version "1.0.0" 1620 | resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" 1621 | 1622 | is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: 1623 | version "1.1.0" 1624 | resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" 1625 | 1626 | is-stream@^1.0.0, is-stream@^1.1.0: 1627 | version "1.1.0" 1628 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" 1629 | 1630 | is-url@^1.2.1: 1631 | version "1.2.4" 1632 | resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" 1633 | 1634 | is-utf8@^0.2.0, is-utf8@^0.2.1: 1635 | version "0.2.1" 1636 | resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" 1637 | 1638 | isarray@1.0.0, isarray@~1.0.0: 1639 | version "1.0.0" 1640 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 1641 | 1642 | isexe@^2.0.0: 1643 | version "2.0.0" 1644 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 1645 | 1646 | isobject@^2.0.0: 1647 | version "2.1.0" 1648 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" 1649 | dependencies: 1650 | isarray "1.0.0" 1651 | 1652 | isurl@^1.0.0-alpha5: 1653 | version "1.0.0" 1654 | resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" 1655 | dependencies: 1656 | has-to-string-tag-x "^1.2.0" 1657 | is-object "^1.0.1" 1658 | 1659 | js-string-escape@^1.0.1: 1660 | version "1.0.1" 1661 | resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" 1662 | 1663 | js-tokens@^3.0.0, js-tokens@^3.0.2: 1664 | version "3.0.2" 1665 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" 1666 | 1667 | js-yaml@^3.10.0: 1668 | version "3.11.0" 1669 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" 1670 | dependencies: 1671 | argparse "^1.0.7" 1672 | esprima "^4.0.0" 1673 | 1674 | jsesc@^1.3.0: 1675 | version "1.3.0" 1676 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" 1677 | 1678 | jsesc@~0.5.0: 1679 | version "0.5.0" 1680 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" 1681 | 1682 | json-buffer@3.0.0: 1683 | version "3.0.0" 1684 | resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" 1685 | 1686 | json-parse-better-errors@^1.0.1: 1687 | version "1.0.2" 1688 | resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" 1689 | 1690 | json5@^0.5.1: 1691 | version "0.5.1" 1692 | resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" 1693 | 1694 | jsonfile@^4.0.0: 1695 | version "4.0.0" 1696 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" 1697 | optionalDependencies: 1698 | graceful-fs "^4.1.6" 1699 | 1700 | keyv@3.0.0: 1701 | version "3.0.0" 1702 | resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" 1703 | dependencies: 1704 | json-buffer "3.0.0" 1705 | 1706 | kind-of@^3.0.2: 1707 | version "3.2.2" 1708 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" 1709 | dependencies: 1710 | is-buffer "^1.1.5" 1711 | 1712 | kind-of@^6.0.0: 1713 | version "6.0.2" 1714 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" 1715 | 1716 | last-line-stream@^1.0.0: 1717 | version "1.0.0" 1718 | resolved "https://registry.yarnpkg.com/last-line-stream/-/last-line-stream-1.0.0.tgz#d1b64d69f86ff24af2d04883a2ceee14520a5600" 1719 | dependencies: 1720 | through2 "^2.0.0" 1721 | 1722 | latest-version@^3.0.0: 1723 | version "3.1.0" 1724 | resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" 1725 | dependencies: 1726 | package-json "^4.0.0" 1727 | 1728 | load-json-file@^1.0.0: 1729 | version "1.1.0" 1730 | resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" 1731 | dependencies: 1732 | graceful-fs "^4.1.2" 1733 | parse-json "^2.2.0" 1734 | pify "^2.0.0" 1735 | pinkie-promise "^2.0.0" 1736 | strip-bom "^2.0.0" 1737 | 1738 | load-json-file@^2.0.0: 1739 | version "2.0.0" 1740 | resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" 1741 | dependencies: 1742 | graceful-fs "^4.1.2" 1743 | parse-json "^2.2.0" 1744 | pify "^2.0.0" 1745 | strip-bom "^3.0.0" 1746 | 1747 | load-json-file@^4.0.0: 1748 | version "4.0.0" 1749 | resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" 1750 | dependencies: 1751 | graceful-fs "^4.1.2" 1752 | parse-json "^4.0.0" 1753 | pify "^3.0.0" 1754 | strip-bom "^3.0.0" 1755 | 1756 | locate-path@^2.0.0: 1757 | version "2.0.0" 1758 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" 1759 | dependencies: 1760 | p-locate "^2.0.0" 1761 | path-exists "^3.0.0" 1762 | 1763 | lodash.clonedeep@^4.5.0: 1764 | version "4.5.0" 1765 | resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" 1766 | 1767 | lodash.clonedeepwith@^4.5.0: 1768 | version "4.5.0" 1769 | resolved "https://registry.yarnpkg.com/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz#6ee30573a03a1a60d670a62ef33c10cf1afdbdd4" 1770 | 1771 | lodash.debounce@^4.0.3: 1772 | version "4.0.8" 1773 | resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" 1774 | 1775 | lodash.difference@^4.3.0: 1776 | version "4.5.0" 1777 | resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" 1778 | 1779 | lodash.flatten@^4.2.0: 1780 | version "4.4.0" 1781 | resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" 1782 | 1783 | lodash.flattendeep@^4.4.0: 1784 | version "4.4.0" 1785 | resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" 1786 | 1787 | lodash.isequal@^4.5.0: 1788 | version "4.5.0" 1789 | resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" 1790 | 1791 | lodash.merge@^4.6.0: 1792 | version "4.6.1" 1793 | resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54" 1794 | 1795 | lodash@^4.15.0, lodash@^4.17.4: 1796 | version "4.17.10" 1797 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" 1798 | 1799 | loose-envify@^1.0.0: 1800 | version "1.3.1" 1801 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" 1802 | dependencies: 1803 | js-tokens "^3.0.0" 1804 | 1805 | loud-rejection@^1.0.0, loud-rejection@^1.2.0: 1806 | version "1.6.0" 1807 | resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" 1808 | dependencies: 1809 | currently-unhandled "^0.4.1" 1810 | signal-exit "^3.0.0" 1811 | 1812 | lowercase-keys@1.0.0: 1813 | version "1.0.0" 1814 | resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" 1815 | 1816 | lowercase-keys@^1.0.0: 1817 | version "1.0.1" 1818 | resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" 1819 | 1820 | lru-cache@^4.0.1: 1821 | version "4.1.3" 1822 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" 1823 | dependencies: 1824 | pseudomap "^1.0.2" 1825 | yallist "^2.1.2" 1826 | 1827 | make-dir@^1.0.0: 1828 | version "1.3.0" 1829 | resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" 1830 | dependencies: 1831 | pify "^3.0.0" 1832 | 1833 | map-obj@^1.0.0, map-obj@^1.0.1: 1834 | version "1.0.1" 1835 | resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" 1836 | 1837 | matcher@^1.0.0: 1838 | version "1.1.1" 1839 | resolved "https://registry.yarnpkg.com/matcher/-/matcher-1.1.1.tgz#51d8301e138f840982b338b116bb0c09af62c1c2" 1840 | dependencies: 1841 | escape-string-regexp "^1.0.4" 1842 | 1843 | math-random@^1.0.1: 1844 | version "1.0.1" 1845 | resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" 1846 | 1847 | md5-hex@^1.2.0, md5-hex@^1.3.0: 1848 | version "1.3.0" 1849 | resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" 1850 | dependencies: 1851 | md5-o-matic "^0.1.1" 1852 | 1853 | md5-hex@^2.0.0: 1854 | version "2.0.0" 1855 | resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" 1856 | dependencies: 1857 | md5-o-matic "^0.1.1" 1858 | 1859 | md5-o-matic@^0.1.1: 1860 | version "0.1.1" 1861 | resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" 1862 | 1863 | meow@^3.7.0: 1864 | version "3.7.0" 1865 | resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" 1866 | dependencies: 1867 | camelcase-keys "^2.0.0" 1868 | decamelize "^1.1.2" 1869 | loud-rejection "^1.0.0" 1870 | map-obj "^1.0.1" 1871 | minimist "^1.1.3" 1872 | normalize-package-data "^2.3.4" 1873 | object-assign "^4.0.1" 1874 | read-pkg-up "^1.0.1" 1875 | redent "^1.0.0" 1876 | trim-newlines "^1.0.0" 1877 | 1878 | micromatch@^2.1.5: 1879 | version "2.3.11" 1880 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" 1881 | dependencies: 1882 | arr-diff "^2.0.0" 1883 | array-unique "^0.2.1" 1884 | braces "^1.8.2" 1885 | expand-brackets "^0.1.4" 1886 | extglob "^0.3.1" 1887 | filename-regex "^2.0.0" 1888 | is-extglob "^1.0.0" 1889 | is-glob "^2.0.1" 1890 | kind-of "^3.0.2" 1891 | normalize-path "^2.0.1" 1892 | object.omit "^2.0.0" 1893 | parse-glob "^3.0.4" 1894 | regex-cache "^0.4.2" 1895 | 1896 | mimic-fn@^1.0.0: 1897 | version "1.2.0" 1898 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" 1899 | 1900 | mimic-response@^1.0.0: 1901 | version "1.0.0" 1902 | resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e" 1903 | 1904 | minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: 1905 | version "3.0.4" 1906 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 1907 | dependencies: 1908 | brace-expansion "^1.1.7" 1909 | 1910 | minimist@0.0.8: 1911 | version "0.0.8" 1912 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 1913 | 1914 | minimist@^1.1.3, minimist@^1.2.0: 1915 | version "1.2.0" 1916 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 1917 | 1918 | minipass@^2.2.1, minipass@^2.3.3: 1919 | version "2.3.3" 1920 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.3.tgz#a7dcc8b7b833f5d368759cce544dccb55f50f233" 1921 | dependencies: 1922 | safe-buffer "^5.1.2" 1923 | yallist "^3.0.0" 1924 | 1925 | minizlib@^1.1.0: 1926 | version "1.1.0" 1927 | resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" 1928 | dependencies: 1929 | minipass "^2.2.1" 1930 | 1931 | mkdirp@^0.5.0, mkdirp@^0.5.1: 1932 | version "0.5.1" 1933 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 1934 | dependencies: 1935 | minimist "0.0.8" 1936 | 1937 | moment@^2.22.1: 1938 | version "2.22.1" 1939 | resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.1.tgz#529a2e9bf973f259c9643d237fda84de3a26e8ad" 1940 | 1941 | ms@2.0.0: 1942 | version "2.0.0" 1943 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 1944 | 1945 | ms@^2.0.0: 1946 | version "2.1.1" 1947 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" 1948 | 1949 | multimatch@^2.1.0: 1950 | version "2.1.0" 1951 | resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" 1952 | dependencies: 1953 | array-differ "^1.0.0" 1954 | array-union "^1.0.1" 1955 | arrify "^1.0.0" 1956 | minimatch "^3.0.0" 1957 | 1958 | nan@^2.9.2: 1959 | version "2.10.0" 1960 | resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" 1961 | 1962 | needle@^2.2.0: 1963 | version "2.2.1" 1964 | resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.1.tgz#b5e325bd3aae8c2678902fa296f729455d1d3a7d" 1965 | dependencies: 1966 | debug "^2.1.2" 1967 | iconv-lite "^0.4.4" 1968 | sax "^1.2.4" 1969 | 1970 | node-pre-gyp@^0.10.0: 1971 | version "0.10.0" 1972 | resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.0.tgz#6e4ef5bb5c5203c6552448828c852c40111aac46" 1973 | dependencies: 1974 | detect-libc "^1.0.2" 1975 | mkdirp "^0.5.1" 1976 | needle "^2.2.0" 1977 | nopt "^4.0.1" 1978 | npm-packlist "^1.1.6" 1979 | npmlog "^4.0.2" 1980 | rc "^1.1.7" 1981 | rimraf "^2.6.1" 1982 | semver "^5.3.0" 1983 | tar "^4" 1984 | 1985 | nopt@^4.0.1: 1986 | version "4.0.1" 1987 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" 1988 | dependencies: 1989 | abbrev "1" 1990 | osenv "^0.1.4" 1991 | 1992 | normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: 1993 | version "2.4.0" 1994 | resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" 1995 | dependencies: 1996 | hosted-git-info "^2.1.4" 1997 | is-builtin-module "^1.0.0" 1998 | semver "2 || 3 || 4 || 5" 1999 | validate-npm-package-license "^3.0.1" 2000 | 2001 | normalize-path@^2.0.0, normalize-path@^2.0.1: 2002 | version "2.1.1" 2003 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" 2004 | dependencies: 2005 | remove-trailing-separator "^1.0.1" 2006 | 2007 | normalize-url@2.0.1: 2008 | version "2.0.1" 2009 | resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" 2010 | dependencies: 2011 | prepend-http "^2.0.0" 2012 | query-string "^5.0.1" 2013 | sort-keys "^2.0.0" 2014 | 2015 | npm-bundled@^1.0.1: 2016 | version "1.0.3" 2017 | resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" 2018 | 2019 | npm-packlist@^1.1.6: 2020 | version "1.1.10" 2021 | resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.10.tgz#1039db9e985727e464df066f4cf0ab6ef85c398a" 2022 | dependencies: 2023 | ignore-walk "^3.0.1" 2024 | npm-bundled "^1.0.1" 2025 | 2026 | npm-run-path@^2.0.0: 2027 | version "2.0.2" 2028 | resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" 2029 | dependencies: 2030 | path-key "^2.0.0" 2031 | 2032 | npmlog@^4.0.2: 2033 | version "4.1.2" 2034 | resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" 2035 | dependencies: 2036 | are-we-there-yet "~1.1.2" 2037 | console-control-strings "~1.1.0" 2038 | gauge "~2.7.3" 2039 | set-blocking "~2.0.0" 2040 | 2041 | nth-check@~1.0.1: 2042 | version "1.0.1" 2043 | resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4" 2044 | dependencies: 2045 | boolbase "~1.0.0" 2046 | 2047 | number-is-nan@^1.0.0: 2048 | version "1.0.1" 2049 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 2050 | 2051 | object-assign@^4.0.1, object-assign@^4.1.0: 2052 | version "4.1.1" 2053 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 2054 | 2055 | object.omit@^2.0.0: 2056 | version "2.0.1" 2057 | resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" 2058 | dependencies: 2059 | for-own "^0.1.4" 2060 | is-extendable "^0.1.1" 2061 | 2062 | observable-to-promise@^0.5.0: 2063 | version "0.5.0" 2064 | resolved "https://registry.yarnpkg.com/observable-to-promise/-/observable-to-promise-0.5.0.tgz#c828f0f0dc47e9f86af8a4977c5d55076ce7a91f" 2065 | dependencies: 2066 | is-observable "^0.2.0" 2067 | symbol-observable "^1.0.4" 2068 | 2069 | once@^1.3.0: 2070 | version "1.4.0" 2071 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 2072 | dependencies: 2073 | wrappy "1" 2074 | 2075 | onetime@^2.0.0: 2076 | version "2.0.1" 2077 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" 2078 | dependencies: 2079 | mimic-fn "^1.0.0" 2080 | 2081 | option-chain@^1.0.0: 2082 | version "1.0.0" 2083 | resolved "https://registry.yarnpkg.com/option-chain/-/option-chain-1.0.0.tgz#938d73bd4e1783f948d34023644ada23669e30f2" 2084 | 2085 | os-homedir@^1.0.0: 2086 | version "1.0.2" 2087 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 2088 | 2089 | os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: 2090 | version "1.0.2" 2091 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" 2092 | 2093 | osenv@^0.1.4: 2094 | version "0.1.5" 2095 | resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" 2096 | dependencies: 2097 | os-homedir "^1.0.0" 2098 | os-tmpdir "^1.0.0" 2099 | 2100 | p-cancelable@^0.4.0: 2101 | version "0.4.1" 2102 | resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" 2103 | 2104 | p-finally@^1.0.0: 2105 | version "1.0.0" 2106 | resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" 2107 | 2108 | p-is-promise@^1.1.0: 2109 | version "1.1.0" 2110 | resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" 2111 | 2112 | p-limit@^1.1.0: 2113 | version "1.2.0" 2114 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" 2115 | dependencies: 2116 | p-try "^1.0.0" 2117 | 2118 | p-locate@^2.0.0: 2119 | version "2.0.0" 2120 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" 2121 | dependencies: 2122 | p-limit "^1.1.0" 2123 | 2124 | p-timeout@^2.0.1: 2125 | version "2.0.1" 2126 | resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" 2127 | dependencies: 2128 | p-finally "^1.0.0" 2129 | 2130 | p-try@^1.0.0: 2131 | version "1.0.0" 2132 | resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" 2133 | 2134 | package-hash@^1.2.0: 2135 | version "1.2.0" 2136 | resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-1.2.0.tgz#003e56cd57b736a6ed6114cc2b81542672770e44" 2137 | dependencies: 2138 | md5-hex "^1.3.0" 2139 | 2140 | package-hash@^2.0.0: 2141 | version "2.0.0" 2142 | resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-2.0.0.tgz#78ae326c89e05a4d813b68601977af05c00d2a0d" 2143 | dependencies: 2144 | graceful-fs "^4.1.11" 2145 | lodash.flattendeep "^4.4.0" 2146 | md5-hex "^2.0.0" 2147 | release-zalgo "^1.0.0" 2148 | 2149 | package-json@^4.0.0: 2150 | version "4.0.1" 2151 | resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" 2152 | dependencies: 2153 | got "^6.7.1" 2154 | registry-auth-token "^3.0.1" 2155 | registry-url "^3.0.3" 2156 | semver "^5.1.0" 2157 | 2158 | parse-glob@^3.0.4: 2159 | version "3.0.4" 2160 | resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" 2161 | dependencies: 2162 | glob-base "^0.3.0" 2163 | is-dotfile "^1.0.0" 2164 | is-extglob "^1.0.0" 2165 | is-glob "^2.0.0" 2166 | 2167 | parse-json@^2.2.0: 2168 | version "2.2.0" 2169 | resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" 2170 | dependencies: 2171 | error-ex "^1.2.0" 2172 | 2173 | parse-json@^4.0.0: 2174 | version "4.0.0" 2175 | resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" 2176 | dependencies: 2177 | error-ex "^1.3.1" 2178 | json-parse-better-errors "^1.0.1" 2179 | 2180 | parse-ms@^0.1.0: 2181 | version "0.1.2" 2182 | resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-0.1.2.tgz#dd3fa25ed6c2efc7bdde12ad9b46c163aa29224e" 2183 | 2184 | parse-ms@^1.0.0: 2185 | version "1.0.1" 2186 | resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-1.0.1.tgz#56346d4749d78f23430ca0c713850aef91aa361d" 2187 | 2188 | parse5@^3.0.1: 2189 | version "3.0.3" 2190 | resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" 2191 | dependencies: 2192 | "@types/node" "*" 2193 | 2194 | path-exists@^2.0.0: 2195 | version "2.1.0" 2196 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" 2197 | dependencies: 2198 | pinkie-promise "^2.0.0" 2199 | 2200 | path-exists@^3.0.0: 2201 | version "3.0.0" 2202 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" 2203 | 2204 | path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: 2205 | version "1.0.1" 2206 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 2207 | 2208 | path-is-inside@^1.0.1: 2209 | version "1.0.2" 2210 | resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" 2211 | 2212 | path-key@^2.0.0: 2213 | version "2.0.1" 2214 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" 2215 | 2216 | path-type@^1.0.0: 2217 | version "1.1.0" 2218 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" 2219 | dependencies: 2220 | graceful-fs "^4.1.2" 2221 | pify "^2.0.0" 2222 | pinkie-promise "^2.0.0" 2223 | 2224 | path-type@^2.0.0: 2225 | version "2.0.0" 2226 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" 2227 | dependencies: 2228 | pify "^2.0.0" 2229 | 2230 | pify@^2.0.0: 2231 | version "2.3.0" 2232 | resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" 2233 | 2234 | pify@^3.0.0: 2235 | version "3.0.0" 2236 | resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" 2237 | 2238 | pinkie-promise@^1.0.0: 2239 | version "1.0.0" 2240 | resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-1.0.0.tgz#d1da67f5482563bb7cf57f286ae2822ecfbf3670" 2241 | dependencies: 2242 | pinkie "^1.0.0" 2243 | 2244 | pinkie-promise@^2.0.0: 2245 | version "2.0.1" 2246 | resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" 2247 | dependencies: 2248 | pinkie "^2.0.0" 2249 | 2250 | pinkie@^1.0.0: 2251 | version "1.0.0" 2252 | resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-1.0.0.tgz#5a47f28ba1015d0201bda7bf0f358e47bec8c7e4" 2253 | 2254 | pinkie@^2.0.0: 2255 | version "2.0.4" 2256 | resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" 2257 | 2258 | pkg-conf@^2.0.0: 2259 | version "2.1.0" 2260 | resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-2.1.0.tgz#2126514ca6f2abfebd168596df18ba57867f0058" 2261 | dependencies: 2262 | find-up "^2.0.0" 2263 | load-json-file "^4.0.0" 2264 | 2265 | pkg-dir@^2.0.0: 2266 | version "2.0.0" 2267 | resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" 2268 | dependencies: 2269 | find-up "^2.1.0" 2270 | 2271 | plur@^2.0.0: 2272 | version "2.1.2" 2273 | resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" 2274 | dependencies: 2275 | irregular-plurals "^1.0.0" 2276 | 2277 | prepend-http@^1.0.1: 2278 | version "1.0.4" 2279 | resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" 2280 | 2281 | prepend-http@^2.0.0: 2282 | version "2.0.0" 2283 | resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" 2284 | 2285 | preserve@^0.2.0: 2286 | version "0.2.0" 2287 | resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" 2288 | 2289 | pretty-ms@^0.2.1: 2290 | version "0.2.2" 2291 | resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-0.2.2.tgz#da879a682ff33a37011046f13d627f67c73b84f6" 2292 | dependencies: 2293 | parse-ms "^0.1.0" 2294 | 2295 | pretty-ms@^3.0.0: 2296 | version "3.2.0" 2297 | resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-3.2.0.tgz#87a8feaf27fc18414d75441467d411d6e6098a25" 2298 | dependencies: 2299 | parse-ms "^1.0.0" 2300 | 2301 | private@^0.1.8: 2302 | version "0.1.8" 2303 | resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" 2304 | 2305 | process-nextick-args@~2.0.0: 2306 | version "2.0.0" 2307 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" 2308 | 2309 | pseudomap@^1.0.2: 2310 | version "1.0.2" 2311 | resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" 2312 | 2313 | query-string@^5.0.1: 2314 | version "5.1.1" 2315 | resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" 2316 | dependencies: 2317 | decode-uri-component "^0.2.0" 2318 | object-assign "^4.1.0" 2319 | strict-uri-encode "^1.0.0" 2320 | 2321 | randomatic@^3.0.0: 2322 | version "3.0.0" 2323 | resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.0.0.tgz#d35490030eb4f7578de292ce6dfb04a91a128923" 2324 | dependencies: 2325 | is-number "^4.0.0" 2326 | kind-of "^6.0.0" 2327 | math-random "^1.0.1" 2328 | 2329 | rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: 2330 | version "1.2.8" 2331 | resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" 2332 | dependencies: 2333 | deep-extend "^0.6.0" 2334 | ini "~1.3.0" 2335 | minimist "^1.2.0" 2336 | strip-json-comments "~2.0.1" 2337 | 2338 | read-pkg-up@^1.0.1: 2339 | version "1.0.1" 2340 | resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" 2341 | dependencies: 2342 | find-up "^1.0.0" 2343 | read-pkg "^1.0.0" 2344 | 2345 | read-pkg-up@^2.0.0: 2346 | version "2.0.0" 2347 | resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" 2348 | dependencies: 2349 | find-up "^2.0.0" 2350 | read-pkg "^2.0.0" 2351 | 2352 | read-pkg@^1.0.0: 2353 | version "1.1.0" 2354 | resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" 2355 | dependencies: 2356 | load-json-file "^1.0.0" 2357 | normalize-package-data "^2.3.2" 2358 | path-type "^1.0.0" 2359 | 2360 | read-pkg@^2.0.0: 2361 | version "2.0.0" 2362 | resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" 2363 | dependencies: 2364 | load-json-file "^2.0.0" 2365 | normalize-package-data "^2.3.2" 2366 | path-type "^2.0.0" 2367 | 2368 | readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5: 2369 | version "2.3.6" 2370 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" 2371 | dependencies: 2372 | core-util-is "~1.0.0" 2373 | inherits "~2.0.3" 2374 | isarray "~1.0.0" 2375 | process-nextick-args "~2.0.0" 2376 | safe-buffer "~5.1.1" 2377 | string_decoder "~1.1.1" 2378 | util-deprecate "~1.0.1" 2379 | 2380 | readdirp@^2.0.0: 2381 | version "2.1.0" 2382 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" 2383 | dependencies: 2384 | graceful-fs "^4.1.2" 2385 | minimatch "^3.0.2" 2386 | readable-stream "^2.0.2" 2387 | set-immediate-shim "^1.0.1" 2388 | 2389 | redent@^1.0.0: 2390 | version "1.0.0" 2391 | resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" 2392 | dependencies: 2393 | indent-string "^2.1.0" 2394 | strip-indent "^1.0.1" 2395 | 2396 | regenerate@^1.2.1: 2397 | version "1.4.0" 2398 | resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" 2399 | 2400 | regenerator-runtime@^0.11.0: 2401 | version "0.11.1" 2402 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" 2403 | 2404 | regex-cache@^0.4.2: 2405 | version "0.4.4" 2406 | resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" 2407 | dependencies: 2408 | is-equal-shallow "^0.1.3" 2409 | 2410 | regexpu-core@^2.0.0: 2411 | version "2.0.0" 2412 | resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" 2413 | dependencies: 2414 | regenerate "^1.2.1" 2415 | regjsgen "^0.2.0" 2416 | regjsparser "^0.1.4" 2417 | 2418 | registry-auth-token@^3.0.1: 2419 | version "3.3.2" 2420 | resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" 2421 | dependencies: 2422 | rc "^1.1.6" 2423 | safe-buffer "^5.0.1" 2424 | 2425 | registry-url@^3.0.3: 2426 | version "3.1.0" 2427 | resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" 2428 | dependencies: 2429 | rc "^1.0.1" 2430 | 2431 | regjsgen@^0.2.0: 2432 | version "0.2.0" 2433 | resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" 2434 | 2435 | regjsparser@^0.1.4: 2436 | version "0.1.5" 2437 | resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" 2438 | dependencies: 2439 | jsesc "~0.5.0" 2440 | 2441 | release-zalgo@^1.0.0: 2442 | version "1.0.0" 2443 | resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" 2444 | dependencies: 2445 | es6-error "^4.0.1" 2446 | 2447 | remove-trailing-separator@^1.0.1: 2448 | version "1.1.0" 2449 | resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" 2450 | 2451 | repeat-element@^1.1.2: 2452 | version "1.1.2" 2453 | resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" 2454 | 2455 | repeat-string@^1.5.2: 2456 | version "1.6.1" 2457 | resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" 2458 | 2459 | repeating@^2.0.0: 2460 | version "2.0.1" 2461 | resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" 2462 | dependencies: 2463 | is-finite "^1.0.0" 2464 | 2465 | require-precompiled@^0.1.0: 2466 | version "0.1.0" 2467 | resolved "https://registry.yarnpkg.com/require-precompiled/-/require-precompiled-0.1.0.tgz#5a1b52eb70ebed43eb982e974c85ab59571e56fa" 2468 | 2469 | resolve-cwd@^2.0.0: 2470 | version "2.0.0" 2471 | resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" 2472 | dependencies: 2473 | resolve-from "^3.0.0" 2474 | 2475 | resolve-from@^3.0.0: 2476 | version "3.0.0" 2477 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" 2478 | 2479 | resolve-url@^0.2.1: 2480 | version "0.2.1" 2481 | resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" 2482 | 2483 | responselike@1.0.2: 2484 | version "1.0.2" 2485 | resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" 2486 | dependencies: 2487 | lowercase-keys "^1.0.0" 2488 | 2489 | restore-cursor@^2.0.0: 2490 | version "2.0.0" 2491 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" 2492 | dependencies: 2493 | onetime "^2.0.0" 2494 | signal-exit "^3.0.2" 2495 | 2496 | rimraf@^2.6.1: 2497 | version "2.6.2" 2498 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" 2499 | dependencies: 2500 | glob "^7.0.5" 2501 | 2502 | rootpath@^0.1.2: 2503 | version "0.1.2" 2504 | resolved "https://registry.yarnpkg.com/rootpath/-/rootpath-0.1.2.tgz#5b379a87dca906e9b91d690a599439bef267ea6b" 2505 | 2506 | safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: 2507 | version "5.1.2" 2508 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 2509 | 2510 | "safer-buffer@>= 2.1.2 < 3": 2511 | version "2.1.2" 2512 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 2513 | 2514 | sax@^1.2.4: 2515 | version "1.2.4" 2516 | resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" 2517 | 2518 | semver-diff@^2.0.0: 2519 | version "2.1.0" 2520 | resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" 2521 | dependencies: 2522 | semver "^5.0.3" 2523 | 2524 | "semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1: 2525 | version "5.5.0" 2526 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" 2527 | 2528 | serialize-error@^2.1.0: 2529 | version "2.1.0" 2530 | resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-2.1.0.tgz#50b679d5635cdf84667bdc8e59af4e5b81d5f60a" 2531 | 2532 | set-blocking@~2.0.0: 2533 | version "2.0.0" 2534 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 2535 | 2536 | set-immediate-shim@^1.0.1: 2537 | version "1.0.1" 2538 | resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" 2539 | 2540 | shebang-command@^1.2.0: 2541 | version "1.2.0" 2542 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" 2543 | dependencies: 2544 | shebang-regex "^1.0.0" 2545 | 2546 | shebang-regex@^1.0.0: 2547 | version "1.0.0" 2548 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" 2549 | 2550 | signal-exit@^3.0.0, signal-exit@^3.0.2: 2551 | version "3.0.2" 2552 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" 2553 | 2554 | slash@^1.0.0: 2555 | version "1.0.0" 2556 | resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" 2557 | 2558 | slice-ansi@^1.0.0: 2559 | version "1.0.0" 2560 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" 2561 | dependencies: 2562 | is-fullwidth-code-point "^2.0.0" 2563 | 2564 | slide@^1.1.5: 2565 | version "1.1.6" 2566 | resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" 2567 | 2568 | sort-keys@^2.0.0: 2569 | version "2.0.0" 2570 | resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" 2571 | dependencies: 2572 | is-plain-obj "^1.0.0" 2573 | 2574 | source-map-resolve@^0.5.1: 2575 | version "0.5.2" 2576 | resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" 2577 | dependencies: 2578 | atob "^2.1.1" 2579 | decode-uri-component "^0.2.0" 2580 | resolve-url "^0.2.1" 2581 | source-map-url "^0.4.0" 2582 | urix "^0.1.0" 2583 | 2584 | source-map-support@^0.4.15: 2585 | version "0.4.18" 2586 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" 2587 | dependencies: 2588 | source-map "^0.5.6" 2589 | 2590 | source-map-support@^0.5.0: 2591 | version "0.5.6" 2592 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.6.tgz#4435cee46b1aab62b8e8610ce60f788091c51c13" 2593 | dependencies: 2594 | buffer-from "^1.0.0" 2595 | source-map "^0.6.0" 2596 | 2597 | source-map-url@^0.4.0: 2598 | version "0.4.0" 2599 | resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" 2600 | 2601 | source-map@^0.1.38: 2602 | version "0.1.43" 2603 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" 2604 | dependencies: 2605 | amdefine ">=0.0.4" 2606 | 2607 | source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: 2608 | version "0.5.7" 2609 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" 2610 | 2611 | source-map@^0.6.0: 2612 | version "0.6.1" 2613 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 2614 | 2615 | spdx-correct@^3.0.0: 2616 | version "3.0.0" 2617 | resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82" 2618 | dependencies: 2619 | spdx-expression-parse "^3.0.0" 2620 | spdx-license-ids "^3.0.0" 2621 | 2622 | spdx-exceptions@^2.1.0: 2623 | version "2.1.0" 2624 | resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9" 2625 | 2626 | spdx-expression-parse@^3.0.0: 2627 | version "3.0.0" 2628 | resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" 2629 | dependencies: 2630 | spdx-exceptions "^2.1.0" 2631 | spdx-license-ids "^3.0.0" 2632 | 2633 | spdx-license-ids@^3.0.0: 2634 | version "3.0.0" 2635 | resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87" 2636 | 2637 | sprintf-js@~1.0.2: 2638 | version "1.0.3" 2639 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 2640 | 2641 | stack-utils@^1.0.1: 2642 | version "1.0.1" 2643 | resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" 2644 | 2645 | strict-uri-encode@^1.0.0: 2646 | version "1.1.0" 2647 | resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" 2648 | 2649 | string-width@^1.0.1: 2650 | version "1.0.2" 2651 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" 2652 | dependencies: 2653 | code-point-at "^1.0.0" 2654 | is-fullwidth-code-point "^1.0.0" 2655 | strip-ansi "^3.0.0" 2656 | 2657 | "string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: 2658 | version "2.1.1" 2659 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" 2660 | dependencies: 2661 | is-fullwidth-code-point "^2.0.0" 2662 | strip-ansi "^4.0.0" 2663 | 2664 | string_decoder@~1.1.1: 2665 | version "1.1.1" 2666 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 2667 | dependencies: 2668 | safe-buffer "~5.1.0" 2669 | 2670 | strip-ansi@^3.0.0, strip-ansi@^3.0.1: 2671 | version "3.0.1" 2672 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 2673 | dependencies: 2674 | ansi-regex "^2.0.0" 2675 | 2676 | strip-ansi@^4.0.0: 2677 | version "4.0.0" 2678 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" 2679 | dependencies: 2680 | ansi-regex "^3.0.0" 2681 | 2682 | strip-ansi@~0.1.0: 2683 | version "0.1.1" 2684 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" 2685 | 2686 | strip-bom-buf@^1.0.0: 2687 | version "1.0.0" 2688 | resolved "https://registry.yarnpkg.com/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz#1cb45aaf57530f4caf86c7f75179d2c9a51dd572" 2689 | dependencies: 2690 | is-utf8 "^0.2.1" 2691 | 2692 | strip-bom@^2.0.0: 2693 | version "2.0.0" 2694 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" 2695 | dependencies: 2696 | is-utf8 "^0.2.0" 2697 | 2698 | strip-bom@^3.0.0: 2699 | version "3.0.0" 2700 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" 2701 | 2702 | strip-eof@^1.0.0: 2703 | version "1.0.0" 2704 | resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" 2705 | 2706 | strip-indent@^1.0.1: 2707 | version "1.0.1" 2708 | resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" 2709 | dependencies: 2710 | get-stdin "^4.0.1" 2711 | 2712 | strip-json-comments@~2.0.1: 2713 | version "2.0.1" 2714 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 2715 | 2716 | supertap@^1.0.0: 2717 | version "1.0.0" 2718 | resolved "https://registry.yarnpkg.com/supertap/-/supertap-1.0.0.tgz#bd9751c7fafd68c68cf8222a29892206a119fa9e" 2719 | dependencies: 2720 | arrify "^1.0.1" 2721 | indent-string "^3.2.0" 2722 | js-yaml "^3.10.0" 2723 | serialize-error "^2.1.0" 2724 | strip-ansi "^4.0.0" 2725 | 2726 | supports-color@^2.0.0: 2727 | version "2.0.0" 2728 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 2729 | 2730 | supports-color@^5.0.0, supports-color@^5.3.0: 2731 | version "5.4.0" 2732 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" 2733 | dependencies: 2734 | has-flag "^3.0.0" 2735 | 2736 | symbol-observable@^0.2.2: 2737 | version "0.2.4" 2738 | resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" 2739 | 2740 | symbol-observable@^1.0.4, symbol-observable@^1.1.0: 2741 | version "1.2.0" 2742 | resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" 2743 | 2744 | tar@^4: 2745 | version "4.4.4" 2746 | resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.4.tgz#ec8409fae9f665a4355cc3b4087d0820232bb8cd" 2747 | dependencies: 2748 | chownr "^1.0.1" 2749 | fs-minipass "^1.2.5" 2750 | minipass "^2.3.3" 2751 | minizlib "^1.1.0" 2752 | mkdirp "^0.5.0" 2753 | safe-buffer "^5.1.2" 2754 | yallist "^3.0.2" 2755 | 2756 | term-size@^1.2.0: 2757 | version "1.2.0" 2758 | resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" 2759 | dependencies: 2760 | execa "^0.7.0" 2761 | 2762 | text-table@^0.2.0: 2763 | version "0.2.0" 2764 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 2765 | 2766 | through2@^2.0.0: 2767 | version "2.0.3" 2768 | resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" 2769 | dependencies: 2770 | readable-stream "^2.1.5" 2771 | xtend "~4.0.1" 2772 | 2773 | time-zone@^1.0.0: 2774 | version "1.0.0" 2775 | resolved "https://registry.yarnpkg.com/time-zone/-/time-zone-1.0.0.tgz#99c5bf55958966af6d06d83bdf3800dc82faec5d" 2776 | 2777 | timed-out@^4.0.0, timed-out@^4.0.1: 2778 | version "4.0.1" 2779 | resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" 2780 | 2781 | to-fast-properties@^1.0.3: 2782 | version "1.0.3" 2783 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" 2784 | 2785 | trim-newlines@^1.0.0: 2786 | version "1.0.0" 2787 | resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" 2788 | 2789 | trim-off-newlines@^1.0.1: 2790 | version "1.0.1" 2791 | resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" 2792 | 2793 | trim-right@^1.0.1: 2794 | version "1.0.1" 2795 | resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" 2796 | 2797 | uid2@0.0.3: 2798 | version "0.0.3" 2799 | resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" 2800 | 2801 | unique-string@^1.0.0: 2802 | version "1.0.0" 2803 | resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" 2804 | dependencies: 2805 | crypto-random-string "^1.0.0" 2806 | 2807 | unique-temp-dir@^1.0.0: 2808 | version "1.0.0" 2809 | resolved "https://registry.yarnpkg.com/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz#6dce95b2681ca003eebfb304a415f9cbabcc5385" 2810 | dependencies: 2811 | mkdirp "^0.5.1" 2812 | os-tmpdir "^1.0.1" 2813 | uid2 "0.0.3" 2814 | 2815 | universalify@^0.1.0: 2816 | version "0.1.1" 2817 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" 2818 | 2819 | unzip-response@^2.0.1: 2820 | version "2.0.1" 2821 | resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" 2822 | 2823 | update-notifier@^2.3.0: 2824 | version "2.5.0" 2825 | resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" 2826 | dependencies: 2827 | boxen "^1.2.1" 2828 | chalk "^2.0.1" 2829 | configstore "^3.0.0" 2830 | import-lazy "^2.1.0" 2831 | is-ci "^1.0.10" 2832 | is-installed-globally "^0.1.0" 2833 | is-npm "^1.0.0" 2834 | latest-version "^3.0.0" 2835 | semver-diff "^2.0.0" 2836 | xdg-basedir "^3.0.0" 2837 | 2838 | urix@^0.1.0: 2839 | version "0.1.0" 2840 | resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" 2841 | 2842 | url-parse-lax@^1.0.0: 2843 | version "1.0.0" 2844 | resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" 2845 | dependencies: 2846 | prepend-http "^1.0.1" 2847 | 2848 | url-parse-lax@^3.0.0: 2849 | version "3.0.0" 2850 | resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" 2851 | dependencies: 2852 | prepend-http "^2.0.0" 2853 | 2854 | url-to-options@^1.0.1: 2855 | version "1.0.1" 2856 | resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" 2857 | 2858 | util-deprecate@~1.0.1: 2859 | version "1.0.2" 2860 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 2861 | 2862 | validate-npm-package-license@^3.0.1: 2863 | version "3.0.3" 2864 | resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz#81643bcbef1bdfecd4623793dc4648948ba98338" 2865 | dependencies: 2866 | spdx-correct "^3.0.0" 2867 | spdx-expression-parse "^3.0.0" 2868 | 2869 | well-known-symbols@^1.0.0: 2870 | version "1.0.0" 2871 | resolved "https://registry.yarnpkg.com/well-known-symbols/-/well-known-symbols-1.0.0.tgz#73c78ae81a7726a8fa598e2880801c8b16225518" 2872 | 2873 | which@^1.2.9: 2874 | version "1.3.1" 2875 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" 2876 | dependencies: 2877 | isexe "^2.0.0" 2878 | 2879 | wide-align@^1.1.0: 2880 | version "1.1.3" 2881 | resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" 2882 | dependencies: 2883 | string-width "^1.0.2 || 2" 2884 | 2885 | widest-line@^2.0.0: 2886 | version "2.0.0" 2887 | resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.0.tgz#0142a4e8a243f8882c0233aa0e0281aa76152273" 2888 | dependencies: 2889 | string-width "^2.1.1" 2890 | 2891 | wrap-ansi@^2.0.0: 2892 | version "2.1.0" 2893 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" 2894 | dependencies: 2895 | string-width "^1.0.1" 2896 | strip-ansi "^3.0.1" 2897 | 2898 | wrappy@1: 2899 | version "1.0.2" 2900 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 2901 | 2902 | write-file-atomic@^1.1.4: 2903 | version "1.3.4" 2904 | resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" 2905 | dependencies: 2906 | graceful-fs "^4.1.11" 2907 | imurmurhash "^0.1.4" 2908 | slide "^1.1.5" 2909 | 2910 | write-file-atomic@^2.0.0: 2911 | version "2.3.0" 2912 | resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" 2913 | dependencies: 2914 | graceful-fs "^4.1.11" 2915 | imurmurhash "^0.1.4" 2916 | signal-exit "^3.0.2" 2917 | 2918 | write-json-file@^2.2.0: 2919 | version "2.3.0" 2920 | resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f" 2921 | dependencies: 2922 | detect-indent "^5.0.0" 2923 | graceful-fs "^4.1.2" 2924 | make-dir "^1.0.0" 2925 | pify "^3.0.0" 2926 | sort-keys "^2.0.0" 2927 | write-file-atomic "^2.0.0" 2928 | 2929 | write-pkg@^3.1.0: 2930 | version "3.1.0" 2931 | resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-3.1.0.tgz#030a9994cc9993d25b4e75a9f1a1923607291ce9" 2932 | dependencies: 2933 | sort-keys "^2.0.0" 2934 | write-json-file "^2.2.0" 2935 | 2936 | xdg-basedir@^3.0.0: 2937 | version "3.0.0" 2938 | resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" 2939 | 2940 | xtend@^4.0.0, xtend@~4.0.1: 2941 | version "4.0.1" 2942 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" 2943 | 2944 | yallist@^2.1.2: 2945 | version "2.1.2" 2946 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" 2947 | 2948 | yallist@^3.0.0, yallist@^3.0.2: 2949 | version "3.0.2" 2950 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" 2951 | --------------------------------------------------------------------------------