]> BookStack Code Mirror - website/commitdiff
Merge branch 'patch-2' of git://github.com/Zenahr/website into Zenahr-patch-2
authorDan Brown <redacted>
Sat, 23 Jan 2021 22:04:47 +0000 (22:04 +0000)
committerDan Brown <redacted>
Sat, 23 Jan 2021 22:04:47 +0000 (22:04 +0000)
82 files changed:
LICENSE
config.toml
content/blog/1-year-of-bookstack.md
content/blog/100-stars-on-github.md
content/blog/5-years-of-bookstack.md [new file with mode: 0644]
content/blog/beta-bugfix-release-v0-11-1.md
content/blog/beta-bugfix-release-v0-12-1.md
content/blog/beta-bugfix-release-v0-12-2.md
content/blog/beta-bugfix-release-v0-13-1.md
content/blog/beta-release-v0-10-0.md
content/blog/beta-release-v0-11-0.md
content/blog/beta-release-v0-12-0.md
content/blog/beta-release-v0-13-0.md
content/blog/beta-release-v0-25-5.md
content/blog/beta-release-v0-30-0.md [new file with mode: 0644]
content/blog/beta-release-v0-31-0.md [new file with mode: 0644]
content/blog/beta-release-v0-7-6.md
content/blog/beta-release-v0-8-0.md
content/blog/beta-release-v0-8-2.md
content/blog/beta-security-release-v0-30-4.md [new file with mode: 0644]
content/blog/beta-security-release-v0-30-5.md [new file with mode: 0644]
content/blog/beta-security-release-v0-30-6.md [new file with mode: 0644]
content/blog/beta-security-release-v0-30-7.md [new file with mode: 0644]
content/blog/beta-security-release-v0-31-4.md [new file with mode: 0644]
content/blog/replacing-ga-and-mailchimp.md [new file with mode: 0644]
content/docs/admin/installation.md
content/docs/admin/ldap-auth.md
content/docs/admin/security.md
content/docs/admin/third-party-auth.md
content/docs/admin/updates.md
content/docs/admin/upload-config.md
content/docs/admin/visual-customisation.md
content/docs/user/content-overview.md
gulpfile.js [deleted file]
package-lock.json
package.json
readme.md
static/images/2017/01/bookstack-includes-popover.webm
static/images/2020/07/bookstack_website_2016_2020.png [new file with mode: 0644]
static/images/2020/09/api_chapters.png [new file with mode: 0644]
static/images/2020/09/attachment_link_insert.png [new file with mode: 0644]
static/images/2020/09/bookstack_audit_log.png [new file with mode: 0644]
static/images/2020/09/code_block_session_saving.png [new file with mode: 0644]
static/images/2021/01/audit_log_updates.png [new file with mode: 0644]
static/images/2021/01/changes_view.png [new file with mode: 0644]
static/images/2021/01/mailbag.png [new file with mode: 0644]
static/images/2021/01/mailchimp_tracked_links.png [new file with mode: 0644]
static/images/2021/01/ownership_change.png [new file with mode: 0644]
static/images/2021/01/pages_api.png [new file with mode: 0644]
static/images/2021/01/plausible_bookstack_site_analytics.png [new file with mode: 0644]
static/images/2021/01/recycle_bin.png [new file with mode: 0644]
static/images/2021/01/recycle_bin_maintenance.png [new file with mode: 0644]
static/images/2021/01/user_list_activity.png [new file with mode: 0644]
static/images/blog-cover-images/gate-masaaki-komori.jpg [new file with mode: 0644]
static/images/blog-cover-images/library-priscilla-du-preez.jpg [new file with mode: 0644]
static/images/blog-cover-images/lock-aubrey-odom.jpg [new file with mode: 0644]
static/images/blog-cover-images/lock-door-waldemar-brandt.jpg [new file with mode: 0644]
static/images/blog-cover-images/lock-jon-moore.jpg [new file with mode: 0644]
static/images/blog-cover-images/locks-marcos-mayer.jpg [new file with mode: 0644]
static/images/blog-cover-images/mountains-jerry-zhang.jpg [new file with mode: 0644]
static/images/blog-cover-images/penguin-steffen-triekel.jpg [new file with mode: 0644]
static/images/blog-cover-images/winter-fox-birger-strahl.jpg [new file with mode: 0644]
static/images/dan.jpg
themes/bookstack/archetypes/default.md
themes/bookstack/layouts/blog/single.html
themes/bookstack/layouts/index.html
themes/bookstack/layouts/partials/footer.html
themes/bookstack/layouts/partials/header.html
themes/bookstack/layouts/partials/icon/logo.svg
themes/bookstack/layouts/partials/mailchimp.html [deleted file]
themes/bookstack/layouts/partials/signup.html [new file with mode: 0644]
themes/bookstack/sass/_blog.scss
themes/bookstack/sass/_buttons.scss
themes/bookstack/sass/_code.scss [new file with mode: 0644]
themes/bookstack/sass/_grid.scss
themes/bookstack/sass/_html.scss
themes/bookstack/sass/_text.scss
themes/bookstack/sass/_variables.scss
themes/bookstack/sass/styles.scss
themes/bookstack/static/js/script.js
themes/bookstack/static/libs/codemirror/modes.js
themes/bookstack/static/libs/photoswipe.min.js

diff --git a/LICENSE b/LICENSE
index d2395ec7faf7a5cf85f7044ba110e784372fad29..ddbe4c907b46a2e77e80ae1ebe329ba9a742dbac 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2017 Dan Brown
+Copyright (c) 2020 Dan Brown
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
index ec398298cfd47b4d0eb43eaf12459c88b35becd0..c1489d1fd4d90a33d69a6feea20272f4d4721550 100644 (file)
@@ -1,8 +1,9 @@
 languageCode = "en-gb"
 title = "BookStack"
-baseurl = "https://bookstackapp.com/"
+baseurl = "https://www.bookstackapp.com/"
 theme="bookstack"
 enableGitInfo=true
+paginate=50
 
 [markup]
   defaultMarkdownHandler = "goldmark"
@@ -10,10 +11,21 @@ enableGitInfo=true
     [markup.goldmark.renderer]
       unsafe = true
       xHTML = true
+  [markup.highlight]
+    anchorLineNos = true
+    codeFences = true
+    guessSyntax = true
+    hl_Lines = ""
+    lineAnchors = ""
+    lineNoStart = 1
+    lineNos = false
+    lineNumbersInTable = false
+    noClasses = false
+    style = "vs"
+    tabWidth = 4
 
 [permalinks]
   post = "/blog/:slug/"
 
 [params]
   blogCover = "/images/cover.jpg"
-  googleAnalyticsUserID = "UA-61486258-4"
index dd564c153aefb3f669f14789bc54003a74ae0030..0d6e1c99f185088495cb9108b142415926fba19a 100644 (file)
@@ -11,7 +11,7 @@ date = 2016-07-11T15:37:51Z
 
 +++
 
-BookStack is now 1 year old! The first commit can be found on [GitHub here](https://github.com/ssddanbrown/BookStack/commit/eaa1765c7a68cd671bcb37a666203210bf05d217). BookStack also now has over 200 stars GitHub stars! It's absolutely awesome to see BookStack grow into something worked on and shaped by a community.
+BookStack is now 1 year old! The first commit can be found on [GitHub here](https://github.com/BookStackApp/BookStack/commit/eaa1765c7a68cd671bcb37a666203210bf05d217). BookStack also now has over 200 stars GitHub stars! It's absolutely awesome to see BookStack grow into something worked on and shaped by a community.
 
 ## Back in Time
 
@@ -64,4 +64,4 @@ Traffic to the website has steadily grown since the [100 stars](https://www.book
 
 ## Moving Forwards
 
-I'd like to re-focus on getting through more of the outstanding issues on GitHub soon since they are starting to build up. I'd also like to slowly prepare the project for becoming multilingual to reach more people. The official docs, https://www.bookstackapp.com/docs/, are still fairly weak (Especial for a documentation platform) so I'd like to focus on getting them up to standard and I'm still eager to make a video to introduce newcomers to the project.
\ No newline at end of file
+I'd like to re-focus on getting through more of the outstanding issues on GitHub soon since they are starting to build up. I'd also like to slowly prepare the project for becoming multilingual to reach more people. The official docs, https://www.bookstackapp.com/docs/, are still fairly weak (Especial for a documentation platform) so I'd like to focus on getting them up to standard and I'm still eager to make a video to introduce newcomers to the project.
index 0d2693f3e1c474270afbb90aa5acd22abbaa0164..60247545a7f6df3fec2197da7024265083726196 100644 (file)
@@ -10,7 +10,7 @@ slug = "100-stars-on-github"
 
 +++
 
-BookStack now has [over 100 stars on GitHub](https://github.com/ssddanbrown/BookStack/stargazers)! It's a minor milestone but I'm very happy about it. Since July of last year I've put a fair amount of effort into the project and it's awesome to see other people find value in BookStack. 
+BookStack now has [over 100 stars on GitHub](https://github.com/BookStackApp/BookStack/stargazers)! It's a minor milestone but I'm very happy about it. Since July of last year I've put a fair amount of effort into the project and it's awesome to see other people find value in BookStack. 
 
 Most of those stars have come from my [initial posting on the Reddit](https://www.reddit.com/r/selfhosted/comments/3z06rb/bookstack_a_free_wikilike_information_store/) and a tweet about the project. These events can be seen in the site analytics:
 
@@ -25,4 +25,4 @@ The initial small spike is my Reddit post and the large middle spike is the twit
 
 I've recently added BookStack to [alternativeto.net](https://alternativeto.net/software/bookstack/) so people can find it when looking at similar systems like Confluence.
 
-I would really like to improve the BookStack documentation soon as it's very weak with the readme being the only source of information. Ideally I'd like the docs to be written in markdown in a git repo so I'm looking to get some kind of markdown import going into BookStack to accommodate this. Also, I'm looking to create some videos to give an overview of what BookStack is and the features it has.
\ No newline at end of file
+I would really like to improve the BookStack documentation soon as it's very weak with the readme being the only source of information. Ideally I'd like the docs to be written in markdown in a git repo so I'm looking to get some kind of markdown import going into BookStack to accommodate this. Also, I'm looking to create some videos to give an overview of what BookStack is and the features it has.
diff --git a/content/blog/5-years-of-bookstack.md b/content/blog/5-years-of-bookstack.md
new file mode 100644 (file)
index 0000000..ef83be6
--- /dev/null
@@ -0,0 +1,109 @@
++++
+categories = ["News"]
+tags = ["News"]
+title = "Five Years of BookStack"
+image = "/images/blog-cover-images/mountains-jerry-zhang.jpg"
+author = "Dan Brown"
+slug = "5-years-of-bookstack"
+draft = false
+date = 2020-07-28T23:00:00Z
+description = "At five years old we take a look at the numbers we've hit"
++++
+
+With a [first commit](https://github.com/BookStackApp/BookStack/commit/eaa1765c7a68cd671bcb37a666203210bf05d217) dated Sunday the 12th of July 2015, BookStack is now over 5 years old. Looking back, those 5 years have appeared to fly by but within that time there's been a lot of growth, both for me as a maintainer and in regards to the project itself. 
+
+For the 5th year anniversary I thought it would be interesting to collate some numbers to quantify the scale of the project while also sharing my experience of maintaining & managing the project.
+
+### BookStack, In Numbers
+
+At the time of writing *(28th July)*:
+
+#### GitHub Figures
+
+- [5,050 GitHub stars](https://github.com/BookStackApp/BookStack/stargazers)
+- [817 forks on GitHub](https://github.com/BookStackApp/BookStack/network/members)
+- 2,202 GitHub issues and PRs opened
+- 1,296 GitHub issues closed, 508 open
+- [90 releases published](https://github.com/BookStackApp/BookStack/releases)
+- 1,322 git clones in the last 14 days, 560 unique
+
+#### Code Repository Stats
+
+- [2,200 commits](https://github.com/BookStackApp/BookStack/commits/master)
+- 127 direct git contributors
+- 51,814 lines of code across 1112 files
+    - PHP 82.9%
+    - HTML 8.1%
+    - JavaScript 5.9%
+    - CSS 3.1%
+
+#### Social & Docker
+
+- [667 Discord members](https://discord.gg/ztkBqR2)
+- [144 Subreddit members](https://www.reddit.com/r/BookStack/)
+- [> 45,000,000 docker hub pulls](https://hub.docker.com/search?q=bookstack&type=image)
+
+#### Website Analytics
+
+Main bookstackapp.com site only, Averaged over last 90 days:
+
+- 431 unique users per day
+- 1,565 page views per day
+- Operating system breakdown:
+    - 49.17% Windows
+    - 20.55% Mac
+    - 12.31% Android
+    - 9.78%  Linux
+    - 7.72%  iOS
+
+Growth since January 2016:
+
+![BookStack site users over time](/images/2020/07/bookstack_website_2016_2020.png)
+
+#### CrowdIn (Project Translations) Numbers
+
+- 26 languages
+- 4243 words to translate
+- 64 project members
+
+#### Thoughts
+
+I've always kept an eye on GitHub stars, so its satisfying to hit the 5k mark at the same time as hitting 5 years. The GitHub stars have been slowly accelerating. The [first 1k](https://www.bookstackapp.com/blog/1k-stars-and-v0-19-0/) took about 2 years & 3 months to accrue, whereas we hit 4k only in February this year.
+
+For me, The two most surprising figures are the docker pulls and the discord member count. 45 million is just a staggering number of docker pulls to imagine. I know there's a massive amount of automation in that area leading to such an inflated figure but I still double take when seeing it.
+
+The discord user count gives me a warm fuzzy feeling; It's incredible that so many people have reached a level of admiration towards the project that they'd subscribe themselves, and remain in, a chat room purposed for it. I was nervous at first about needing to monitor an instant messaging social channel but it's definitely grown on me as an ideal place for informal project chat.
+
+
+### My Experience of the Last 5 Years
+
+Within the last 5 years I've bought my own house, adopted a cat, become a Tech Lead at work and discovered I have, and learnt to live with, a chronic arthritis-based disease. During this time BookStack has been a large part of my life, with many weekends and evenings dedicated to the project.
+
+For the most part, I'm really happy with the project and its growth. I absolutely love open source software and being part of something in that area is wonderful. Working on the project has forced me into many new areas of development & technology including LDAP, SAML, Web Accessibility and multi-language support (Including supporting right-to-left content). Accessibility has been my favorite topic so far since it was something I thought I knew but in reality was a subject I had little depth in. Learning how to make the platform more inclusive to those with disabilities has not only been mindfully rewarding but it has also been rewarding in skills and fundamental understandings I can utilize in my other work.
+
+The social aspect of managing something like BookStack has been quite a new experience for me. I'm not too much of a social person by default, so working out how to deal with the thoughts and opinions of a growing amount of people has been a challenge. The anonymisation and distance inferred by the web introduces a lot of unknowns to each issue & pull request that is addressed; In many cases you have no idea of the skill, experience, history or the intentions of the other party. Their idea of what the project is, or should be, may be completely different to my own. As time goes on I feel I'm getting better at knowing where to draw the scope for the project and how to be assertive in that scope. The hard part comes in the reasoning when you have to disappoint, It can be a tricky & time consuming task to apply the thought and write out the reasoning from the maintainer perspective, especially when an idea or request is popular so that perspective is very much the minority. A good example of this can be seen with [my thoughts for SQLite/PostgreSQL support here](https://github.com/BookStackApp/BookStack/issues/76#issuecomment-494956958).
+
+GitHub issues do seem to have a mental burden. I take a lax approach to closing off issues, since I prefer to leave things open to feedback & opinion even if I do not intend to include, which may not help but seeing that counter increase can yet remain worrisome. I think it's likely due knowing that each of those could potentially take a lot of time, some may take mere minutes but some can consume an evening or even weekend with little reward in return. I am very thankful to those that help out and to those that spend the time detailing or investigate the issue when posting. 
+
+There are two main principles I've learnt when it comes to GitHub issues & pull requests:
+
+1. Always be polite & thankful where possible. I always remind myself that these are people that are taking their own time to report an issue, or are passionate enough about the project to share their own opinion. In many cases it'll be someone's first interaction with GitHub or open source; The extra effort to make that a positive experience is likely well worth it.
+2. If my initial reaction to an idea or request is negative, Don't respond right away but come back to it in a day or two. With time often comes additional perspective and empathy which may change your alignment on the matter, or at least allow for a more constructive response.
+
+One thing I still find particularly tricky are pull requests. Once someone has put the time in to create something it becomes more awkward to reject or request fundamental changes. In addition, merge of a pull request can often force my focus to less interesting busy-work like documenting, implementation clean-up and test writing. That's not to say I'm not appreciative of people's efforts though, it's amazing that individuals are interested enough to contribute, it's just that I need to learn how to manage that process better.
+
+Over the next couple of years I'd like to attend a few open source events & conferences. It would be great to speak to others with similar projects to get some first-hand advice and learn to build up a community in a manageable way.
+
+### BookStack on YouTube
+
+As a positive addendum to this five year post, I've been seeing some great videos emerge on YouTube that cover how to install or configure BookStack in various cases. Here's a couple of examples:
+
+<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/NhPw1DvxYZc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
+
+<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/_13K1DeZwhk" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
+
+There are many other videos out there; I'm keeping track of any I find, that feature or mention the project, in this playlist: https://www.youtube.com/playlist?list=PLMI5XWgNpCyVjdIqx9oPoHl2y42Rph3Co
+
+---
+
+<span style="font-size: 0.8em;opacity:0.8;">Header Image Credits: &nbsp; <span>Photo by <a href="https://unsplash.com/@z734923105?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Jerry Zhang</a> on <a href="https://unsplash.com/s/photos/mountain?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span></span>
\ No newline at end of file
index 6d49e0fd4c792af0ca4fa20a0bbb0666b0bac324..23d9d6c1cccfbc4dc0b05e2ebcb50fac762f5acc 100644 (file)
@@ -22,7 +22,7 @@ A new BookStack bug-fix release has now been released to resolve a few issues fo
 Update instructions can be found in the links below. If you're having issues running the update commands you may have to run `composer dump-autoload` followed by `php artisan clear-compiled` from the root BookStack directory.
 
 * [Update instructions](https://www.bookstackapp.com/docs/admin/updates)
-* [GitHub release page](https://github.com/ssddanbrown/BookStack/releases/tag/v0.11.1)
+* [GitHub release page](https://github.com/BookStackApp/BookStack/releases/tag/v0.11.1)
 
 #### BookStack in a URL 'Sub-directory'
 
@@ -30,8 +30,8 @@ Due to the changes to links within BookStack the application can now be placed o
 
 Due to the many potentially sensitive application files & scripts within a BookStack instance's folder it should not be installed traditionally in an actual folder subdirectory of another website due to many security concerns. Instead the web server should proxy requests to a BookStack instance.
 
-This will be documented soon but if you're eager to set this up and you have some Nginx knowledge you can follow the posts on [the issue request](https://github.com/ssddanbrown/BookStack/issues/40#issuecomment-238538445) to get going.
+This will be documented soon but if you're eager to set this up and you have some Nginx knowledge you can follow the posts on [the issue request](https://github.com/BookStackApp/BookStack/issues/40#issuecomment-238538445) to get going.
 
 ----
 
-<span style="font-size: 0.8em;opacity:0.8;">Header Image Credits: <a href="https://unsplash.com/@michelbosma" target="_blank">Michel Bosma</a></span>
\ No newline at end of file
+<span style="font-size: 0.8em;opacity:0.8;">Header Image Credits: <a href="https://unsplash.com/@michelbosma" target="_blank">Michel Bosma</a></span>
index aee7ab0f5bd0d79f464371b55e92fa7ccee8d8d1..ed8f3a21adbe729cb43b3169ba1d428934d576f6 100644 (file)
@@ -14,7 +14,7 @@ slug = "beta-bugfix-release-v0-12-1"
 A new bugfix has been released to patch up a few issues found in v0.12.
 
 * [Update instructions](https://www.bookstackapp.com/docs/admin/updates)
-* [GitHub release page](https://github.com/ssddanbrown/BookStack/releases/tag/v0.12.1)
+* [GitHub release page](https://github.com/BookStackApp/BookStack/releases/tag/v0.12.1)
 
 It was found that I had accidentally set two shortcuts on the same keys, The draft quick save and inline-code format were both mapped to `ctrl+s`. This has now been updated so that inline code is mapped to `Ctrl+Shift+E`. Also, as part of this bugfix the WYSIWYG editor shortcuts on mac will use the command key instead of the ctrl key to better fit with other Mac shortcuts.
 
@@ -24,4 +24,4 @@ Tables have been updated to prevent words being sliced across lines in FireFox a
 
 ----
 
-<span style="font-size: 0.8em;opacity:0.8;">Header Image Credits: <a href="https://unsplash.com/@samdasherx13" target="_blank">Samuel Myles</a></span>
\ No newline at end of file
+<span style="font-size: 0.8em;opacity:0.8;">Header Image Credits: <a href="https://unsplash.com/@samdasherx13" target="_blank">Samuel Myles</a></span>
index 42d238fcf617c7d9aa6ecacf975f2ce4a79b8940..1102076e342857b37af9be08ce283a5d41a4d2a1 100644 (file)
@@ -14,7 +14,7 @@ description = ""
 A second bugfix release has been put together to patch up a some issues found in v0.12.1.
 
 * [Update instructions](https://www.bookstackapp.com/docs/admin/updates)
-* [GitHub release page](https://github.com/ssddanbrown/BookStack/releases/tag/v0.12.2)
+* [GitHub release page](https://github.com/BookStackApp/BookStack/releases/tag/v0.12.2)
 
 #### Fixes & Changes
 
@@ -28,4 +28,4 @@ A second bugfix release has been put together to patch up a some issues found in
 
 ----
 
-<span style="font-size: 0.8em;opacity:0.8;">Header Image Credits: <a href="https://unsplash.com/@santosh313" target="_blank">Santosh Maharjan</a></span>
\ No newline at end of file
+<span style="font-size: 0.8em;opacity:0.8;">Header Image Credits: <a href="https://unsplash.com/@santosh313" target="_blank">Santosh Maharjan</a></span>
index c4bd82fb7877bbc4df08c43b2e7dd3d2b88aa4e9..21c09887d99524441aa0fcfc027265d15dc486b6 100644 (file)
@@ -14,7 +14,7 @@ image = "/images/2016/11/jayden-yoon-bookstack-bugfix-v0-13-1.jpg"
 Due to some critical issues, A bugfix release has been released for BookStack v0.13.
 
 * [Update instructions](https://www.bookstackapp.com/docs/admin/updates)
-* [GitHub release page](https://github.com/ssddanbrown/BookStack/releases/tag/v0.13.1)
+* [GitHub release page](https://github.com/BookStackApp/BookStack/releases/tag/v0.13.1)
 
 #### Fixes & Changes
 
@@ -24,4 +24,4 @@ Due to some critical issues, A bugfix release has been released for BookStack v0
 
 ----
 
-<span style="font-size: 0.8em;opacity:0.8;">Header Image Credits: <a href="https://unsplash.com/@jaydenyoonzk" target="_blank">Jayden Yoon</a></span>
\ No newline at end of file
+<span style="font-size: 0.8em;opacity:0.8;">Header Image Credits: <a href="https://unsplash.com/@jaydenyoonzk" target="_blank">Jayden Yoon</a></span>
index 749c05b269f80adcd0c8b4fec8fea7f69bb23c6b..c46cfa4e6e67f0d2460653303547ed2625aba8ad 100644 (file)
@@ -13,12 +13,12 @@ tags = ["Releases"]
 It's been a short while since the last release *(43 days to be exact)* but BookStack v0.10 is finally here. Here are some handy links:
 
 * [Update instructions](https://www.bookstackapp.com/docs/admin/updates)
-* [GitHub release page](https://github.com/ssddanbrown/BookStack/releases/tag/v0.10.0)
-* [GitHub milestone](https://github.com/ssddanbrown/BookStack/issues?utf8=%E2%9C%93&q=milestone%3A%22BookStack+Beta+v0.10.0%22+)
+* [GitHub release page](https://github.com/BookStackApp/BookStack/releases/tag/v0.10.0)
+* [GitHub milestone](https://github.com/BookStackApp/BookStack/issues?utf8=%E2%9C%93&q=milestone%3A%22BookStack+Beta+v0.10.0%22+)
 * v0.9 Bugfixes:
-    - [v0.9.1](https://github.com/ssddanbrown/BookStack/releases/tag/v0.9.1)
-    - [v0.9.2](https://github.com/ssddanbrown/BookStack/releases/tag/v0.9.2)
-    - [v0.9.3](https://github.com/ssddanbrown/BookStack/releases/tag/v0.9.3)
+    - [v0.9.1](https://github.com/BookStackApp/BookStack/releases/tag/v0.9.1)
+    - [v0.9.2](https://github.com/BookStackApp/BookStack/releases/tag/v0.9.2)
+    - [v0.9.3](https://github.com/BookStackApp/BookStack/releases/tag/v0.9.3)
 
 Most of the development time for this release was spent implementing a tagging system and overhauling the permissions systems which, although mainly for internal purposes, brings some useful extra functionality.
 
@@ -64,4 +64,4 @@ There is now a new option in settings to allow custom HTML content to be inserte
 * Allowed sorting & searching on the users page.
 * Reworked the database migrations to only use simple non-app code to avoid future breakages.
 * Cleaned some of the settings layouts for better consistency and hid more links when you don't have permissions to click them.
-* Made user names as the bottom of entities linked to user profiles. 
\ No newline at end of file
+* Made user names as the bottom of entities linked to user profiles. 
index cdd0f93a33a3388d38c37cc5202e3054f3a58402..5584bd83bc69b5431b35990edb403715eeef83c2 100644 (file)
@@ -13,7 +13,7 @@ description = ""
 BookStack v0.11 has now been released. This version is a cleanup and bugfix release with a few new handy features to make nicer pages and to help organise books easier. Here are the useful links for this release:
 
 * [Update instructions](https://www.bookstackapp.com/docs/admin/updates)
-* [GitHub release page](https://github.com/ssddanbrown/BookStack/releases/tag/v0.11.0)
+* [GitHub release page](https://github.com/BookStackApp/BookStack/releases/tag/v0.11.0)
 
 #### Editor Updates
 ###### Callouts
@@ -58,4 +58,4 @@ By default popular books and chapters are shown otherwise you can search for a p
 * Fixed bug with new chapters having an incorrect initial list priority/ordering set.
 * Fixed page sidebar not reacting to window resize.
 * Fixed bug preventing images from being deleted.
-* Fixed activity list bug causing too many hidden activities.
\ No newline at end of file
+* Fixed activity list bug causing too many hidden activities.
index fb18d3640a5db76c8397fe022be4510e04a72c13..db04f0810111dbfabc742781a1948f053714bd2a 100644 (file)
@@ -14,7 +14,7 @@ slug = "beta-release-v0-12-0"
 BookStack v0.12.0 has now been released bringing a range of new features and bug fixes. Let's get to it:
 
 * [Update instructions](https://www.bookstackapp.com/docs/admin/updates)
-* [GitHub release page](https://github.com/ssddanbrown/BookStack/releases/tag/v0.12.0)
+* [GitHub release page](https://github.com/BookStackApp/BookStack/releases/tag/v0.12.0)
 
 ### Edit Summaries
 
@@ -65,4 +65,4 @@ Just want to note another little nice UI change, When a page draft is saved an i
 
 ----
 
-<span style="font-size: 0.8em;opacity:0.8;">Header Image Credits: <a href="https://unsplash.com/@videmusart" target="_blank">Syd Wachs</a></span>
\ No newline at end of file
+<span style="font-size: 0.8em;opacity:0.8;">Header Image Credits: <a href="https://unsplash.com/@videmusart" target="_blank">Syd Wachs</a></span>
index e9822006560d4ed6292b34eaa855b129d974682f..b5e2cc3cef042957869f9a0e6fae17e25dd32f65 100644 (file)
@@ -14,7 +14,7 @@ draft = false
 BookStack v0.13.0 has now been released. This release has taken a while but it did require some large under-the-hood updates and brings a few chunky features. Here are the update links:
 
 * [Update instructions](https://www.bookstackapp.com/docs/admin/updates)
-* [GitHub release page](https://github.com/ssddanbrown/BookStack/releases/tag/v0.13.0)
+* [GitHub release page](https://github.com/BookStackApp/BookStack/releases/tag/v0.13.0)
 
 **Please read the additional information** at the bottom of the update instructions page as there are some changes in v0.13 that will likely require some manual intervention due to new system requirements.
 
@@ -89,4 +89,4 @@ If you would like to keep updated on BookStack blog content you can sign up to t
 
 ----
 
-<span style="font-size: 0.8em;opacity:0.8;">Header Image Credits: <a href="https://unsplash.com/@kazuend" target="_blank">kazuend</a></span>
\ No newline at end of file
+<span style="font-size: 0.8em;opacity:0.8;">Header Image Credits: <a href="https://unsplash.com/@kazuend" target="_blank">kazuend</a></span>
index cfa328b97ae7a961d2660c071c4c6604e316b638..c78bcc0779e2c57b12cec4cd1f6af8f60de397b8 100644 (file)
@@ -34,7 +34,7 @@ Please consider that malicious exploitation of this vulnerability may have allow
 
 When enacting upon the above security issues I noticed that the processes for security concerns could be improved. Details of how to report a sensitive security issue can now be found in the [project readme](https://github.com/BookStackApp/BookStack/tree/master#security).
 
-For the purpose of notifying admins on security issues, A new mailing list has been created which you can [subscribe to here](http://eepurl.com/glIh8z). 
+For the purpose of notifying admins on security issues, A new mailing list has been created which you can [subscribe to here](https://updates.bookstackapp.com/signup/bookstack-security-updates). 
 
 ### Translations
 
diff --git a/content/blog/beta-release-v0-30-0.md b/content/blog/beta-release-v0-30-0.md
new file mode 100644 (file)
index 0000000..deb0837
--- /dev/null
@@ -0,0 +1,245 @@
++++
+categories = ["Releases"]
+tags = ["Releases"]
+title = "Beta Release v0.30.0"
+date = 2020-09-20T09:30:00Z
+author = "Dan Brown"
+image = "/images/blog-cover-images/library-priscilla-du-preez.jpg"
+description = "The v0.30 release introduces the audit log, adds chapters to the API, improves code editing and more"
+slug = "beta-release-v0-30-0"
+draft = false
++++
+
+Although intended to be a quick release cycle, v0.30 is now here 5 months after the last major release. Sketchy personal health, a poorly pet & a busy day-job workload, combined with constant working-from-home, have reduced the amount of time I could afford to spare working on the project but with normality somewhat returning I present BookStack v0.30 which includes an assortment of enhancements. 
+
+
+* [Update instructions](https://www.bookstackapp.com/docs/admin/updates)
+* [GitHub release page](https://github.com/BookStackApp/BookStack/releases/tag/v0.30.0)
+
+
+Before we get into the features, just a couple of important advisories:
+
+
+**Security Notice** - Possible Privilege Escalation
+
+Thanks to [@Defelo](https://github.com/BookStackApp/BookStack/issues/2105)
+it was advised that current privilege escalation situations are not made clear when applying role permissions.
+Any user with a "Manage app settings", "Manage users" or "Manage roles & role permissions" system permission 
+assigned to one of their roles could technically alter their own permissions to gain wider access.
+A clear advisory of these cases has been added in the UI in v0.30
+but admins are advised to review which users have these permissions with the above in mind.
+
+
+**LDAP & SAML Group Matching** - Potential Change
+
+Thanks to [@nem1989](https://github.com/BookStackApp/BookStack/issues/2032) it was found that 
+BookStack roles would be matched to LDAP/SAML groups based upon the role display name, which is expected,
+but only those roles with a matching "name" value would be considered for this matching. This "name" field was redundant, 
+and has now been removed, but it would store a cleaned version the first-set name of the role.
+All roles will now be considered before being matched on name which may mean that roles which did not sync before, 
+that would have been expected to based on their name, may now start to sync.
+
+
+### Audit Log
+
+User activity within BookStack is shown across various locations of the system but it's
+always shown to a limited length. Additionally, there are some activities that havn't been
+visible without database access such as item deletions.
+
+As of v0.30 you can now see an audit log interface if you have permission to both "Manage
+System Settings" and "Manage Users". This is an unfiltered list of the activities that are 
+currently logged to the database by BookStack. Here's how this looks:
+
+![BookStack Audit Log](/images/2020/09/bookstack_audit_log.png)
+
+In this interface you're able to set a date range for activities in addition to being able to filter by activity type.
+In future releases we'll look to track more activity types and bring them into this interface.
+
+### Code Block Editing Session History
+
+Many people use BookStack to display and store code snippets so the code block editor can be core to the workflow of 
+many users within the platform. Unfortunately, since the code block editor opened in a popup,
+it was fairly easy to lose changes by clicking the popup close button or by accidentally clicking
+outside the popup.
+
+In v0.30 we've added session history to the code block editor:
+
+![BookStack Code Block Code Session Saving](/images/2020/09/code_block_session_saving.png)
+
+Any event that causes the popup to close will now save a copy of the contents into the browser's session
+history. Within the editor you'll see a "Session History" link, if anything is in the store, with a dropdown
+of times showing when code was saved. Clicking one of those times will update the editor with the code saved
+at that time. Note, This store is temporary and intended for short-term recovery where needed; In most browsers
+this data will be cleared as soon as the browser tab is closed.
+
+
+### Attachment Link Insertion
+
+The process of inserting attachments into your page content has now been streamlined.
+A new link button found on the attachment list, when editing a page, allows you to 
+insert an attachment link, with the correct attachment name, into the page content with a single click.
+
+![BookStack Attachment Link Insert](/images/2020/09/attachment_link_insert.png)
+
+
+On FireFox, or any browser when using the MarkDown editor, you can also drag the attachment card directly 
+into your page content. Unfortunately chromium based browser's drag+drop handling, combined with the WYSIWYG editor's
+own event handling, proved too troublesome to implement this reliably for that environment.
+
+
+### API Update - Chapters
+
+Work continues on the API to bring us chapter endpoints in this release.
+As we have for Books, this includes endpoints for exporting to the same
+formats that we support via the standard UI.
+
+![BookStack API Chapters](/images/2020/09/api_chapters.png)
+
+Next up, we'll be looking to implement endpoints for pages.
+If you've played with the API I'd love to hear your feedback in this [GitHub issue](https://github.com/BookStackApp/BookStack/issues/1852).
+
+### Dark Mode Tweaks
+
+Since releasing dark mode in v0.29 we've had feedback regarding some choices
+made in addition to a good set of bugs being reported and fixed.
+
+When implementing dark mode I made the choice to use CSS filters to alter the saturation
+and brightness of imagery in the hopes it would make content sit within the theme better.
+After feedback I realise this was a bad decision; It's effectively altering core user-content
+which should remain in control of the user/editor. In addition, these filters could massively
+affect the legibility of screenshots and similar text-based imagery. Use of these filters on
+images has been removed in v0.30.
+
+### Removal of Vue.js
+
+I absolutely love Vue.js, I've been a heavy user of the library with it being my go-to JS framework
+since version 1.0 after jumping ship from Angular 1. Therefore I used it to drive some of the more
+dynamic elements of BookStack such as the image manager and attachments interface. Within BookStack, I 
+try to limit JS usage where possible, looking at native back-end solutions before jumping to JS solutions.
+For smaller dynamic tasks I've slowly built up small set of "components" written in fairly basic plain JS for tasks
+such as handling dropdowns and complex select menus. 
+
+The trouble with frameworks such as Vue is that they ideally need to own the DOM from the point they're attached to downwards. 
+That leads to friction with the little JS "components" we had elsewhere as they'd either need to be re-written as a
+Vue component or an adapter would need to be created to "wire" the component into Vue.
+
+As much as I love Vue, it wasn't really needed in BookStack and we were not really using the full power of the framework.
+In v0.30 I've converted the existing Vue usages to a combination of back-end driven logic and an extended form of the plain JS
+components we already had. The removal of Vue brings a small reduction in the initial JS bundle download size in addition
+to a greater reduction of code being ran on each page load, leading to a more responsive interface overall.
+
+As part of these changes I've also spent some time trying to document and standardise
+an approach for these plain JS components [which can be seen here](https://github.com/BookStackApp/BookStack/blob/9e11fc33fa6cf657b35af97a268210ec447c59a7/dev/docs/components.md). I'm slowly updating the older components
+in the system to conform to these changes.
+
+### Removal of Webpack
+
+Unlike Vue.js, I've never really liked Webpack due to the many hours I've wasted trying to integrate
+Webpack based build systems into existing projects. That said, I've always respected the Webpack project and
+it's developers for the developed ecosystem and the sheer amount Webpack is able to do.
+
+As of v0.30 we have removed Webpack from the development flow of BookStack. Instead we're now using
+SASS directly for CSS builds (Thanks [@timoschwarzer](https://github.com/BookStackApp/BookStack/pull/2166) for swapping
+this to the newer dart-sass during this release cycle) and using [esbuild](https://github.com/evanw/esbuild) for JS building & bundling. Our build systems 
+are all simply [npm scripts which can be seen here](https://github.com/BookStackApp/BookStack/blob/9e11fc33fa6cf657b35af97a268210ec447c59a7/package.json#L4-L9).
+
+In addition to a simpler setup, these changes bring some good performance improvements; As a rough example, These changes bring the development build time of both JS & CSS down from about 2.7 seconds to about 1.5 seconds on my development system.
+
+### Failed Access Logging
+
+Thanks to [@benrubson](https://github.com/BookStackApp/BookStack/pull/1881) it's now possible for failed login events
+to be logged. This will function for both the standard email & password login as well as LDAP logins.
+
+To enable this you simple need to define the `LOG_FAILED_LOGIN_MESSAGE` option in your `.env` file like so:
+
+```bash
+LOG_FAILED_LOGIN_MESSAGE="Failed login for %u"
+```
+
+The optional "%u" element of the message will be replaced with the username or email provided in the login attempt
+when the message is logged. By default messages will be logged via the php `error_log` function which, in most
+cases, will log to your webserver error log files.
+
+### Translations
+
+As always our terrific translating tribe continue to provide their awesome efforts as this release brings updates
+to the below languages by the following fantastic Crowdin & GitHub members:
+
+* Orenda (OREDNA) - *Bulgarian*
+* Marek Pavelka (marapavelka) - *Czech*
+* Venkinovec - *Czech*
+* Tommy Ku (tommyku) - *Japanese*, *Chinese Traditional*
+* Michał Bielejewski  (bielej) - *Polish*
+* jozefrebjak - *Slovak*
+* Ikhwan Koo (Ikhwan.Koo) - *Korean*
+* Whay (remkovdhoef) - *Dutch*
+* jc7115 - *Chinese Traditional*
+* 주서현 (seohyeon.joo) - *Korean*
+* nutsflag - *French*
+* Mykola Ronik (Mantikor) - *Ukrainian*
+* ReadySystems - *Arabic*
+* m0uch0 - *Spanish*
+* Rodrigo Saczuk Niz (rodrigoniz) - *Portuguese, Brazilian*
+* HFinch - *German*, *German Informal*
+* cipi1965 - *Italian*
+* brechtgijsens - *Dutch*
+* Emil Petersen (emoyly) - *Danish*
+* Leonardo Mario Martinez (leonardo.m.martinez) - *Spanish, Argentina*
+* Lowkey (v587ygq) - *Chinese Simplified*
+* Statium - *Russian*
+* Alex Lee (qianmengnet) - *Chinese Simplified*
+* Ali Yasir Yılmaz (ayyilmaz) - *Turkish*
+* sdl-blue - *German Informal*
+* sqlik - *Polish*
+* Julio Alberto García (Yllelder) - *Spanish*
+* Beenbag - *German*, *German Informal*
+* Roy van Schaijk (royvanschaijk) - *Dutch*
+* Simsimpicpic - *French*
+* Zenahr Barzani (Zenahr) - *German*, *Japanese*, *Dutch*, *German Informal*
+* tatsuya.info - *Japanese*
+* fadiapp - *Arabic*
+* Jakub “Jéžiš” Bouček (jakubboucek) - *Czech*
+* [@Honvid](https://github.com/BookStackApp/BookStack/pull/2157) - *Chinese Simplified*
+
+### Full List of Changes
+
+* Added API endpoints for chapters.
+* Added audit log to the settings area. ([#2173](https://github.com/BookStackApp/BookStack/issues/2173), [#1167](https://github.com/BookStackApp/BookStack/issues/1167))
+* Added the ability to insert an attachment link directly into the current editor window. ([#1460](https://github.com/BookStackApp/BookStack/issues/1460))
+* Added session-based code-block editor auto-save to prevent potential loss of content. ([#1398](https://github.com/BookStackApp/BookStack/issues/1398))
+* Added warning wording around role system permissions to indicate what permissions could allow privilege escalation. ([#2105](https://github.com/BookStackApp/BookStack/issues/2105))
+* Added the ability to log login failures to a file. Thanks to [@benrubson](https://github.com/BookStackApp/BookStack/pull/1881). ([#1881](https://github.com/BookStackApp/BookStack/pull/1881), [#728](https://github.com/BookStackApp/BookStack/issues/728))
+* Updated Simplified Chinese translations. Thanks to [@Honvid](https://github.com/BookStackApp/BookStack/pull/2157). ([#2157](https://github.com/BookStackApp/BookStack/pull/2157))
+* Updated WYSIWYG editor css to put editor in it's own layer to improve degraded dark mode performance. ([#2154](https://github.com/BookStackApp/BookStack/issues/2154))
+* Updated Czech translations. Thanks to [@jakubboucek](https://github.com/BookStackApp/BookStack/pull/2238). ([#2238](https://github.com/BookStackApp/BookStack/pull/2238))
+* Updated permission system so that the permission map table does not contain ID's since database limits could be met in scenarios where permissions were automatically refreshed on a frequent basis. ([#2091](https://github.com/BookStackApp/BookStack/issues/2091))
+* Updated to role table in the database to remove a redundant name field which fixes issue where changing a role name would not change the name used to match with LDAP groups. ([#2032](https://github.com/BookStackApp/BookStack/issues/2032))
+* Updated URL slug generation to achieve a much cleaner result when non-ascii characters are used. Thanks to [@drzippie](https://github.com/BookStackApp/BookStack/pull/2165). ([#2165](https://github.com/BookStackApp/BookStack/pull/2165), [#2026](https://github.com/BookStackApp/BookStack/issues/2026), [#1765](https://github.com/BookStackApp/BookStack/issues/1765))
+* Updated error reporting so that not-found errors are not written to the log, causing logs to fill much quicker than expected. ([#2110](https://github.com/BookStackApp/BookStack/issues/2110))
+* Updated dark mode styles to remove filters applied to images so that they display as expected. ([#2045](https://github.com/BookStackApp/BookStack/issues/2045))
+* Removed Vue.js from project & started standardisation of custom basic component system. ([#2202](https://github.com/BookStackApp/BookStack/issues/2202))
+* Replaced dev usage of node-sass with dart-sass. Thanks to [@timoschwarzer](https://github.com/BookStackApp/BookStack/pull/2166). ([#2166](https://github.com/BookStackApp/BookStack/pull/2166))
+* Fixed issue where, upon role delete, users would not be migrated when specified to during role delete flow. ([#2211](https://github.com/BookStackApp/BookStack/issues/2211))
+* Fixed issue where the system would error on upload of images that contain a hash in the name. ([#2161](https://github.com/BookStackApp/BookStack/issues/2161))
+* Fixed scenario where page drafts would show as saved where request would actually fail, leading to loss of data. Added a browser-side storage mechanism for emergency use. ([#2150](https://github.com/BookStackApp/BookStack/issues/2150))
+* Fixed issue where LDAP groups would not sync on initial login due to the email confirmation system taking over before the group sync would run. ([#2082](https://github.com/BookStackApp/BookStack/issues/2082))
+* Fixed issue where the redirect upon login could lead to an external site. ([#2073](https://github.com/BookStackApp/BookStack/issues/2073))
+* Fixed low visibility of horizontal lines when dark mode is in use. ([#2209](https://github.com/BookStackApp/BookStack/issues/2209))
+* Fixed issue where HTML entities would be seen in page preview content. Thanks to [@mr-vinn](https://github.com/BookStackApp/BookStack/pull/2257). ([#2257](https://github.com/BookStackApp/BookStack/pull/2257), [#2114](https://github.com/BookStackApp/BookStack/issues/2114))
+* Fixed issue where previous page content would be indexed upon save instead of the fresh content. ([#2042](https://github.com/BookStackApp/BookStack/issues/2042))
+* Fixed issue where an error would be thrown on SAML logout request from the IdP. ([#2002](https://github.com/BookStackApp/BookStack/issues/2002))
+* Fixed bad pagination styling which would result in invisible numbering. ([#1839](https://github.com/BookStackApp/BookStack/issues/1839))
+* Fixed incorrect and misleading behaviour when saving a comment with no content. ([#1836](https://github.com/BookStackApp/BookStack/issues/1836))
+
+
+### Next Steps
+
+For v0.31 my main focus will be adding pages to the API which will be a bit more involved than the other endpoints we've added so far. That would complete the core API endpoints I wanted to initially implement; After that I'll allow issues to be created to request other API endpoints that people may need.
+
+Now that I've added the audit log I'd like to expand the activities we track to include things such as setting changes, logins & user creations so that admins will be able to review administration operations. As part of that work I'll try to start a deeper scoping into how content notifications could fit into the application.
+
+I've opened a proposal to implement proper "Owner" controls, [which can be seen here](https://github.com/BookStackApp/BookStack/issues/2246). At the moment the permission system has the ability to apply different permissions for someone's own content but this currently relates to the creator. This causes issues in scenarios where someone would create elements, such as a book, on behalf of another user. These changes would mean a "Owner" user would be assigned to each item, the creator by default, but that "Owner" could easily be re-assigned where required. I'll likely implement this as part of the next release cycle unless there are any major concerns. 
+
+----
+
+<span style="font-size: 0.8em;opacity:0.9;">Header Image Credits: <span>Photo by <a href="https://unsplash.com/@priscilladupreez?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Priscilla Du Preez</a> on <a href="https://unsplash.com/s/photos/books?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span></span>
diff --git a/content/blog/beta-release-v0-31-0.md b/content/blog/beta-release-v0-31-0.md
new file mode 100644 (file)
index 0000000..4d33d10
--- /dev/null
@@ -0,0 +1,210 @@
++++
+categories = ["Releases"]
+tags = ["Releases"]
+title = "Beta Release v0.31.0"
+date = 2021-01-03T21:30:00Z
+author = "Dan Brown"
+image = "/images/blog-cover-images/winter-fox-birger-strahl.jpg"
+description = "We begin 2021 with BookStack v0.31 which comes with recycle bin functionality, the page REST API endpoints and much more"
+slug = "beta-release-v0-31-0"
+draft = false
++++
+
+We kick of this optimistic year with BookStack v0.31 which includes some great additions & updates to existing functionality including
+a new recycle bin system, controllable item ownership, audit log changes, page API endpoints and much more.
+
+
+* [Update instructions](https://www.bookstackapp.com/docs/admin/updates)
+* [GitHub release page](https://github.com/BookStackApp/BookStack/releases/tag/v0.31.0)
+
+
+Just to note, There were a few security releases for v0.30. If you're not upgrading from v0.30.7 be sure to 
+read through the version specific notes on the [updates page](https://www.bookstackapp.com/docs/admin/updates).
+
+
+### Recycle Bin
+
+Ever had an accidental deletion in your instance that you needed to undo? Now you can,
+without having to restore a database backup, using the new recycle bin system. 
+When you delete a shelf, book, chapter or page they'll now be sent to the recycle bin:
+
+
+![Recycle Bin Listing](/images/2021/01/recycle_bin.png)
+
+
+On each item you can choose to restore or permanently delete it as required. By default, Items deleted
+over 30 days ago may be automatically permanently deleted from the recycle bin.
+
+The recycle bin can be accessed via the maintenance page where you'll also be provided with an overview of what is 
+currently in the bin:
+
+![Recycle Bin Maintenance Overview](/images/2021/01/recycle_bin_maintenance.png)
+
+The inclusion of the recycle bin also introduces a change into how chapter deletion works. Previously deleting
+a chapter would cause all child pages to be moved to the parent book. From v0.31, deleting a chapter will send
+the chapter and all child pages to the recycle bin. This aligns with the deletion behaviour of books.
+
+
+### Item Ownership
+
+Since March in 2016 BookStack has had permissions available that permit the owner of content to make certain actions, For scenarios
+such as "user is able to create pages within their own books". While potentially useful, these permissions were hard to 
+use in practice since the owner would always simply be the creator.
+
+In v0.31 the owner is now a separately tracked user, defaulting to the creator. The owner can be changed
+on the permissions view of a shelf, book, chapter or page as shown below:
+
+![Page OwnerShip Change](/images/2021/01/ownership_change.png)
+
+When you delete a user, you'll now be given the option to transfer ownership to another user if required.
+
+These changes should make it much easier to setup scenarios where you have user-owned books where
+they can only create, edit and delete within their own book.
+
+### Audit Log Updates
+
+With the last feature release introducing the audit log, time has been spent this release cycle on expanding the tracked activities
+to include many more events such as logins, user-management actions and settings update actions.
+
+![New Audit Log Activities](/images/2021/01/audit_log_updates.png)
+
+### User List Changes
+
+A common requirement when managing users is to see who's inactive and therefore might need to be removed from the system.
+This was previously tricky to do without direct database queries or careful manual monitoring but now in v0.31
+the latest activity will now be shown on the users list within a sortable column:
+
+![User List with Latest Activity](/images/2021/01/user_list_activity.png)
+
+Since you can sort by this column you can quickly find inactive users. Note, the latest activity date
+reflected is based on the activity tracked in the audit-log, so does not include view/read only events but should 
+include anything that counts as a modification. Activities made before v0.31 may not be reflected.
+
+### New Revision Changes System
+
+When viewing a revision you have the option to preview pages.
+This was done through the [gathercontent/htmldiff](https://github.com/gathercontent/htmldiff) which was great
+but had not been supported in a while and required the PHP Tidy extension which could be tricky to locate and 
+install on some systems. 
+
+In v0.31 we've now switched to [ssddanbrown/htmldiff](https://github.com/ssddanbrown/htmldiff/) which I ported
+from a [c# implementation found here](https://github.com/Rohland/htmldiff.net) which is a port of a [ruby implementation found here](https://github.com/myobie/htmldiff).  Major credit to [@Rohland](https://github.com/Rohland) and [@myobie](https://github.com/myobie) for their original work which I
+have simply ported.
+
+![Revision Changes View](/images/2021/01/changes_view.png)
+
+This new library does not have the PHP Tidy extension requirement so should make installation & maintenance
+easier for some. From my testing this new library has appeared to work without issue but we will have to see
+how it performs in wider use. 
+
+### API Update - Pages
+
+This release brings page endpoints to the REST API. This completes the initial phase
+of the API now that we have CRUD endpoints for shelves, books, chapters and pages.
+
+![Pages API Documentation](/images/2021/01/pages_api.png)
+
+Now the core content parts are in place, I'm open to GitHub issues being created to request
+specific features or endpoints so further actions can be performed. 
+
+To support usage of the API, I've setup a new BookStack api-scripts repository on GitHub:
+https://github.com/BookStackApp/api-scripts. This will be a collection of useful scripts I,
+or others, create as examples or for specific tasks. These can be used directly, or as a base/guide to
+create other scripts.
+
+
+### Iframe & Cookie Security Updates
+
+Over the last 6 months some of the mainstream browsers have added additional protections for cookies,
+restricting the default usage within a third-party context. For BookStack, this meant that access
+through an iframe may not fully work due to cookies being blocked.
+
+In v0.31, we've added additional controls to prevent usage within an iframe. [CSP frame-ancestors](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors) headers will now be set, and used by modern browsers, to ensure it will only load within an iframe 
+where the parent page is on the same host as BookStack. 
+
+A new `ALLOWED_IFRAME_HOSTS` option, to be used in the `.env` file, can be used to allow iframe access for certain hosts. This can be used like so:
+
+```bash
+# Adding a single host
+ALLOWED_IFRAME_HOSTS="https://example.com"
+
+# Mulitple hosts can be separated with a space
+ALLOWED_IFRAME_HOSTS="https://a.example.com https://b.example.com"
+```
+
+Setting this option will also adjust cookie security so that they can be set in a third-party context, and hence work when inside an iframe.
+
+Details of this have been added to the [security page of the docs](/docs/admin/security/#iframe-control).
+
+
+### Translations
+
+Big thanks to [@Swoy](https://github.com/BookStackApp/BookStack/pull/2336) who as provided Norwegian translations to BookStack for this release.
+In addition, the below list shows the fantastic translators that have made changes since v0.30 and the languages they've updated:
+
+* [@Swoy](https://github.com/BookStackApp/BookStack/pull/2336) - *Norwegian*
+* Andrej Močan (andrejm) - *Slovenian*
+* gilane9_ - *Arabic*
+* Jakub Bouček (jakubboucek) - *Czech*
+* Raed alnahdi (raednahdi) - *Arabic*
+* rcy - *Swedish*
+* Mykola Ronik (Mantikor) - *Ukrainian*
+* m0uch0 - *Spanish*
+* Xiphoseer - *German*
+* 10935336 - *Chinese Simplified*
+* MerlinSVK (merlinsvk) - *Slovak*
+* nutsflag - *French*
+* Kauê Sena (kaue.sena.ks) - *Portuguese, Brazilian*
+* Leonardo Mario Martinez (leonardo.m.martinez) - *Spanish, Argentina*
+* Vuong Trung Hieu (fpooon) - *Vietnamese*
+* milesteg - *Hungarian*
+* Statium - *Russian*
+* Ghost_chu (dbguichu) - *Chinese Simplified*
+* Ikhwan Koo (Ikhwan.Koo) - *Korean*
+* Marco (cdrfun) - *German*
+* MatthieuParis - *French*
+* Douradinho - *Portuguese, Brazilian*
+* Lowkey (v587ygq) - *Chinese Simplified*
+* Beenbag - *German*
+* ReadySystems - *Arabic*
+* Gaku Yaguchi (tama11) - *Japanese*
+* 孟繁阳 (FanyangMeng) - *Chinese Simplified*
+
+
+
+### Full List of Changes
+
+* Added recycle bin implementation. ([#2283](https://github.com/BookStackApp/BookStack/pull/2283), [#2183](https://github.com/BookStackApp/BookStack/issues/2183), [#280](https://github.com/BookStackApp/BookStack/issues/280))
+* Added Norwegian translations to BookStack. Thanks to [@Swoy](https://github.com/BookStackApp/BookStack/pull/2336). ([#2336](https://github.com/BookStackApp/BookStack/pull/2336))
+* Added ownership system for pages, chapters, books and shelves. ([#2436](https://github.com/BookStackApp/BookStack/pull/2436), [#2246](https://github.com/BookStackApp/BookStack/issues/2246))
+* Added host iframe control with cookie security management. ([#2427](https://github.com/BookStackApp/BookStack/issues/2427), [#2207](https://github.com/BookStackApp/BookStack/issues/2207))
+* Added API endpoints for pages. ([#2382](https://github.com/BookStackApp/BookStack/pull/2382))
+* Added many more activity types to the audit-log. ([#2360](https://github.com/BookStackApp/BookStack/pull/2360), [#1243](https://github.com/BookStackApp/BookStack/issues/1243))
+* Added a sortable "Latest Activity" column to the users list. ([#848](https://github.com/BookStackApp/BookStack/issues/848))
+* Replaced revision diff library so that the php tidy extension is no longer required. ([#2347](https://github.com/BookStackApp/BookStack/issues/2347), [#1553](https://github.com/BookStackApp/BookStack/issues/1553))
+* Updated GitLab authentication to use the `read_user` scope. ([#2359](https://github.com/BookStackApp/BookStack/issues/2359))
+* Updated revision restore to add sensible default change summary text. Thanks to [@rondaa](https://github.com/BookStackApp/BookStack/pull/2353). ([#2353](https://github.com/BookStackApp/BookStack/pull/2353), [#2349](https://github.com/BookStackApp/BookStack/issues/2349))
+* Updated the "Cleanup Images" maintenance option wording for clarity. ([#2352](https://github.com/BookStackApp/BookStack/issues/2352))
+* Updated dev docker setup to install composer dependencies in Docker entrypoint. Thanks to [@timoschwarzer](https://github.com/BookStackApp/BookStack/pull/2298). ([#2298](https://github.com/BookStackApp/BookStack/pull/2298))
+* Updated chapter delete behaviour so pages are removed instead of being moved to the parent book. ([#2164](https://github.com/BookStackApp/BookStack/issues/2164))
+* Updated grid-layout book/shelf item names to better fit into two lines. ([#1469](https://github.com/BookStackApp/BookStack/issues/1469))
+* Updated translations. ([#2439](https://github.com/BookStackApp/BookStack/pull/2439), [#2327](https://github.com/BookStackApp/BookStack/pull/2327))
+* Fixed issue where the export dropdown may show cut-off with options hidden. Thanks to [@shubhamosmosys](https://github.com/BookStackApp/BookStack/pull/2416). ([#2416](https://github.com/BookStackApp/BookStack/pull/2416))
+
+
+### Next Steps
+
+Over the last few months we've had a good number of authentication-based pull requests, in addition to some others, which I've been somewhat ignoring so I'll
+look to spend some time reviewing a few of those.
+
+Now we have the core elements of the API integrated we'll now see what other features people may need. I'm imagining we'd add a few endpoints each future release for a while.
+
+With the API base down and the activity system fleshed out, now may be a good time to implement an outbound web-hook system.
+I'll likely create an implementation proposal so I can ensure we'd be covering the main use-cases required.
+
+PHP 8 support is another thing I'll look to work on over the next release cycle. Some work has been put into this but, due to 
+scale of changes in PHP 8 and the rate that some required packages move at, it's a trickier process than previous new PHP versions.
+
+----
+
+<span style="font-size: 0.8em;opacity:0.9;">Header Image Credits: <span>Photo by <a href="https://unsplash.com/@bist31?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Birger Strahl</a> on <a href="https://unsplash.com/t/animals?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span></span>
index a6421108d08c8546b38ec3d762224a51a10a301c..c4e24e5f54a53831dee8bb9d17e7adc9763d989a 100644 (file)
@@ -10,7 +10,7 @@ tags = ["Releases"]
 
 +++
 
-BookStack Beta v0.7.6 has now been released. The release can be found [here on GitHub](https://github.com/ssddanbrown/BookStack/releases/tag/v0.7.6) and [update instructions can be found here](https://github.com/ssddanbrown/BookStack/blob/master/readme.md#updating-bookstack).
+BookStack Beta v0.7.6 has now been released. The release can be found [here on GitHub](https://github.com/BookStackApp/BookStack/releases/tag/v0.7.6) and [update instructions can be found here](https://github.com/BookStackApp/BookStack/blob/master/readme.md#updating-bookstack).
 
 **Here are some important things to note with this update:**
 
@@ -48,4 +48,4 @@ When searching the system you can now put words in double quotes, `"like this"`,
 ### Bug Fixes & Small Updates
 
 * Fixed homepage 'Recent Pages' list showing the same pages as the 'Recently Created Pages' list.
-* Added configration support for Memcached.
\ No newline at end of file
+* Added configration support for Memcached.
index b7a4878eede539a59a1a2302b196c7f1dd4570a3..60a59fde44cf733e76e7ca110520d861dc018599 100644 (file)
@@ -12,11 +12,11 @@ author = "Dan Brown"
 
 **Update**
 
-[BookStack v0.8.1 has since been released](https://github.com/ssddanbrown/BookStack/releases/tag/v0.8.0) to address some bugs.
+[BookStack v0.8.1 has since been released](https://github.com/BookStackApp/BookStack/releases/tag/v0.8.0) to address some bugs.
 
 ----
 
-BookStack v0.8.0 has now been released!. The release can be found [here on GitHub](https://github.com/ssddanbrown/BookStack/releases/tag/v0.8.0) and [update/install instructions can be found here](https://github.com/ssddanbrown/BookStack/blob/master/readme.md#updating-bookstack). 
+BookStack v0.8.0 has now been released!. The release can be found [here on GitHub](https://github.com/BookStackApp/BookStack/releases/tag/v0.8.0) and [update/install instructions can be found here](https://github.com/BookStackApp/BookStack/blob/master/readme.md#updating-bookstack). 
 
 We realised that we have pretty much been randomly creating the release numbers so far so but from now on we are going to stick to [Semantic Versioning 2.0.0](http://semver.org/) as much as possible. Since this release has some large new features that are upgrade-compatible we're jumping off v0.7.x and going direct to v0.8.0.
 
index 3e22f5b99cc2abacf9f320c188ade154665797b5..c8eb698ef501ff18fe1fa584bca1248245dccea9 100644 (file)
@@ -8,10 +8,10 @@ date = 2016-03-30T16:13:09Z
 
 +++
 
-BookStack v0.8.2 has just been push up to the release branch in the official [GitHub repository](https://github.com/ssddanbrown/BookStack/releases/tag/v0.8.2). This is a bugfix release to fix a few small things up before the next feature release. Update instructions can be found in the [new documentation pages here](https://www.bookstackapp.com/docs/admin/updates).
+BookStack v0.8.2 has just been push up to the release branch in the official [GitHub repository](https://github.com/BookStackApp/BookStack/releases/tag/v0.8.2). This is a bugfix release to fix a few small things up before the next feature release. Update instructions can be found in the [new documentation pages here](https://www.bookstackapp.com/docs/admin/updates).
 
 The biggest update is to the Book, Chapter & Page restrictions that were introduced in version 0.7.6. This has been re-named from 'Restrictions' to 'Permissions' since that's a much more appropriate name for them. Also it was noticed that the 'Restriction' system did not allow a role, with given permissions selected, to perform actions that they did not also have permissions for on a role level. Both role and asset permissions were required before which prevented this system being really useful.
 
-This behaviour has now been amended so that asset-level permissions will now override role-level permissions. This makes total sense since, on assets, you have to specify what actions to allow on a role-by-role basis anyway. More details about this change can be found in my comment on [this issue](https://github.com/ssddanbrown/BookStack/issues/89#issuecomment-203135563).
+This behaviour has now been amended so that asset-level permissions will now override role-level permissions. This makes total sense since, on assets, you have to specify what actions to allow on a role-by-role basis anyway. More details about this change can be found in my comment on [this issue](https://github.com/BookStackApp/BookStack/issues/89#issuecomment-203135563).
 
-One other tweak is a presentational fix in the header. Longer names will be cut down (Or hidden if necessary) to prevent them from dropping down onto a new line and taking up space. Details of this issue can be [found here](https://github.com/ssddanbrown/BookStack/issues/87).
\ No newline at end of file
+One other tweak is a presentational fix in the header. Longer names will be cut down (Or hidden if necessary) to prevent them from dropping down onto a new line and taking up space. Details of this issue can be [found here](https://github.com/BookStackApp/BookStack/issues/87).
diff --git a/content/blog/beta-security-release-v0-30-4.md b/content/blog/beta-security-release-v0-30-4.md
new file mode 100644 (file)
index 0000000..4294e58
--- /dev/null
@@ -0,0 +1,70 @@
++++
+categories = ["Releases"]
+tags = ["Releases"]
+title = "Beta Security Release v0.30.4"
+date = 2020-10-31T16:30:00Z
+author = "Dan Brown"
+image = "/images/blog-cover-images/locks-marcos-mayer.jpg"
+description = "This release contains some security fixes to prevent various XSS attacks"
+slug = "beta-release-v0-30-4"
+draft = false
++++
+
+
+XSS and user-injected auto-redirect vulnerabilities have been found within the page content & attachment components of BookStack which BookStack v0.30.4 looks to address. These are primarily a concern if untrusted users can edit content on your BookStack instance.
+
+* [Update instructions](https://www.bookstackapp.com/docs/admin/updates)
+* [GitHub release page](https://github.com/BookStackApp/BookStack/releases/tag/v0.30.4)
+
+
+### Impact
+
+1. A user with permissions to edit a page could insert JavaScript code through the use of `javascript:` URIs within a link or form which would run, within the context of the current page, when clicked or submitted. 
+
+2. A user with permissions to edit a page could insert a particular meta tag which could be used to silently redirect users to a alternative location upon visit of a page.
+
+3. A user with permissions to edit a page could add an attached link which would execute untrusted JavaScript code when clicked by a viewer of the page.
+
+### Patches
+
+The issues were addressed in BookStack v0.30.4. 
+
+Dangerous content may remain in the database. The in-page vulnerabilities will be removed before being displayed on a page but dangerous attachment content will remain if exploited. If you think this could have been exploited you can search for potential cases with the following SQL commands:
+
+```sql
+# XSS within page content:
+select * from pages where html like '%javascript:%';
+
+# Auto-redirect within page content:
+select * from pages where html like '%<meta%';
+
+# XSS in page link attachments:
+select a.name as attachment_name, p.name as page_name, p.id as page_id from attachments a left join pages p on (a.uploaded_to=p.id) where a.path like '%javascript:%';
+```
+
+### Workarounds
+
+Page edit permissions could be limited to only those that are trusted until you can upgrade although this will not address existing exploitation of this vulnerability. 
+
+### References
+
+* [BookStack Beta v0.30.4](https://github.com/BookStackApp/BookStack/releases/tag/v0.30.4)
+* [GitHub Security Page - XSS/Redirect in Page Content](https://github.com/BookStackApp/BookStack/security/advisories/GHSA-r2cf-8778-3jgp)
+* [GitHub Security Page - XSS in Page Attachment](https://github.com/BookStackApp/BookStack/security/advisories/GHSA-7p2j-4h6p-cq3h)
+
+### Attribution
+
+* Thanks to [@PercussiveElbow](https://github.com/PercussiveElbow) for the discovery, reporting, patching and testing of the page-content vulnerabilities.
+* Thanks to Yassine ABOUKIR (https://twitter.com/yassineaboukir/) for the discovery and reporting of the page attachment vulnerability.
+
+### More Information
+
+If you have any questions or comments about this advisory:
+* Open an issue in [the BookStack GitHub repository](BookStackApp/BookStack/issues).
+* Ask on the [BookStack Discord chat](https://discord.gg/ztkBqR2).
+* Follow the [BookStack Security Advice](https://github.com/BookStackApp/BookStack#-security) to contact someone privately.
+
+
+----
+
+<span style="font-size: 0.8em;opacity:0.9;">Header Image Credits: <span>Photo by <a href="https://unsplash.com/@mmayyer?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">marcos mayer</a> on <a href="https://unsplash.com/s/photos/lock?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span></span>
diff --git a/content/blog/beta-security-release-v0-30-5.md b/content/blog/beta-security-release-v0-30-5.md
new file mode 100644 (file)
index 0000000..f80ebc6
--- /dev/null
@@ -0,0 +1,54 @@
++++
+categories = ["Releases"]
+tags = ["Releases"]
+title = "Beta Security Release v0.30.5"
+date = 2020-12-06T20:30:00Z
+author = "Dan Brown"
+image = "/images/blog-cover-images/lock-jon-moore.jpg"
+description = "This release contains some security fixes to prevent phishing and server-side request forgery"
+slug = "beta-release-v0-30-5"
+draft = false
++++
+
+
+Phishing and and server-side request forgery vulnerabilities have been found within BookStack. Release v0.30.5 will remove this server-side request forgery issue while bringing updated wording and advisories to prevent the potential phishing vulnerability.
+
+* [Update instructions](https://www.bookstackapp.com/docs/admin/updates)
+* [GitHub release page](https://github.com/BookStackApp/BookStack/releases/tag/v0.30.5)
+
+
+### Impact
+
+1. A user with permissions to edit a page could set certain image URL's within a page to manipulate functionality in the exporting system, which would allow them to make server side requests and/or have access to a wider scope of files within the BookStack file storage locations. This is primarily a concern if untrusted users are able to edit pages in your instance.
+
+2. A malicious attacker could craft a password reset request with an alternate host address, resulting in a password reset email being sent to someone with an alternate destination. This could be used for phishing attempts with a sight to gain further access if successful. This is a primarily a concern on hosts where requests to unexpected domain names could reach your BookStack instance.
+
+### Patches
+
+Within v0.30.5 the above server-side request forgery vulnerability will no longer exist since that specific functionality was removed. Within v0.30.5 the default state and wording within the provided `.env.example` file was updated to encorage filling of the `APP_URL` parameter (See below).
+
+### Workarounds
+
+To help prevent the potential phishing vulnerability, please ensure you have set the `APP_URL` option in your `.env` file. The value of this should exactly match the base URL you are using to host BookStack.
+
+To prevent exploitation of the server-side request forgery issue, page edit permissions could be limited to only those that are trusted until you can upgrade. 
+
+### References
+
+* [BookStack Beta v0.30.5](https://github.com/BookStackApp/BookStack/releases/tag/v0.30.5)
+* [GitHub Security Page - Server Side Request Forgery](https://github.com/BookStackApp/BookStack/security/advisories/GHSA-8wfc-w2r5-x7cr)
+
+### Attribution
+
+* Thanks to [@PercussiveElbow](https://github.com/PercussiveElbow) for the responsible discovery & reporting of this vulnerability.
+
+### More Information
+
+If you have any questions or comments about this advisory:
+* Open an issue in [the BookStack GitHub repository](BookStackApp/BookStack/issues).
+* Ask on the [BookStack Discord chat](https://discord.gg/ztkBqR2).
+* Follow the [BookStack Security Advice](https://github.com/BookStackApp/BookStack#-security) to contact someone privately.
+
+----
+
+<span style="font-size: 0.8em;opacity:0.9;">Header Image Credits: <span>Photo by <a href="https://unsplash.com/@thejmoore?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Jon Moore</a> on <a href="https://unsplash.com/s/photos/locks?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span></span>
diff --git a/content/blog/beta-security-release-v0-30-6.md b/content/blog/beta-security-release-v0-30-6.md
new file mode 100644 (file)
index 0000000..f159954
--- /dev/null
@@ -0,0 +1,51 @@
++++
+categories = ["Releases"]
+tags = ["Releases"]
+title = "Beta Security Release v0.30.6"
+date = 2020-12-17T21:30:00Z
+author = "Dan Brown"
+image = "/images/blog-cover-images/lock-door-waldemar-brandt.jpg"
+description = "BookStack v0.30.6 has been released to address an issue that could lead to restricted page content being visible in certain circumstances."
+slug = "beta-release-v0-30-6"
+draft = false
++++
+
+
+BookStack v0.30.6 has been released to address an issue that could lead to restricted page content being visible in certain circumstances.
+You should upgrade to this released as soon as possible if you make use of page-level permissions at all.
+
+* [Update instructions](https://www.bookstackapp.com/docs/admin/updates)
+* [GitHub release page](https://github.com/BookStackApp/BookStack/releases/tag/v0.30.6)
+
+
+### Impact
+
+If a chapter was visible to a user, but all of it's pages were made not visible, then the details of these pages could be visible. Within the BookStack interface, the names of the pages and preview content could be seen. If the parent book was exported then this would include the content of the pages that had been restricted.
+
+### Patches
+
+This has been patched in v0.30.6.
+
+### Workarounds
+
+Please update. As a temporary workaround you could ensure that there is at least one other page within a chapter that's visible to users. 
+
+### References
+
+* [BookStack Beta v0.30.6](https://github.com/BookStackApp/BookStack/releases/tag/v0.30.6)
+* [GitHub Issue #2414](https://github.com/BookStackApp/BookStack/issues/2414)
+
+### Attribution
+
+A big thanks to [@cdrfun](https://github.com/cdrfun) for [discovering and reporting](https://github.com/BookStackApp/BookStack/issues/2414) this issue.
+
+### For more information
+
+If you have any questions or comments about this advisory:
+* Open an issue in [the BookStack GitHub repository](BookStackApp/BookStack/issues).
+* Ask on the [BookStack Discord chat](https://discord.gg/ztkBqR2).
+* Follow the [BookStack Security Advice](https://github.com/BookStackApp/BookStack#-security) to contact someone privately.
+
+----
+
+<span style="font-size: 0.8em;opacity:0.9;">Header Image Credits: <span>Photo by <a href="https://unsplash.com/@waldemarbrandt67w?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Waldemar Brandt</a> on <a href="https://unsplash.com/s/photos/lock?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span></span>
diff --git a/content/blog/beta-security-release-v0-30-7.md b/content/blog/beta-security-release-v0-30-7.md
new file mode 100644 (file)
index 0000000..f8bc7ed
--- /dev/null
@@ -0,0 +1,51 @@
++++
+categories = ["Releases"]
+tags = ["Releases"]
+title = "Beta Security Release v0.30.7"
+date = 2020-12-18T14:00:00Z
+author = "Dan Brown"
+image = "/images/blog-cover-images/lock-aubrey-odom.jpg"
+description = "In continuation of the patches in v0.30.6, BookStack v0.30.7 has been released to address an issue that could lead to restricted page content being made visible in exports."
+slug = "beta-release-v0-30-7"
+draft = false
++++
+
+
+In continuation of the patches in v0.30.6, BookStack v0.30.7 has been released to address an issue that could lead to restricted page content being made visible in exports.
+As with the last release, You should upgrade to this released as soon as possible if you make use of page-level permissions at all. Apologies for the frequency of security releases.
+
+* [Update instructions](https://www.bookstackapp.com/docs/admin/updates)
+* [GitHub release page](https://github.com/BookStackApp/BookStack/releases/tag/v0.30.7)
+
+
+### Impact
+
+The content of pages made non-viewable to a user via permissions, within a visible parent, could be seen via the plaintext export option. Before v0.30.6 this would have applied only to scenarios where all pages within the chapter were made non-visible. In v0.30.6 this would make all pages within the chapter visible.
+
+### Patches
+
+This has been patched in v0.30.7.
+
+### Workarounds
+
+Please update. As a temporary workaround you could make parent chapters/books non accessible.
+
+### References
+
+* [BookStack Beta v0.30.7](https://github.com/BookStackApp/BookStack/releases/tag/v0.30.7)
+* [GitHub Issue #2414](https://github.com/BookStackApp/BookStack/issues/2414)
+
+### Attribution
+
+A big thanks again to [@cdrfun](https://github.com/cdrfun) for [discovering and reporting](https://github.com/BookStackApp/BookStack/issues/2414) this issue.
+
+### For more information
+
+If you have any questions or comments about this advisory:
+* Open an issue in [the BookStack GitHub repository](BookStackApp/BookStack/issues).
+* Ask on the [BookStack Discord chat](https://discord.gg/ztkBqR2).
+* Follow the [BookStack Security Advice](https://github.com/BookStackApp/BookStack#-security) to contact someone privately.
+
+----
+
+<span style="font-size: 0.8em;opacity:0.9;">Header Image Credits: <span>Photo by <a href="https://unsplash.com/@octoberroses?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Aubrey Odom</a> on <a href="https://unsplash.com/s/photos/lock?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span></span>
diff --git a/content/blog/beta-security-release-v0-31-4.md b/content/blog/beta-security-release-v0-31-4.md
new file mode 100644 (file)
index 0000000..29b29d5
--- /dev/null
@@ -0,0 +1,32 @@
++++
+categories = ["Releases"]
+tags = ["Releases"]
+title = "Beta Security Release v0.31.4"
+date = 2021-01-16T18:00:00Z
+author = "Dan Brown"
+image = "/images/blog-cover-images/gate-masaaki-komori.jpg"
+slug = "beta-release-v0-31-4"
+draft = false
++++
+
+BookStack v0.31.4 has been released. This security release updates the [Laravel framework version](https://blog.laravel.com/security-laravel-62012-7303-released), due to a vulnerability that could occur if request data was crafted and then used in a certain way. While it is not known if such a case exists in BookStack, this release updates the framework as a pre-emptive measure.
+
+* [Update instructions](https://www.bookstackapp.com/docs/admin/updates)
+* [GitHub release page](https://github.com/BookStackApp/BookStack/releases/tag/v0.31.4)
+
+### Markdown editing in v0.31
+
+In addition to this security release, A range of patch releases (v0.31.1, v0.31.2 & v0.31.3) have been made available recently
+which largely covers issues in how markdown content is rendered upon save. In BookStack v0.31 I changed the way we render
+markdown content so it's done server-side upon save. This was done so that markdown could be used via the API and to prepare for future changes. These patch releases have worked to better align the abilities of the new back-end renderer and the existing front-end renderer, that you see as a preview when editing a page.
+
+### For more information
+
+If you have any questions or comments about this advisory:
+* Open an issue in [the BookStack GitHub repository](BookStackApp/BookStack/issues).
+* Ask on the [BookStack Discord chat](https://discord.gg/ztkBqR2).
+* Follow the [BookStack Security Advice](https://github.com/BookStackApp/BookStack#-security) to contact someone privately.
+
+----
+
+<span style="font-size: 0.8em;opacity:0.9;">Header Image Credits: <span>Photo by <a href="https://unsplash.com/@gaspanik?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Masaaki Komori</a> on <a href="https://unsplash.com/s/photos/gate?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span></span>
diff --git a/content/blog/replacing-ga-and-mailchimp.md b/content/blog/replacing-ga-and-mailchimp.md
new file mode 100644 (file)
index 0000000..f8702d6
--- /dev/null
@@ -0,0 +1,102 @@
++++
+title = "Replacing Google Analytics & Mailchimp"
+date = 2021-01-05T18:44:52Z
+categories = ["News"]
+tags = ["News"]
+author = "Dan Brown"
+image = "/images/blog-cover-images/penguin-steffen-triekel.jpg"
+draft = false
++++
+
+On this BookStack site I have been using Google Analytics to track visitor metrics.
+While not crucial to know, it's generally useful to have an idea of the target audience, current popularity and
+be aware of any visitor spikes. For the email updates and email security alerts I've been
+using Mailchimp. This post explains the move to more privacy aware alternatives.
+
+
+### Google Analytics to Plausible
+
+BookStack, being an open source self-hostable platform, will have an audience that's generally quite privacy aware.
+Google is generally seen as an ever-growing threat to privacy on the internet. 
+Google Analytics, as a service to track website visitor metrics, is very popular and well used since it's available
+without paying and provides a very good amount of data hence was my choice for this site until now but I've 
+had a growing unease sending visitor's details to Google without their consent. I did use it without cookie
+usage while choosing to anonymise IP addresses but it would still effectively contribute to Google's 
+own data usage which may be misaligned with the wishes of visitors.
+
+As an alternative, I've set-up a self-hosted instance of [Plausible](https://plausible.io/). 
+I was initially put off with its simplicity, compared to Google Analytics; I mean it has way fewer menus, graphs,
+pages and options so it must be inferior right? But I thought about the questions I want answered from such a service:
+
+* How many visitors are on my site?
+* How many visitors have been on my site?
+* Where have they come from?
+* What pages are being viewed?
+* What country are they visiting from?
+* What kind of devices are being used?
+* When does a traffic spike occur?
+
+Plausible answers all of these, and it does so directly, in an easy and beautiful UI.
+It's simplicity actually makes it better for the questions I need answered since I no longer
+need to navigate through the slow, confusing interface that Google Analytics presents.
+It's all just there in a single view.
+
+![Plausible BookStack Site Analytics](/images/2021/01/plausible_bookstack_site_analytics.png)
+
+Plausible offer paid, hosted plans but I've chosen to self-host the service to keep costs minimal and so that my visitor's data
+is not held by a third-party. That said, I still want to support the project which can be done as a self-hoster via 
+their [GitHub sponsors page](https://github.com/sponsors/plausible). Setup was a straight-forward process using their docker
+configuration and it's been stable so far. I ran it alongside Google Analytics for a few days to check if figures aligned. 
+The numbers were slightly higher (~5 to 10% or so) on the Plausible side which I'd guess may be down to visitors blocking
+Google scripts/domains.
+
+One of my favourite features of Plausible is that it's really easy to make the dashboard public which is something
+I've often wanted to do with Google Analytics in the interest of transparency. The BookStack dashboard can be 
+seen at https://analytics.bookstackapp.com/bookstackapp.com.
+
+### Mailchimp to MailBag
+
+As mentioned in the intro, I've been using Mailchimp to send newsletter updates and security alerts.
+To be honest, It's worked fairly well; Their interface is generally pleasant, it was cost-free for my usage,
+it sent the emails without issue. That said, there were two things I was not a fan of:
+
+1. It's another entity that registrants would have to trust in addition to myself/BookStack.
+2. They added link tracking even when choosing to disable it.
+
+The second point really irked me, especially since you could choose to disable it during campaign setup.
+To be fair, I did not raise it with them but based on this line from their [support page](https://mailchimp.com/help/troubleshooting-click-tracking/):
+
+> We encourage you to leave click tracking on. However, you can disable click tracking in paid accounts after you've sent a few campaigns without any compliance issues.
+
+It appears that user privacy may be a paid feature. 
+
+This tracking was particularly unappealing on our plaintext security updates.
+It's not obvious at all where the links actually lead to:
+
+![Mailchimp Tracked Links Example](/images/2021/01/mailchimp_tracked_links.png)
+
+When looking around for alternatives, I found lots of great options including:
+
+- [Mailcoach](https://mailcoach.app/)
+- [phpList](https://www.phplist.com/)
+- [listmonk](https://listmonk.app/)
+- [Mautic](https://www.mautic.org/)
+
+Unfortunately though many of these lacked an auto-RSS-send feature and/or appeared too complex
+for the focused use-case I had in mind so, with some extra Christmas holiday time, I put together
+my own app which I've called [MailBag](https://github.com/ssddanbrown/mailbag).
+
+![MailBag Home Dashboard ScreenShot](/images/2021/01/mailbag.png)
+
+This is a purposefully very simple app and has lots of limitations, as listed in the [readme](https://github.com/ssddanbrown/mailbag#mailbag),
+but it does what I need it to while providing me an opportunity to work on something
+fresh for a change to sharpen some development skills.
+There is no open/click tracking support; No HTML email support.
+
+Over the next month or so I'll be migrating the existing contact lists from Mailchimp. I'll send out emails to existing
+subscribers as a advisory and to provide an opportunity to opt-out of the migration beforehand. The subscribe links, found
+at the bottom of all posts here, have been updated to the MailBag instance since I'll be running both systems side-by-side for a while.
+
+----
+
+<span style="font-size: 0.9em;opacity:0.9;">Header Image Credits: <span>Photo by <a href="https://unsplash.com/@okinapansa?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Steffen Triekels</a> on <a href="https://unsplash.com/t/animals?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span></span>
\ No newline at end of file
index c146bcb6165d1878a28ff928eafbf8e4b3521c45..46e29535f0f6e18705a2d8001e4e4bc2d8de183f 100644 (file)
@@ -15,6 +15,7 @@ Below you can find details on how to install BookStack on your own hosting. Ther
 * [Ubuntu 18.04 Script](#ubuntu-1804)
 * [Ubuntu 16.04 Script](#ubuntu-1604)
 * [Community Guides](#community)
+* [Other Hosting Options](#other)
 
 ---
 
@@ -24,9 +25,9 @@ Below you can find details on how to install BookStack on your own hosting. Ther
 
 BookStack has the following requirements:
 
-* **PHP** >= 7.2
+* **PHP** >= 7.2.5
     * For installation and maintenence, you'll need to be able to run `php` from the command line.
-    * Required Extensions: *OpenSSL, PDO, MBstring, Tokenizer, GD, MySQL, Tidy, SimpleXML & DOM*
+    * Required Extensions: *OpenSSL, PDO, MBstring, Tokenizer, GD, MySQL, SimpleXML & DOM*
 * **MySQL** >= 5.6
     *  Single Database *(All permissions advised since application manages schema)*
 * **Git Version Control**
@@ -67,16 +68,34 @@ git clone https://github.com/BookStackApp/BookStack.git --branch release --singl
 #### URL Rewrite rules
 
 **Apache**
-```apache
-Options +FollowSymLinks
+
+Ensure `mod_rewrite` is enabled.
+
+```xml
+<IfModule mod_negotiation.c>
+    Options -MultiViews -Indexes
+</IfModule>
+
 RewriteEngine On
 
+# Handle Authorization Header
+RewriteCond %{HTTP:Authorization} .
+RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
+
+# Redirect Trailing Slashes If Not A Folder...
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteCond %{REQUEST_URI} (.+)/$
+RewriteRule ^ %1 [L,R=301]
+
+# Send Requests To Front Controller...
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteRule ^ index.php [L]
 ```
 
 **Nginx**
+
+
 ```nginx
 location / {
     try_files $uri $uri/ /index.php?$query_string;
@@ -188,3 +207,16 @@ This is a collection of guides created by awesome members of the BookStack commu
 * [CentOS 8 Install by Xhark](https://github.com/blogmotion/bm-bookstack-install/blob/master/bookstack-install-centos8.sh) - [french guide](http://blogmotion.fr/internet/bookstack-script-installation-centos-8-18255)
 * [CentOS 7 Install by Deviant Engineer](https://deviant.engineer/2017/02/bookstack-centos7/)
 * [Fedora 27 Install by Jared Busch](https://mangolassi.it/topic/16471/install-bookstack-on-fedora-27/)
+
+
+---
+
+<a name="other"></a>
+
+## Other Hosting Options
+
+Below are some alternative platforms and services that can be used to host BookStack. <br>
+_**Note: These are not tested, vetted nor supported by the official BookStack project in any manner**_.
+
+- [Cloudron](https://www.cloudron.io/store/com.bookstackapp.cloudronapp.html) - A solution for running apps on your own server.
+- [Uberspace](https://lab.uberspace.de/guide_bookstack.html) - A European based hosting provider.
\ No newline at end of file
index 14b28e2ba3665b55beecf6e97bbfc8697fdb0ebf..503e7c4a22fb6ff4b36de659920faaca8b9d9934 100644 (file)
@@ -83,7 +83,7 @@ This can be overridden by via the 'External Authentication IDs' field which can
 
 When matching LDAP groups with role names or 'External Authentication IDs' values, BookStack will standardise the names of ldap groups to be lower-cased and spaces will be replaced with hypens. For example, to match a LDAP group named "United Kingdom" an 'External Authentication IDs' value of "united-kingdom" could be used.
 
-This feature requires the LDAP server to be able to provide user groups when queried. This is enabled by default on ActiveDirectory via the 'memberOf' attribute but other LDAP systems may need to be configured to enable such functionality. If using OpenLDAP you'll need to setup the memberof overlay.
+This feature requires the LDAP server to be able to provide user groups when queried. This is enabled by default on ActiveDirectory via the 'memberOf' attribute but other LDAP systems may need to be configured to enable such functionality. Be aware that the 'memberOf' attribute does not include the user's primary group. If using OpenLDAP you'll need to setup the memberof overlay.
 
 Here are the settings required to be added to your `.env` file to enable group syncing:
 
index 00b3a5071b147e3a3fcb85901b4d87c780e8affb..1e8b2bcf00f0ea690a6c3b8fe74b28b6cb8bb7e3 100644 (file)
@@ -9,6 +9,9 @@ Since BookStack can hold important information for users you should be aware of
 Read through the below to ensure you have secured your BookStack instance. Note, The below only
 relates to BookStack itself. The security of the server BookStack is hosted on is not instructed below but should be taken into account.
 
+If you'd like to be notified of new potential security concerns you can sign-up to the [BookStack security mailing list](https://updates.bookstackapp.com/signup/bookstack-security-updates). For reporting security vulnerabilities, please see the ["Security" section](https://github.com/BookStackApp/BookStack/blob/master/readme.md#-security) of the project readme on GitHub.
+
+
 <ul>
     <li><a href="#initial-security-setup">Initial Security Setup</a></li>
     <li><a href="#securing-images">Securing Images</a></li>
@@ -17,6 +20,8 @@ relates to BookStack itself. The security of the server BookStack is hosted on i
     <li><a href="#javascript-in-page-content">JavaScript in Page Content</a></li>
     <li><a href="#web-crawler-control">Web Crawler Control</a></li>
     <li><a href="#secure-cookies">Secure Cookies</a></li>
+    <li><a href="#iframe-control">Host IFrame Control</a></li>
+    <li><a href="#failed-access-logging">Failed Access Logging</a></li>
 </ul>
 
 ---
@@ -31,9 +36,10 @@ opens up a lot of code that does not need to be public. Triple check this if you
 BookStack within the commonly used `/var/www` folder.
 3. Ensure the database user you've used for BookStack has limited permissions for only accessing
 the database used for BookStack data.
-4. Within BookStack, go through the settings to ensure registration and public access settings are as you expect.
-5. Review the user roles in the settings area.
-6. Read the below to further understand the security for images & attachments.
+4. Check that you've set the `APP_URL` option in your `.env` file so that system generated URLs cannot be manipulated.
+5. Within BookStack, go through the settings to ensure registration and public access settings are as you expect.
+6. Review the user roles in the settings area.
+7. Read the below to further understand the security for images & attachments.
 
 ---
 
@@ -125,4 +131,41 @@ The rules found in the `/robots.txt` file are automatically controlled via the "
 
 ### Secure Cookies
 
-BookStack uses cookies to track sessions, remember logins and for XSRF protection. When using HTTPS you may want to ensure that cookies are only sent back to the browser if the connection is over HTTPS. This can be enabled by setting `SESSION_SECURE_COOKIE=true` in your `.env` file.
\ No newline at end of file
+BookStack uses cookies to track sessions, remember logins and for XSRF protection. When using HTTPS you may want to ensure that cookies are only sent back to the browser if the connection is over HTTPS. If you have set a https `APP_URL` option in your `.env` this will enabled automatically but it can also be forced on by setting `SESSION_SECURE_COOKIE=true` in your `.env` file.
+
+---
+
+<a name="iframe-control"></a>
+
+### Host Iframe Control
+
+By default BookStack will only allow itself to be embedded within iframes on the same domain as you're hosting on. This is done through a [CSP: frame-ancestors](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors) header. You can add additional trusted hosts by setting a `ALLOWED_IFRAME_HOSTS` option in your `.env` file like the example below:
+
+```bash
+# Adding a single host
+ALLOWED_IFRAME_HOSTS="https://example.com"
+
+# Mulitple hosts can be separated with a space
+ALLOWED_IFRAME_HOSTS="https://a.example.com https://b.example.com"
+```
+
+Note: when this option is used, all cookies will served with `SameSite=None` [(info)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite#None) set so that
+a user session can persist within the iframe.
+
+---
+
+<a name="failed-access-logging"></a>
+
+### Failed Access Logging
+
+An option is available to log failed login events to a log file which is useful to identify users having trouble logging in, track malicious login attempts or to use with tools such as Fail2Ban. This works with login attempts using the default email & password login mechanism or attempts via LDAP login. Failed attempts are **not logged** for "one-click" social or SAML2 options.
+
+To enable this you simple need to define the `LOG_FAILED_LOGIN_MESSAGE` option in your `.env` file like so:
+
+```bash
+LOG_FAILED_LOGIN_MESSAGE="Failed login for %u"
+```
+
+The optional "%u" element of the message will be replaced with the username or email provided in the login attempt
+when the message is logged. By default messages will be logged via the php `error_log` function which, in most
+cases, will log to your webserver error log files.
\ No newline at end of file
index e94c75f53f1cc60287cc9901aa151ac6d3f317cc..9fdf4a6e5050d604ed96d65d8b718bedd2cc3dc5 100644 (file)
@@ -205,7 +205,7 @@ GitLab authentication works for both [gitlab.com](https://gitlab.com) and self-h
 3. Set a name to identify the application, such as 'BookStack Authentication', and in the 'Redirect URI' input add both of the below URLs, Changing `https://example.com` to the base URL of your BookStack instance:
     - `https://example.com/login/service/gitlab/callback`
     - `https://example.com/register/service/gitlab/callback`
-4. Do not select any of the 'Scopes' checkboxes.
+4. Select the checkbox for the `read_user` scope.
 5. Press 'Save application'. You will be shown the application ID and secret which you'll need for the next step.  
 6. Copy the below details and add them as new variables in your `.env` file like so:
     ```bash
index 358b3c7beef862bf03086bd31d3cde03dba96b67..72a6d995367bfe21c4fe52efac1aebb645803729 100644 (file)
@@ -31,6 +31,45 @@ Check the below list for the version you are updating to for any additional inst
 
 ## Version Specific Instructions
 
+The below lists things you may need to be aware of when upgrading to a newer version of BookStack.
+
+#### Updating to v0.31.0 or higher
+
+**Requirements Change** - The minimum required PHP version has changed from 7.2 to 7.2.5. Additionally, the `Tidy` PHP extension is no longer required.
+
+**GitLab Authentication** - The `read_user` scope will now be passed and is required on the "Application" setup within GitLab. Not having this scope may lead to errors when users attempt to authenticate via GitLab.
+
+**Security & IFrame Usage** - By default BookStack will set headers to prevent usage within an iframe. You can set trusted iframe hosts through the `ALLOWED_IFRAME_HOSTS` option in your `.env` file. See the [security page](/docs/admin/security#iframe-control) for more information on this option.
+
+#### Updating to v0.30.6, v0.30.7 or higher
+
+**Security** - v0.30.6 and v0.30.7 both address issues where page content could be visible to those without permission. If a chapter was visible to a user, but all of it's pages were made not visible, then the details of these pages could be visible. Within the BookStack interface, the names of the pages and preview content could be seen. If the parent book was exported then this would include the content of the pages that had been restricted. If using BookStack v0.30.6, then all non-visible page content could be visible in plaintext exports. Please see the blog release pages for more details: [v0.30.6](/blog/beta-release-v0-30-6/), [v0.30.7](/blog/beta-release-v0-30-7/).
+
+#### Updating to v0.30.5 or higher
+
+**Security** - v0.30.5 fixes an potential vulnerability where a user with edit permissions could perform server-side requests using the export system. Additionally it was found that, if using standard email/password authentication, the system host URL could be manipulated on the forgot password form which could allow for email phishing attempts. Ensure you have set the `APP_URL` option in your `.env` file to help prevent this. Please see the [blog release page for more details](/blog/beta-release-v0-30-5/).
+
+#### Updating to v0.30.4 or higher
+
+**Security** - v0.30.4 fixes a couple of XSS vulnerabilities that could be exploited by untrusted users via page content and page link attachments. Please see the [blog release page for more details](/blog/beta-release-v0-30-4/).
+
+#### Updating to v0.30 or higher
+
+**Security** - Possible Privilege Escalation. During the v0.30 release cycle
+it was advised that current privilege escalation situations are not made clear when applying role permissions.
+Any user with a "Manage app settings", "Manage users" or "Manage roles & role permissions" system permission 
+assigned to one of their roles could technically alter their own permissions to gain wider access.
+A clear advisory of these cases has been added in the UI in v0.30
+but admins are advised to review which users have these permissions with the above in mind.
+
+
+**LDAP & SAML Group Matching** - During the v0.30 release cycle it was found that 
+BookStack roles would be matched to LDAP/SAML groups based upon the role display name, which is expected,
+but only those roles with a matching "name" value would be considered. This "name" field was redundant, 
+and has now been removed, but it would store a cleaned version the first-set name of the role.
+All roles will now be considered before being matched on name which may mean that roles which did not sync before, 
+that would have been expected to based on their name, may now start to sync.
+
 
 #### Updating to v0.29.3 or higher
 
@@ -56,7 +95,7 @@ sudo systemctl restart nginx.service
 
 #### Updating to v0.26 or higher
 
-**Internet Explorer Support** - IE11 Support has now been dropped. We *may* support any critical issues for view-only scenarios otherwise please use a modern browser.
+**Internet Explorer Support** - IE11 Support has now been dropped. Please use a modern browser.
 
 **Translations** - Since many interfaces and lines of text have been updated, It may take a little while for some translations to catch-up. Expect to see more English text than usual if you're using a non-English language option.
 
index 68e1aae22de2fc28b05a90e4cab4a40048dd3dd2..f8c9a8420cd4238c650e341bbe9085f170c080f6 100644 (file)
@@ -128,11 +128,17 @@ PHP has two main variables which effect upload limits. Find your `php.ini` file
 
 If the values of these variables are low increase them to something sensible that's not too high to cause issues. Unless you need something higher 10MB is a sensible value to enter for these values:
 
-```
+```ini
 post_max_size = 10M
 upload_max_filesize = 10M
 ```
 
+If wanting to upload files over 128MB, you may also need to adjust your PHP memory limit like so:
+
+```ini
+memory_limit = 256M
+```
+
 After updating these values ensure you restart your webserver and also PHP if using PHP-FPM or something similar.
 
 #### NGINX
index f77a387dd15a796e78f939227d8d2bf842e580ca..ae1ca0d0c256a49e1be74242c9c894331ce5f762 100644 (file)
@@ -21,7 +21,7 @@ in the admin settings of BookStack.
 body, button, input, select, label, textarea {
   font-family: "Roboto", sans-serif;
 }
-.Codemirror, pre, #markdown-editor-input, .editor-toolbar, .code-base {
+.CodeMirror, pre, #markdown-editor-input, .editor-toolbar, .code-base {
   font-family: monospace;
 }
 </style>
@@ -35,7 +35,7 @@ Here's an example of using the 'Lato' font from [Google Web Fonts](https://fonts
 body, button, input, select, label, textarea {
   font-family: 'Lato', sans-serif;
 }
-.Codemirror, pre, #markdown-editor-input, .editor-toolbar, .code-base {
+.CodeMirror, pre, #markdown-editor-input, .editor-toolbar, .code-base {
   font-family: monospace;
 }
 </style>
index fb556e8bd42efc380c7b98f344ab932f65dde056..adc8a68f3b920e7d01265e9409cfd6480d87e154 100644 (file)
@@ -32,7 +32,7 @@ Bookshelves, Books, chapters and pages have set colour coding in BookStack to en
 
 ### Starting Out
 
-When you start out with your new BookStack instance you can organise things in two ways; You can plan out your book/chapter/page structure or you can let things grow naturally over time. If you know or already have the content which will be going into BookStack then it's probably best to plan early otherwise, if you're starting from scratch, you'll want to let everything find it's own place.
+When you start out with your new BookStack instance you can organise things in two ways; You can plan out your book/chapter/page structure or you can let things grow naturally over time. If you know or already have the content which will be going into BookStack then it's probably best to plan early otherwise, if you're starting from scratch, you'll want to let everything find its own place.
 
-If you decide to grow naturally then you'll likely start with a book for each major category and add pages directly into those books. As you start getting a lot of pages in each book you'll start to use chapters to group those pages. Once a chapter gets too large you may find it better to split it out into it's own book. Within BookStack you can easily move chapters and pages between books and chapters so you shouldn't worry about having to move things around in the future.
+If you decide to grow naturally then you'll likely start with a book for each major category and add pages directly into those books. As you start getting a lot of pages in each book you'll start to use chapters to group those pages. Once a chapter gets too large you may find it better to split it out into its own book. Within BookStack you can easily move chapters and pages between books and chapters so you shouldn't worry about having to move things around in the future.
 
diff --git a/gulpfile.js b/gulpfile.js
deleted file mode 100644 (file)
index c77159d..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-const gulp = require('gulp');
-const plumber = require('gulp-plumber');
-const rename = require('gulp-rename');
-const cleanCss = require('gulp-clean-css');
-const sass = require('gulp-sass');
-
-gulp.task('styles', function() {
-  return gulp.src(['themes/bookstack/sass/**/*.scss'])
-    .pipe(plumber({
-      errorHandler: function (error) {
-        console.log(error.message);
-        this.emit('end');
-    }}))
-    .pipe(sass())
-    .pipe(gulp.dest('themes/bookstack/static/css/'))
-    .pipe(rename({suffix: '.min'}))
-    .pipe(cleanCss())
-    .pipe(gulp.dest('themes/bookstack/static/css/'));
-});
-
-
-gulp.task('default', gulp.series('styles'));
-
-gulp.task('watch', function() {
-  gulp.watch('themes/bookstack/sass/**/*.scss', gulp.series('styles'));
-});
index d735fa00f1e2250feb7099ab90baede7a234e0c0..13397eead94efe9a1ccf543442d03eae90303f08 100644 (file)
@@ -4,84 +4,6 @@
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
-    "abbrev": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
-      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
-      "dev": true
-    },
-    "ajv": {
-      "version": "6.10.2",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
-      "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
-      "dev": true,
-      "requires": {
-        "fast-deep-equal": "^2.0.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
-      }
-    },
-    "amdefine": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
-      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
-      "dev": true
-    },
-    "ansi-colors": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz",
-      "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==",
-      "dev": true,
-      "requires": {
-        "ansi-wrap": "^0.1.0"
-      }
-    },
-    "ansi-cyan": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz",
-      "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=",
-      "dev": true,
-      "requires": {
-        "ansi-wrap": "0.1.0"
-      }
-    },
-    "ansi-gray": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
-      "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=",
-      "dev": true,
-      "requires": {
-        "ansi-wrap": "0.1.0"
-      }
-    },
-    "ansi-red": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz",
-      "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=",
-      "dev": true,
-      "requires": {
-        "ansi-wrap": "0.1.0"
-      }
-    },
-    "ansi-regex": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-      "dev": true
-    },
-    "ansi-styles": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-      "dev": true
-    },
-    "ansi-wrap": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
-      "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
-      "dev": true
-    },
     "anymatch": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
         "normalize-path": "^2.1.1"
       }
     },
-    "append-buffer": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz",
-      "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=",
-      "dev": true,
-      "requires": {
-        "buffer-equal": "^1.0.0"
-      }
-    },
-    "aproba": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
-      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
-      "dev": true
-    },
-    "archy": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
-      "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
-      "dev": true
-    },
-    "are-we-there-yet": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
-      "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
-      "dev": true,
-      "requires": {
-        "delegates": "^1.0.0",
-        "readable-stream": "^2.0.6"
-      }
-    },
     "arr-diff": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
       "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
       "dev": true
     },
-    "arr-filter": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz",
-      "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=",
-      "dev": true,
-      "requires": {
-        "make-iterator": "^1.0.0"
-      }
-    },
     "arr-flatten": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
       "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
       "dev": true
     },
-    "arr-map": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz",
-      "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=",
-      "dev": true,
-      "requires": {
-        "make-iterator": "^1.0.0"
-      }
-    },
     "arr-union": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
       "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
       "dev": true
     },
-    "array-each": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
-      "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=",
-      "dev": true
-    },
-    "array-find-index": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
-      "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
-      "dev": true
-    },
-    "array-initial": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz",
-      "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=",
-      "dev": true,
-      "requires": {
-        "array-slice": "^1.0.0",
-        "is-number": "^4.0.0"
-      },
-      "dependencies": {
-        "is-number": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
-          "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
-          "dev": true
-        }
-      }
-    },
-    "array-last": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz",
-      "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==",
-      "dev": true,
-      "requires": {
-        "is-number": "^4.0.0"
-      },
-      "dependencies": {
-        "is-number": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
-          "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
-          "dev": true
-        }
-      }
-    },
-    "array-slice": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
-      "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
-      "dev": true
-    },
-    "array-sort": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz",
-      "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==",
-      "dev": true,
-      "requires": {
-        "default-compare": "^1.0.0",
-        "get-value": "^2.0.6",
-        "kind-of": "^5.0.2"
-      },
-      "dependencies": {
-        "kind-of": {
-          "version": "5.1.0",
-          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
-          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
-          "dev": true
-        }
-      }
-    },
     "array-unique": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
       "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
       "dev": true
     },
-    "asn1": {
-      "version": "0.2.4",
-      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
-      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
-      "dev": true,
-      "requires": {
-        "safer-buffer": "~2.1.0"
-      }
-    },
-    "assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
-      "dev": true
-    },
     "assign-symbols": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
       "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
       "dev": true
     },
-    "async-done": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.1.tgz",
-      "integrity": "sha512-R1BaUeJ4PMoLNJuk+0tLJgjmEqVsdN118+Z8O+alhnQDQgy0kmD5Mqi0DNEmMx2LM0Ed5yekKu+ZXYvIHceicg==",
-      "dev": true,
-      "requires": {
-        "end-of-stream": "^1.1.0",
-        "once": "^1.3.2",
-        "process-nextick-args": "^1.0.7",
-        "stream-exhaust": "^1.0.1"
-      }
-    },
     "async-each": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
       "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
       "dev": true
     },
-    "async-foreach": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
-      "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
-      "dev": true
-    },
-    "async-settle": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz",
-      "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=",
-      "dev": true,
-      "requires": {
-        "async-done": "^1.2.2"
-      }
-    },
-    "asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
-      "dev": true
-    },
     "atob": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
       "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
       "dev": true
     },
-    "aws-sign2": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
-      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
-      "dev": true
-    },
-    "aws4": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.0.tgz",
-      "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==",
-      "dev": true
-    },
-    "bach": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz",
-      "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=",
-      "dev": true,
-      "requires": {
-        "arr-filter": "^1.1.1",
-        "arr-flatten": "^1.0.1",
-        "arr-map": "^2.0.0",
-        "array-each": "^1.0.0",
-        "array-initial": "^1.0.0",
-        "array-last": "^1.1.1",
-        "async-done": "^1.2.2",
-        "async-settle": "^1.0.0",
-        "now-and-later": "^2.0.0"
-      }
-    },
     "balanced-match": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
         }
       }
     },
-    "bcrypt-pbkdf": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
-      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
-      "dev": true,
-      "requires": {
-        "tweetnacl": "^0.14.3"
-      }
-    },
     "binary-extensions": {
       "version": "1.13.1",
       "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
       "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
       "dev": true
     },
-    "block-stream": {
-      "version": "0.0.9",
-      "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
-      "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
-      "dev": true,
-      "requires": {
-        "inherits": "~2.0.0"
-      }
-    },
     "brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
         }
       }
     },
-    "buffer-equal": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz",
-      "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=",
-      "dev": true
-    },
-    "buffer-from": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
-      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
-      "dev": true
-    },
     "builtin-modules": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
         "unset-value": "^1.0.0"
       }
     },
-    "camelcase": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
-      "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
-      "dev": true
-    },
-    "camelcase-keys": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
-      "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
-      "dev": true,
-      "requires": {
-        "camelcase": "^2.0.0",
-        "map-obj": "^1.0.0"
-      },
-      "dependencies": {
-        "camelcase": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
-          "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
-          "dev": true
-        }
-      }
-    },
-    "caseless": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
-      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
-      "dev": true
-    },
-    "chalk": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+    "call-bind": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz",
+      "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==",
       "dev": true,
       "requires": {
-        "ansi-styles": "^2.2.1",
-        "escape-string-regexp": "^1.0.2",
-        "has-ansi": "^2.0.0",
-        "strip-ansi": "^3.0.0",
-        "supports-color": "^2.0.0"
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.0"
       }
     },
     "chokidar": {
         }
       }
     },
-    "cliui": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
-      "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
-      "dev": true,
-      "requires": {
-        "string-width": "^1.0.1",
-        "strip-ansi": "^3.0.1",
-        "wrap-ansi": "^2.0.0"
-      }
-    },
-    "clone-buffer": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
-      "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=",
-      "dev": true
-    },
-    "cloneable-readable": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz",
-      "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==",
-      "dev": true,
-      "requires": {
-        "inherits": "^2.0.1",
-        "process-nextick-args": "^2.0.0",
-        "readable-stream": "^2.3.5"
-      },
-      "dependencies": {
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
-        },
-        "process-nextick-args": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
-          "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
-          "dev": true,
-          "requires": {
-            "core-util-is": "~1.0.0",
-            "inherits": "~2.0.3",
-            "isarray": "~1.0.0",
-            "process-nextick-args": "~2.0.0",
-            "safe-buffer": "~5.1.1",
-            "string_decoder": "~1.1.1",
-            "util-deprecate": "~1.0.1"
-          }
-        },
-        "string_decoder": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "~5.1.0"
-          }
-        }
-      }
-    },
-    "code-point-at": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
-      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
-      "dev": true
-    },
-    "collection-map": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz",
-      "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=",
-      "dev": true,
-      "requires": {
-        "arr-map": "^2.0.2",
-        "for-own": "^1.0.0",
-        "make-iterator": "^1.0.0"
-      }
-    },
     "collection-visit": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
       "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
       "dev": true
     },
-    "color-support": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
-      "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
-      "dev": true
-    },
-    "combined-stream": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
-      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
-      "dev": true,
-      "requires": {
-        "delayed-stream": "~1.0.0"
-      }
-    },
     "component-emitter": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
       "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
       "dev": true
     },
-    "concat-stream": {
-      "version": "1.6.2",
-      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
-      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
-      "dev": true,
-      "requires": {
-        "buffer-from": "^1.0.0",
-        "inherits": "^2.0.3",
-        "readable-stream": "^2.2.2",
-        "typedarray": "^0.0.6"
-      },
-      "dependencies": {
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
-        },
-        "process-nextick-args": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
-          "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
-          "dev": true,
-          "requires": {
-            "core-util-is": "~1.0.0",
-            "inherits": "~2.0.3",
-            "isarray": "~1.0.0",
-            "process-nextick-args": "~2.0.0",
-            "safe-buffer": "~5.1.1",
-            "string_decoder": "~1.1.1",
-            "util-deprecate": "~1.0.1"
-          }
-        },
-        "string_decoder": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "~5.1.0"
-          }
-        }
-      }
-    },
-    "console-control-strings": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
-      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
-      "dev": true
-    },
-    "convert-source-map": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
-      "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
-      "dev": true,
-      "requires": {
-        "safe-buffer": "~5.1.1"
-      }
-    },
-    "copy-descriptor": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
-      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
-      "dev": true
-    },
-    "copy-props": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz",
-      "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==",
-      "dev": true,
-      "requires": {
-        "each-props": "^1.3.0",
-        "is-plain-object": "^2.0.1"
-      }
-    },
-    "core-util-is": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
-      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
-      "dev": true
-    },
-    "cross-spawn": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
-      "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
-      "dev": true,
-      "requires": {
-        "lru-cache": "^4.0.1",
-        "which": "^1.2.9"
-      }
-    },
-    "currently-unhandled": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
-      "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
-      "dev": true,
-      "requires": {
-        "array-find-index": "^1.0.1"
-      }
-    },
-    "d": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
-      "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
-      "dev": true,
-      "requires": {
-        "es5-ext": "^0.10.9"
-      }
-    },
-    "dashdash": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "^1.0.0"
-      }
-    },
-    "debug": {
-      "version": "2.6.9",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+    "copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+      "dev": true
+    },
+    "debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
       "dev": true,
       "requires": {
         "ms": "2.0.0"
       }
     },
-    "decamelize": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
-      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
-      "dev": true
-    },
     "decode-uri-component": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
       "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
       "dev": true
     },
-    "default-compare": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz",
-      "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==",
-      "dev": true,
-      "requires": {
-        "kind-of": "^5.0.2"
-      },
-      "dependencies": {
-        "kind-of": {
-          "version": "5.1.0",
-          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
-          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
-          "dev": true
-        }
-      }
-    },
-    "default-resolution": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz",
-      "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=",
-      "dev": true
-    },
     "define-properties": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
         }
       }
     },
-    "delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
-      "dev": true
-    },
-    "delegates": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
-      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
-      "dev": true
-    },
-    "detect-file": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
-      "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
-      "dev": true
-    },
-    "duplexify": {
-      "version": "3.7.1",
-      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
-      "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
-      "dev": true,
-      "requires": {
-        "end-of-stream": "^1.0.0",
-        "inherits": "^2.0.1",
-        "readable-stream": "^2.0.0",
-        "stream-shift": "^1.0.0"
-      },
-      "dependencies": {
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
-        },
-        "process-nextick-args": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
-          "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
-          "dev": true,
-          "requires": {
-            "core-util-is": "~1.0.0",
-            "inherits": "~2.0.3",
-            "isarray": "~1.0.0",
-            "process-nextick-args": "~2.0.0",
-            "safe-buffer": "~5.1.1",
-            "string_decoder": "~1.1.1",
-            "util-deprecate": "~1.0.1"
-          }
-        },
-        "string_decoder": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "~5.1.0"
-          }
-        }
-      }
-    },
-    "each-props": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz",
-      "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==",
-      "dev": true,
-      "requires": {
-        "is-plain-object": "^2.0.1",
-        "object.defaults": "^1.1.0"
-      }
-    },
-    "ecc-jsbn": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
-      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
-      "dev": true,
-      "requires": {
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.1.0"
-      }
-    },
-    "end-of-stream": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
-      "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
-      "dev": true,
-      "requires": {
-        "once": "^1.4.0"
-      }
-    },
     "error-ex": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
         "is-arrayish": "^0.2.1"
       }
     },
-    "es5-ext": {
-      "version": "0.10.50",
-      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.50.tgz",
-      "integrity": "sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw==",
-      "dev": true,
-      "requires": {
-        "es6-iterator": "~2.0.3",
-        "es6-symbol": "~3.1.1",
-        "next-tick": "^1.0.0"
-      }
-    },
-    "es6-iterator": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
-      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
-      "dev": true,
-      "requires": {
-        "d": "1",
-        "es5-ext": "^0.10.35",
-        "es6-symbol": "^3.1.1"
-      }
-    },
-    "es6-symbol": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
-      "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+    "es-abstract": {
+      "version": "1.18.0-next.1",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
+      "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
       "dev": true,
       "requires": {
-        "d": "1",
-        "es5-ext": "~0.10.14"
-      }
-    },
-    "es6-weak-map": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
-      "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
+        "es-to-primitive": "^1.2.1",
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1",
+        "is-callable": "^1.2.2",
+        "is-negative-zero": "^2.0.0",
+        "is-regex": "^1.1.1",
+        "object-inspect": "^1.8.0",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.1",
+        "string.prototype.trimend": "^1.0.1",
+        "string.prototype.trimstart": "^1.0.1"
+      }
+    },
+    "es-to-primitive": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+      "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
       "dev": true,
       "requires": {
-        "d": "1",
-        "es5-ext": "^0.10.14",
-        "es6-iterator": "^2.0.1",
-        "es6-symbol": "^3.1.1"
+        "is-callable": "^1.1.4",
+        "is-date-object": "^1.0.1",
+        "is-symbol": "^1.0.2"
       }
     },
     "escape-string-regexp": {
         }
       }
     },
-    "expand-tilde": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
-      "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
-      "dev": true,
-      "requires": {
-        "homedir-polyfill": "^1.0.1"
-      }
-    },
-    "extend": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
-      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
-      "dev": true
-    },
     "extend-shallow": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
         }
       }
     },
-    "extsprintf": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
-      "dev": true
-    },
-    "fast-deep-equal": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
-      "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
-      "dev": true
-    },
-    "fast-json-stable-stringify": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
-      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
-      "dev": true
-    },
     "fill-range": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
         }
       }
     },
-    "find-up": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
-      "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
-      "dev": true,
-      "requires": {
-        "path-exists": "^2.0.0",
-        "pinkie-promise": "^2.0.0"
-      }
-    },
-    "findup-sync": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz",
-      "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==",
-      "dev": true,
-      "requires": {
-        "detect-file": "^1.0.0",
-        "is-glob": "^4.0.0",
-        "micromatch": "^3.0.4",
-        "resolve-dir": "^1.0.1"
-      }
+    "for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true
     },
-    "fined": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz",
-      "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==",
+    "fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
       "dev": true,
       "requires": {
-        "expand-tilde": "^2.0.2",
-        "is-plain-object": "^2.0.3",
-        "object.defaults": "^1.1.0",
-        "object.pick": "^1.2.0",
-        "parse-filepath": "^1.0.1"
+        "map-cache": "^0.2.2"
       }
     },
-    "flagged-respawn": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
-      "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==",
-      "dev": true
-    },
-    "flush-write-stream": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
-      "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
+    "fsevents": {
+      "version": "1.2.9",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz",
+      "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==",
       "dev": true,
+      "optional": true,
       "requires": {
-        "inherits": "^2.0.3",
-        "readable-stream": "^2.3.6"
+        "nan": "^2.12.1",
+        "node-pre-gyp": "^0.12.0"
       },
       "dependencies": {
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
+        "abbrev": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
         },
-        "process-nextick-args": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
-          "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
-          "dev": true,
-          "requires": {
-            "core-util-is": "~1.0.0",
-            "inherits": "~2.0.3",
-            "isarray": "~1.0.0",
-            "process-nextick-args": "~2.0.0",
-            "safe-buffer": "~5.1.1",
-            "string_decoder": "~1.1.1",
-            "util-deprecate": "~1.0.1"
-          }
-        },
-        "string_decoder": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "~5.1.0"
-          }
-        }
-      }
-    },
-    "for-in": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
-      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
-      "dev": true
-    },
-    "for-own": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
-      "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
-      "dev": true,
-      "requires": {
-        "for-in": "^1.0.1"
-      }
-    },
-    "forever-agent": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
-      "dev": true
-    },
-    "form-data": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
-      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
-      "dev": true,
-      "requires": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.6",
-        "mime-types": "^2.1.12"
-      }
-    },
-    "fragment-cache": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
-      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
-      "dev": true,
-      "requires": {
-        "map-cache": "^0.2.2"
-      }
-    },
-    "fs-mkdirp-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
-      "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "^4.1.11",
-        "through2": "^2.0.3"
-      }
-    },
-    "fs.realpath": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
-      "dev": true
-    },
-    "fsevents": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz",
-      "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==",
-      "dev": true,
-      "optional": true,
-      "requires": {
-        "nan": "^2.12.1",
-        "node-pre-gyp": "^0.12.0"
-      },
-      "dependencies": {
-        "abbrev": {
-          "version": "1.1.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
-        "ansi-regex": {
-          "version": "2.1.1",
-          "bundled": true,
-          "dev": true,
-          "optional": true
+        "ansi-regex": {
+          "version": "2.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
         },
         "aproba": {
           "version": "1.2.0",
           "dev": true,
           "optional": true
         },
-        "ini": {
-          "version": "1.3.5",
-          "bundled": true,
-          "dev": true,
-          "optional": true
-        },
         "is-fullwidth-code-point": {
           "version": "1.0.0",
           "bundled": true,
         }
       }
     },
-    "fstream": {
-      "version": "1.0.12",
-      "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
-      "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "^4.1.2",
-        "inherits": "~2.0.0",
-        "mkdirp": ">=0.5 0",
-        "rimraf": "2"
-      }
-    },
     "function-bind": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
       "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
       "dev": true
     },
-    "gauge": {
-      "version": "2.7.4",
-      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
-      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
-      "dev": true,
-      "requires": {
-        "aproba": "^1.0.3",
-        "console-control-strings": "^1.0.0",
-        "has-unicode": "^2.0.0",
-        "object-assign": "^4.1.0",
-        "signal-exit": "^3.0.0",
-        "string-width": "^1.0.1",
-        "strip-ansi": "^3.0.1",
-        "wide-align": "^1.1.0"
-      }
-    },
-    "gaze": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
-      "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
+    "get-intrinsic": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz",
+      "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==",
       "dev": true,
       "requires": {
-        "globule": "^1.0.0"
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1"
       }
     },
-    "get-caller-file": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
-      "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
-      "dev": true
-    },
-    "get-stdin": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
-      "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
-      "dev": true
-    },
     "get-value": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
       "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
       "dev": true
     },
-    "getpass": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "^1.0.0"
-      }
-    },
-    "glob": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
-      "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
-      "dev": true,
-      "requires": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.0.4",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
-      }
-    },
     "glob-parent": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
         }
       }
     },
-    "glob-stream": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz",
-      "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=",
-      "dev": true,
-      "requires": {
-        "extend": "^3.0.0",
-        "glob": "^7.1.1",
-        "glob-parent": "^3.1.0",
-        "is-negated-glob": "^1.0.0",
-        "ordered-read-streams": "^1.0.0",
-        "pumpify": "^1.3.5",
-        "readable-stream": "^2.1.5",
-        "remove-trailing-separator": "^1.0.1",
-        "to-absolute-glob": "^2.0.0",
-        "unique-stream": "^2.0.2"
-      },
-      "dependencies": {
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
-        },
-        "process-nextick-args": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
-          "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
-          "dev": true,
-          "requires": {
-            "core-util-is": "~1.0.0",
-            "inherits": "~2.0.3",
-            "isarray": "~1.0.0",
-            "process-nextick-args": "~2.0.0",
-            "safe-buffer": "~5.1.1",
-            "string_decoder": "~1.1.1",
-            "util-deprecate": "~1.0.1"
-          }
-        },
-        "string_decoder": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "~5.1.0"
-          }
-        }
-      }
-    },
-    "glob-watcher": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz",
-      "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==",
-      "dev": true,
-      "requires": {
-        "anymatch": "^2.0.0",
-        "async-done": "^1.2.0",
-        "chokidar": "^2.0.0",
-        "is-negated-glob": "^1.0.0",
-        "just-debounce": "^1.0.0",
-        "object.defaults": "^1.1.0"
-      }
+    "graceful-fs": {
+      "version": "4.1.15",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
+      "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
+      "dev": true
     },
-    "global-modules": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
-      "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+    "has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
       "dev": true,
       "requires": {
-        "global-prefix": "^1.0.1",
-        "is-windows": "^1.0.1",
-        "resolve-dir": "^1.0.0"
+        "function-bind": "^1.1.1"
       }
     },
-    "global-prefix": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
-      "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
-      "dev": true,
-      "requires": {
-        "expand-tilde": "^2.0.2",
-        "homedir-polyfill": "^1.0.1",
-        "ini": "^1.3.4",
-        "is-windows": "^1.0.1",
-        "which": "^1.2.14"
-      }
+    "has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "dev": true
     },
-    "globule": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
-      "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==",
-      "dev": true,
-      "requires": {
-        "glob": "~7.1.1",
-        "lodash": "~4.17.10",
-        "minimatch": "~3.0.2"
-      }
+    "has-symbols": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+      "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+      "dev": true
     },
-    "glogg": {
+    "has-value": {
       "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz",
-      "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
       "dev": true,
       "requires": {
-        "sparkles": "^1.0.0"
+        "get-value": "^2.0.6",
+        "has-values": "^1.0.0",
+        "isobject": "^3.0.0"
       }
     },
-    "graceful-fs": {
-      "version": "4.1.15",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
-      "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
-      "dev": true
-    },
-    "gulp": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.1.tgz",
-      "integrity": "sha512-yDVtVunxrAdsk7rIV/b7lVSBifPN1Eqe6wTjsESGrFcL+MEVzaaeNTkpUuGTUptloSOU+8oJm/lBJbgPV+tMAw==",
+    "has-values": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
       "dev": true,
       "requires": {
-        "glob-watcher": "^5.0.3",
-        "gulp-cli": "^2.2.0",
-        "undertaker": "^1.2.1",
-        "vinyl-fs": "^3.0.0"
+        "is-number": "^3.0.0",
+        "kind-of": "^4.0.0"
       },
       "dependencies": {
-        "fancy-log": {
-          "version": "1.3.3",
-          "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz",
-          "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==",
-          "dev": true,
-          "requires": {
-            "ansi-gray": "^0.1.1",
-            "color-support": "^1.1.3",
-            "parse-node-version": "^1.0.0",
-            "time-stamp": "^1.0.0"
-          }
-        },
-        "gulp-cli": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.2.0.tgz",
-          "integrity": "sha512-rGs3bVYHdyJpLqR0TUBnlcZ1O5O++Zs4bA0ajm+zr3WFCfiSLjGwoCBqFs18wzN+ZxahT9DkOK5nDf26iDsWjA==",
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
           "dev": true,
           "requires": {
-            "ansi-colors": "^1.0.1",
-            "archy": "^1.0.0",
-            "array-sort": "^1.0.0",
-            "color-support": "^1.1.3",
-            "concat-stream": "^1.6.0",
-            "copy-props": "^2.0.1",
-            "fancy-log": "^1.3.2",
-            "gulplog": "^1.0.0",
-            "interpret": "^1.1.0",
-            "isobject": "^3.0.1",
-            "liftoff": "^3.1.0",
-            "matchdep": "^2.0.0",
-            "mute-stdout": "^1.0.0",
-            "pretty-hrtime": "^1.0.0",
-            "replace-homedir": "^1.0.0",
-            "semver-greatest-satisfied-range": "^1.1.0",
-            "v8flags": "^3.0.1",
-            "yargs": "^7.1.0"
+            "is-buffer": "^1.1.5"
           }
         }
       }
     },
-    "gulp-clean-css": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/gulp-clean-css/-/gulp-clean-css-4.2.0.tgz",
-      "integrity": "sha512-r4zQsSOAK2UYUL/ipkAVCTRg/2CLZ2A+oPVORopBximRksJ6qy3EX1KGrIWT4ZrHxz3Hlobb1yyJtqiut7DNjA==",
+    "hosted-git-info": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
+      "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
+      "dev": true
+    },
+    "inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+      "dev": true
+    },
+    "ini": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+      "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+      "dev": true,
+      "optional": true
+    },
+    "is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
       "dev": true,
       "requires": {
-        "clean-css": "4.2.1",
-        "plugin-error": "1.0.1",
-        "through2": "3.0.1",
-        "vinyl-sourcemaps-apply": "0.2.1"
+        "kind-of": "^3.0.2"
       },
       "dependencies": {
-        "clean-css": {
-          "version": "4.2.1",
-          "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
-          "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==",
-          "dev": true,
-          "requires": {
-            "source-map": "~0.6.0"
-          }
-        },
-        "readable-stream": {
-          "version": "3.3.0",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.3.0.tgz",
-          "integrity": "sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==",
-          "dev": true,
-          "requires": {
-            "inherits": "^2.0.3",
-            "string_decoder": "^1.1.1",
-            "util-deprecate": "^1.0.1"
-          }
-        },
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-          "dev": true
-        },
-        "string_decoder": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz",
-          "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "~5.1.0"
-          }
-        },
-        "through2": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz",
-          "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==",
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
           "dev": true,
           "requires": {
-            "readable-stream": "2 || 3"
-          }
-        }
-      }
-    },
-    "gulp-plumber": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/gulp-plumber/-/gulp-plumber-1.2.1.tgz",
-      "integrity": "sha512-mctAi9msEAG7XzW5ytDVZ9PxWMzzi1pS2rBH7lA095DhMa6KEXjm+St0GOCc567pJKJ/oCvosVAZEpAey0q2eQ==",
-      "dev": true,
-      "requires": {
-        "chalk": "^1.1.3",
-        "fancy-log": "^1.3.2",
-        "plugin-error": "^0.1.2",
-        "through2": "^2.0.3"
-      },
-      "dependencies": {
-        "arr-diff": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz",
-          "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=",
-          "dev": true,
-          "requires": {
-            "arr-flatten": "^1.0.1",
-            "array-slice": "^0.2.3"
-          }
-        },
-        "arr-union": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz",
-          "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=",
-          "dev": true
-        },
-        "array-slice": {
-          "version": "0.2.3",
-          "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
-          "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=",
-          "dev": true
-        },
-        "extend-shallow": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz",
-          "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=",
-          "dev": true,
-          "requires": {
-            "kind-of": "^1.1.0"
-          }
-        },
-        "fancy-log": {
-          "version": "1.3.3",
-          "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz",
-          "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==",
-          "dev": true,
-          "requires": {
-            "ansi-gray": "^0.1.1",
-            "color-support": "^1.1.3",
-            "parse-node-version": "^1.0.0",
-            "time-stamp": "^1.0.0"
-          }
-        },
-        "kind-of": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
-          "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
-          "dev": true
-        },
-        "plugin-error": {
-          "version": "0.1.2",
-          "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz",
-          "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=",
-          "dev": true,
-          "requires": {
-            "ansi-cyan": "^0.1.1",
-            "ansi-red": "^0.1.1",
-            "arr-diff": "^1.0.1",
-            "arr-union": "^2.0.1",
-            "extend-shallow": "^1.1.2"
-          }
-        }
-      }
-    },
-    "gulp-rename": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.4.0.tgz",
-      "integrity": "sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg==",
-      "dev": true
-    },
-    "gulp-sass": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-4.0.2.tgz",
-      "integrity": "sha512-q8psj4+aDrblJMMtRxihNBdovfzGrXJp1l4JU0Sz4b/Mhsi2DPrKFYCGDwjIWRENs04ELVHxdOJQ7Vs98OFohg==",
-      "dev": true,
-      "requires": {
-        "chalk": "^2.3.0",
-        "lodash.clonedeep": "^4.3.2",
-        "node-sass": "^4.8.3",
-        "plugin-error": "^1.0.1",
-        "replace-ext": "^1.0.0",
-        "strip-ansi": "^4.0.0",
-        "through2": "^2.0.0",
-        "vinyl-sourcemaps-apply": "^0.2.0"
-      },
-      "dependencies": {
-        "ansi-regex": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
-          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
-          "dev": true
-        },
-        "ansi-styles": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-          "dev": true,
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "strip-ansi": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^3.0.0"
-          }
-        },
-        "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
-        }
-      }
-    },
-    "gulplog": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz",
-      "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=",
-      "dev": true,
-      "requires": {
-        "glogg": "^1.0.0"
-      }
-    },
-    "har-schema": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
-      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
-      "dev": true
-    },
-    "har-validator": {
-      "version": "5.1.3",
-      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
-      "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
-      "dev": true,
-      "requires": {
-        "ajv": "^6.5.5",
-        "har-schema": "^2.0.0"
-      }
-    },
-    "has-ansi": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
-      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
-      "dev": true,
-      "requires": {
-        "ansi-regex": "^2.0.0"
-      }
-    },
-    "has-flag": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-      "dev": true
-    },
-    "has-symbols": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
-      "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
-      "dev": true
-    },
-    "has-unicode": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
-      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
-      "dev": true
-    },
-    "has-value": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
-      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
-      "dev": true,
-      "requires": {
-        "get-value": "^2.0.6",
-        "has-values": "^1.0.0",
-        "isobject": "^3.0.0"
-      }
-    },
-    "has-values": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
-      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
-      "dev": true,
-      "requires": {
-        "is-number": "^3.0.0",
-        "kind-of": "^4.0.0"
-      },
-      "dependencies": {
-        "kind-of": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
-          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
-          "dev": true,
-          "requires": {
-            "is-buffer": "^1.1.5"
-          }
-        }
-      }
-    },
-    "homedir-polyfill": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
-      "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
-      "dev": true,
-      "requires": {
-        "parse-passwd": "^1.0.0"
-      }
-    },
-    "hosted-git-info": {
-      "version": "2.7.1",
-      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
-      "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
-      "dev": true
-    },
-    "http-signature": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
-      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "^1.0.0",
-        "jsprim": "^1.2.2",
-        "sshpk": "^1.7.0"
-      }
-    },
-    "in-publish": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
-      "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=",
-      "dev": true
-    },
-    "indent-string": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
-      "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
-      "dev": true,
-      "requires": {
-        "repeating": "^2.0.0"
-      }
-    },
-    "inflight": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
-      "dev": true,
-      "requires": {
-        "once": "^1.3.0",
-        "wrappy": "1"
-      }
-    },
-    "inherits": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
-      "dev": true
-    },
-    "ini": {
-      "version": "1.3.5",
-      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
-      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
-      "dev": true
-    },
-    "interpret": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz",
-      "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==",
-      "dev": true
-    },
-    "invert-kv": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
-      "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
-      "dev": true
-    },
-    "is-absolute": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
-      "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
-      "dev": true,
-      "requires": {
-        "is-relative": "^1.0.0",
-        "is-windows": "^1.0.1"
-      }
-    },
-    "is-accessor-descriptor": {
-      "version": "0.1.6",
-      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
-      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
-      "dev": true,
-      "requires": {
-        "kind-of": "^3.0.2"
-      },
-      "dependencies": {
-        "kind-of": {
-          "version": "3.2.2",
-          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-          "dev": true,
-          "requires": {
-            "is-buffer": "^1.1.5"
+            "is-buffer": "^1.1.5"
           }
         }
       }
         "builtin-modules": "^1.0.0"
       }
     },
+    "is-callable": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
+      "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
+      "dev": true
+    },
     "is-data-descriptor": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
         }
       }
     },
+    "is-date-object": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
+      "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
+      "dev": true
+    },
     "is-descriptor": {
       "version": "0.1.6",
       "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
       "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
       "dev": true
     },
-    "is-finite": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
-      "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
-      "dev": true,
-      "requires": {
-        "number-is-nan": "^1.0.0"
-      }
-    },
-    "is-fullwidth-code-point": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
-      "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
-      "dev": true,
-      "requires": {
-        "number-is-nan": "^1.0.0"
-      }
-    },
     "is-glob": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
         "is-extglob": "^2.1.1"
       }
     },
-    "is-negated-glob": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
-      "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=",
+    "is-negative-zero": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
+      "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
       "dev": true
     },
     "is-number": {
         "isobject": "^3.0.1"
       }
     },
-    "is-relative": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
-      "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+    "is-regex": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
+      "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
       "dev": true,
       "requires": {
-        "is-unc-path": "^1.0.0"
+        "has-symbols": "^1.0.1"
       }
     },
-    "is-typedarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
-      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
-      "dev": true
-    },
-    "is-unc-path": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
-      "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+    "is-symbol": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
+      "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
       "dev": true,
       "requires": {
-        "unc-path-regex": "^0.1.2"
+        "has-symbols": "^1.0.1"
       }
     },
-    "is-utf8": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
-      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
-      "dev": true
-    },
-    "is-valid-glob": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
-      "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=",
-      "dev": true
-    },
     "is-windows": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
       "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
       "dev": true
     },
-    "isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-      "dev": true
-    },
     "isexe": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
       "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
       "dev": true
     },
-    "isstream": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
-      "dev": true
-    },
-    "js-base64": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz",
-      "integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==",
-      "dev": true
-    },
-    "jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+    "json-parse-better-errors": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
       "dev": true
     },
-    "json-schema": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+    "kind-of": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
       "dev": true
     },
-    "json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true
-    },
-    "json-stable-stringify-without-jsonify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
-      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
-      "dev": true
-    },
-    "json-stringify-safe": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
-      "dev": true
-    },
-    "jsprim": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
-      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "1.0.0",
-        "extsprintf": "1.3.0",
-        "json-schema": "0.2.3",
-        "verror": "1.10.0"
-      }
-    },
-    "just-debounce": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz",
-      "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=",
-      "dev": true
-    },
-    "kind-of": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
-      "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
-      "dev": true
-    },
-    "last-run": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz",
-      "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=",
-      "dev": true,
-      "requires": {
-        "default-resolution": "^2.0.0",
-        "es6-weak-map": "^2.0.1"
-      }
-    },
-    "lazystream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
-      "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
-      "dev": true,
-      "requires": {
-        "readable-stream": "^2.0.5"
-      },
-      "dependencies": {
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
-        },
-        "process-nextick-args": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
-          "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
-          "dev": true,
-          "requires": {
-            "core-util-is": "~1.0.0",
-            "inherits": "~2.0.3",
-            "isarray": "~1.0.0",
-            "process-nextick-args": "~2.0.0",
-            "safe-buffer": "~5.1.1",
-            "string_decoder": "~1.1.1",
-            "util-deprecate": "~1.0.1"
-          }
-        },
-        "string_decoder": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "~5.1.0"
-          }
-        }
-      }
-    },
-    "lcid": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
-      "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
-      "dev": true,
-      "requires": {
-        "invert-kv": "^1.0.0"
-      }
-    },
-    "lead": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz",
-      "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=",
-      "dev": true,
-      "requires": {
-        "flush-write-stream": "^1.0.2"
-      }
-    },
-    "liftoff": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz",
-      "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==",
-      "dev": true,
-      "requires": {
-        "extend": "^3.0.0",
-        "findup-sync": "^3.0.0",
-        "fined": "^1.0.1",
-        "flagged-respawn": "^1.0.0",
-        "is-plain-object": "^2.0.4",
-        "object.map": "^1.0.0",
-        "rechoir": "^0.6.2",
-        "resolve": "^1.1.7"
-      }
-    },
-    "load-json-file": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
-      "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "^4.1.2",
-        "parse-json": "^2.2.0",
-        "pify": "^2.0.0",
-        "pinkie-promise": "^2.0.0",
-        "strip-bom": "^2.0.0"
-      }
-    },
-    "lodash": {
-      "version": "4.17.15",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
-      "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
-      "dev": true
-    },
-    "lodash.clonedeep": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
-      "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
-      "dev": true
-    },
-    "loud-rejection": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
-      "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
-      "dev": true,
-      "requires": {
-        "currently-unhandled": "^0.4.1",
-        "signal-exit": "^3.0.0"
-      }
-    },
-    "lru-cache": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
-      "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
-      "dev": true,
-      "requires": {
-        "pseudomap": "^1.0.2",
-        "yallist": "^2.1.2"
-      }
-    },
-    "make-iterator": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
-      "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
-      "dev": true,
-      "requires": {
-        "kind-of": "^6.0.2"
-      }
-    },
-    "map-cache": {
-      "version": "0.2.2",
-      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
-      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
-      "dev": true
-    },
-    "map-obj": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
-      "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+    "map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
       "dev": true
     },
     "map-visit": {
         "object-visit": "^1.0.0"
       }
     },
-    "matchdep": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz",
-      "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=",
-      "dev": true,
-      "requires": {
-        "findup-sync": "^2.0.0",
-        "micromatch": "^3.0.4",
-        "resolve": "^1.4.0",
-        "stack-trace": "0.0.10"
-      },
-      "dependencies": {
-        "findup-sync": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
-          "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=",
-          "dev": true,
-          "requires": {
-            "detect-file": "^1.0.0",
-            "is-glob": "^3.1.0",
-            "micromatch": "^3.0.4",
-            "resolve-dir": "^1.0.1"
-          }
-        },
-        "is-glob": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
-          "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
-          "dev": true,
-          "requires": {
-            "is-extglob": "^2.1.0"
-          }
-        }
-      }
-    },
-    "meow": {
-      "version": "3.7.0",
-      "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
-      "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
-      "dev": true,
-      "requires": {
-        "camelcase-keys": "^2.0.0",
-        "decamelize": "^1.1.2",
-        "loud-rejection": "^1.0.0",
-        "map-obj": "^1.0.1",
-        "minimist": "^1.1.3",
-        "normalize-package-data": "^2.3.4",
-        "object-assign": "^4.0.1",
-        "read-pkg-up": "^1.0.1",
-        "redent": "^1.0.0",
-        "trim-newlines": "^1.0.0"
-      }
+    "memorystream": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
+      "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=",
+      "dev": true
     },
     "micromatch": {
       "version": "3.1.10",
         "to-regex": "^3.0.2"
       }
     },
-    "mime-db": {
-      "version": "1.42.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz",
-      "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==",
-      "dev": true
-    },
-    "mime-types": {
-      "version": "2.1.25",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz",
-      "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==",
-      "dev": true,
-      "requires": {
-        "mime-db": "1.42.0"
-      }
-    },
     "minimatch": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
         "brace-expansion": "^1.1.7"
       }
     },
-    "minimist": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-      "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
-      "dev": true
-    },
     "mixin-deep": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
         }
       }
     },
-    "mkdirp": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
-      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
-      "dev": true,
-      "requires": {
-        "minimist": "0.0.8"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "0.0.8",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-          "dev": true
-        }
-      }
-    },
     "ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
       "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
       "dev": true
     },
-    "mute-stdout": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz",
-      "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==",
-      "dev": true
-    },
     "nan": {
       "version": "2.12.1",
       "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz",
         "to-regex": "^3.0.1"
       }
     },
-    "next-tick": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
-      "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+    "nice-try": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
       "dev": true
     },
-    "node-gyp": {
-      "version": "3.8.0",
-      "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
-      "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
-      "dev": true,
-      "requires": {
-        "fstream": "^1.0.0",
-        "glob": "^7.0.3",
-        "graceful-fs": "^4.1.2",
-        "mkdirp": "^0.5.0",
-        "nopt": "2 || 3",
-        "npmlog": "0 || 1 || 2 || 3 || 4",
-        "osenv": "0",
-        "request": "^2.87.0",
-        "rimraf": "2",
-        "semver": "~5.3.0",
-        "tar": "^2.0.0",
-        "which": "1"
-      },
-      "dependencies": {
-        "semver": {
-          "version": "5.3.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
-          "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
-          "dev": true
-        }
-      }
-    },
-    "node-sass": {
-      "version": "4.13.0",
-      "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.0.tgz",
-      "integrity": "sha512-W1XBrvoJ1dy7VsvTAS5q1V45lREbTlZQqFbiHb3R3OTTCma0XBtuG6xZ6Z4506nR4lmHPTqVRwxT6KgtWC97CA==",
-      "dev": true,
-      "requires": {
-        "async-foreach": "^0.1.3",
-        "chalk": "^1.1.1",
-        "cross-spawn": "^3.0.0",
-        "gaze": "^1.0.0",
-        "get-stdin": "^4.0.1",
-        "glob": "^7.0.3",
-        "in-publish": "^2.0.0",
-        "lodash": "^4.17.15",
-        "meow": "^3.7.0",
-        "mkdirp": "^0.5.1",
-        "nan": "^2.13.2",
-        "node-gyp": "^3.8.0",
-        "npmlog": "^4.0.0",
-        "request": "^2.88.0",
-        "sass-graph": "^2.2.4",
-        "stdout-stream": "^1.4.0",
-        "true-case-path": "^1.0.2"
-      },
-      "dependencies": {
-        "nan": {
-          "version": "2.14.0",
-          "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
-          "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
-          "dev": true
-        }
-      }
-    },
-    "nopt": {
-      "version": "3.0.6",
-      "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
-      "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
-      "dev": true,
-      "requires": {
-        "abbrev": "1"
-      }
-    },
     "normalize-package-data": {
       "version": "2.4.0",
       "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
         "remove-trailing-separator": "^1.0.1"
       }
     },
-    "now-and-later": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz",
-      "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==",
-      "dev": true,
-      "requires": {
-        "once": "^1.3.2"
-      }
-    },
-    "npmlog": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
-      "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+    "npm-run-all": {
+      "version": "4.1.5",
+      "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz",
+      "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==",
       "dev": true,
       "requires": {
-        "are-we-there-yet": "~1.1.2",
-        "console-control-strings": "~1.1.0",
-        "gauge": "~2.7.3",
-        "set-blocking": "~2.0.0"
+        "ansi-styles": "^3.2.1",
+        "chalk": "^2.4.1",
+        "cross-spawn": "^6.0.5",
+        "memorystream": "^0.3.1",
+        "minimatch": "^3.0.4",
+        "pidtree": "^0.3.0",
+        "read-pkg": "^3.0.0",
+        "shell-quote": "^1.6.1",
+        "string.prototype.padend": "^3.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "cross-spawn": {
+          "version": "6.0.5",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+          "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+          "dev": true,
+          "requires": {
+            "nice-try": "^1.0.4",
+            "path-key": "^2.0.1",
+            "semver": "^5.5.0",
+            "shebang-command": "^1.2.0",
+            "which": "^1.2.9"
+          }
+        },
+        "load-json-file": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+          "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.2",
+            "parse-json": "^4.0.0",
+            "pify": "^3.0.0",
+            "strip-bom": "^3.0.0"
+          }
+        },
+        "parse-json": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+          "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+          "dev": true,
+          "requires": {
+            "error-ex": "^1.3.1",
+            "json-parse-better-errors": "^1.0.1"
+          }
+        },
+        "path-type": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+          "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+          "dev": true,
+          "requires": {
+            "pify": "^3.0.0"
+          }
+        },
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        },
+        "read-pkg": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+          "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+          "dev": true,
+          "requires": {
+            "load-json-file": "^4.0.0",
+            "normalize-package-data": "^2.3.2",
+            "path-type": "^3.0.0"
+          }
+        },
+        "strip-bom": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+          "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
       }
     },
-    "number-is-nan": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
-      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
-      "dev": true
-    },
-    "oauth-sign": {
-      "version": "0.9.0",
-      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
-      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
-      "dev": true
-    },
-    "object-assign": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
-      "dev": true
-    },
     "object-copy": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
         }
       }
     },
+    "object-inspect": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
+      "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
+      "dev": true
+    },
     "object-keys": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
       "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
       "dev": true,
       "requires": {
-        "isobject": "^3.0.0"
-      }
-    },
-    "object.assign": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
-      "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
-      "dev": true,
-      "requires": {
-        "define-properties": "^1.1.2",
-        "function-bind": "^1.1.1",
-        "has-symbols": "^1.0.0",
-        "object-keys": "^1.0.11"
-      }
-    },
-    "object.defaults": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
-      "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=",
-      "dev": true,
-      "requires": {
-        "array-each": "^1.0.1",
-        "array-slice": "^1.0.0",
-        "for-own": "^1.0.0",
-        "isobject": "^3.0.0"
-      }
-    },
-    "object.map": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
-      "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=",
-      "dev": true,
-      "requires": {
-        "for-own": "^1.0.0",
-        "make-iterator": "^1.0.0"
-      }
-    },
-    "object.pick": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
-      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
-      "dev": true,
-      "requires": {
-        "isobject": "^3.0.1"
-      }
-    },
-    "object.reduce": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz",
-      "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=",
-      "dev": true,
-      "requires": {
-        "for-own": "^1.0.0",
-        "make-iterator": "^1.0.0"
-      }
-    },
-    "once": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
-      "dev": true,
-      "requires": {
-        "wrappy": "1"
-      }
-    },
-    "ordered-read-streams": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz",
-      "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=",
-      "dev": true,
-      "requires": {
-        "readable-stream": "^2.0.1"
-      },
-      "dependencies": {
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
-        },
-        "process-nextick-args": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
-          "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
-          "dev": true,
-          "requires": {
-            "core-util-is": "~1.0.0",
-            "inherits": "~2.0.3",
-            "isarray": "~1.0.0",
-            "process-nextick-args": "~2.0.0",
-            "safe-buffer": "~5.1.1",
-            "string_decoder": "~1.1.1",
-            "util-deprecate": "~1.0.1"
-          }
-        },
-        "string_decoder": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "~5.1.0"
-          }
-        }
-      }
-    },
-    "os-homedir": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
-      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
-      "dev": true
-    },
-    "os-locale": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
-      "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
-      "dev": true,
-      "requires": {
-        "lcid": "^1.0.0"
-      }
-    },
-    "os-tmpdir": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
-      "dev": true
-    },
-    "osenv": {
-      "version": "0.1.5",
-      "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
-      "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
-      "dev": true,
-      "requires": {
-        "os-homedir": "^1.0.0",
-        "os-tmpdir": "^1.0.0"
-      }
-    },
-    "parse-filepath": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
-      "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=",
-      "dev": true,
-      "requires": {
-        "is-absolute": "^1.0.0",
-        "map-cache": "^0.2.0",
-        "path-root": "^0.1.1"
-      }
-    },
-    "parse-json": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
-      "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
-      "dev": true,
-      "requires": {
-        "error-ex": "^1.2.0"
-      }
-    },
-    "parse-node-version": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.0.tgz",
-      "integrity": "sha512-02GTVHD1u0nWc20n2G7WX/PgdhNFG04j5fi1OkaJzPWLTcf6vh6229Lta1wTmXG/7Dg42tCssgkccVt7qvd8Kg==",
-      "dev": true
-    },
-    "parse-passwd": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
-      "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
-      "dev": true
-    },
-    "pascalcase": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
-      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
-      "dev": true
-    },
-    "path-dirname": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
-      "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
-      "dev": true
-    },
-    "path-exists": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
-      "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
-      "dev": true,
-      "requires": {
-        "pinkie-promise": "^2.0.0"
-      }
-    },
-    "path-is-absolute": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
-      "dev": true
-    },
-    "path-parse": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
-      "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
-      "dev": true
-    },
-    "path-root": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
-      "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=",
-      "dev": true,
-      "requires": {
-        "path-root-regex": "^0.1.0"
-      }
-    },
-    "path-root-regex": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
-      "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=",
-      "dev": true
-    },
-    "path-type": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
-      "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "^4.1.2",
-        "pify": "^2.0.0",
-        "pinkie-promise": "^2.0.0"
-      }
-    },
-    "performance-now": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
-      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
-      "dev": true
-    },
-    "pify": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-      "dev": true
-    },
-    "pinkie": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
-      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
-      "dev": true
-    },
-    "pinkie-promise": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
-      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
-      "dev": true,
-      "requires": {
-        "pinkie": "^2.0.0"
-      }
-    },
-    "plugin-error": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz",
-      "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==",
-      "dev": true,
-      "requires": {
-        "ansi-colors": "^1.0.1",
-        "arr-diff": "^4.0.0",
-        "arr-union": "^3.1.0",
-        "extend-shallow": "^3.0.2"
-      }
-    },
-    "posix-character-classes": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
-      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
-      "dev": true
-    },
-    "pretty-hrtime": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
-      "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
-      "dev": true
-    },
-    "process-nextick-args": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
-      "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
-      "dev": true
-    },
-    "pseudomap": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
-      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
-      "dev": true
-    },
-    "psl": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/psl/-/psl-1.6.0.tgz",
-      "integrity": "sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA==",
-      "dev": true
+        "isobject": "^3.0.0"
+      }
     },
-    "pump": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
-      "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+    "object.assign": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+      "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
       "dev": true,
       "requires": {
-        "end-of-stream": "^1.1.0",
-        "once": "^1.3.1"
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "has-symbols": "^1.0.1",
+        "object-keys": "^1.1.1"
       }
     },
-    "pumpify": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
-      "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+    "object.pick": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
       "dev": true,
       "requires": {
-        "duplexify": "^3.6.0",
-        "inherits": "^2.0.3",
-        "pump": "^2.0.0"
+        "isobject": "^3.0.1"
       }
     },
-    "punycode": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+    "pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
       "dev": true
     },
-    "qs": {
-      "version": "6.5.2",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
-      "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+    "path-dirname": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+      "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
       "dev": true
     },
-    "read-pkg": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
-      "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
-      "dev": true,
-      "requires": {
-        "load-json-file": "^1.0.0",
-        "normalize-package-data": "^2.3.2",
-        "path-type": "^1.0.0"
-      }
-    },
-    "read-pkg-up": {
+    "path-is-absolute": {
       "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
-      "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
-      "dev": true,
-      "requires": {
-        "find-up": "^1.0.0",
-        "read-pkg": "^1.0.0"
-      }
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "dev": true
     },
-    "readable-stream": {
-      "version": "2.3.6",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-      "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
-      "dev": true,
-      "requires": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.3",
-        "isarray": "~1.0.0",
-        "process-nextick-args": "~2.0.0",
-        "safe-buffer": "~5.1.1",
-        "string_decoder": "~1.1.1",
-        "util-deprecate": "~1.0.1"
-      },
-      "dependencies": {
-        "process-nextick-args": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
-          "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
-          "dev": true
-        }
-      }
+    "path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true
+    },
+    "pidtree": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz",
+      "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==",
+      "dev": true
+    },
+    "posix-character-classes": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+      "dev": true
     },
     "readdirp": {
       "version": "2.2.1",
         }
       }
     },
-    "rechoir": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
-      "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
-      "dev": true,
-      "requires": {
-        "resolve": "^1.1.6"
-      }
-    },
-    "redent": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
-      "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
-      "dev": true,
-      "requires": {
-        "indent-string": "^2.1.0",
-        "strip-indent": "^1.0.1"
-      }
-    },
     "regex-not": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
         "safe-regex": "^1.1.0"
       }
     },
-    "remove-bom-buffer": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz",
-      "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==",
-      "dev": true,
-      "requires": {
-        "is-buffer": "^1.1.5",
-        "is-utf8": "^0.2.1"
-      }
-    },
-    "remove-bom-stream": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz",
-      "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=",
-      "dev": true,
-      "requires": {
-        "remove-bom-buffer": "^3.0.0",
-        "safe-buffer": "^5.1.0",
-        "through2": "^2.0.3"
-      }
-    },
     "remove-trailing-separator": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
       "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
       "dev": true
     },
-    "repeating": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
-      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
-      "dev": true,
-      "requires": {
-        "is-finite": "^1.0.0"
-      }
-    },
-    "replace-ext": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
-      "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
-      "dev": true
-    },
-    "replace-homedir": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz",
-      "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=",
-      "dev": true,
-      "requires": {
-        "homedir-polyfill": "^1.0.1",
-        "is-absolute": "^1.0.0",
-        "remove-trailing-separator": "^1.1.0"
-      }
-    },
-    "request": {
-      "version": "2.88.0",
-      "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
-      "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
-      "dev": true,
-      "requires": {
-        "aws-sign2": "~0.7.0",
-        "aws4": "^1.8.0",
-        "caseless": "~0.12.0",
-        "combined-stream": "~1.0.6",
-        "extend": "~3.0.2",
-        "forever-agent": "~0.6.1",
-        "form-data": "~2.3.2",
-        "har-validator": "~5.1.0",
-        "http-signature": "~1.2.0",
-        "is-typedarray": "~1.0.0",
-        "isstream": "~0.1.2",
-        "json-stringify-safe": "~5.0.1",
-        "mime-types": "~2.1.19",
-        "oauth-sign": "~0.9.0",
-        "performance-now": "^2.1.0",
-        "qs": "~6.5.2",
-        "safe-buffer": "^5.1.2",
-        "tough-cookie": "~2.4.3",
-        "tunnel-agent": "^0.6.0",
-        "uuid": "^3.3.2"
-      },
-      "dependencies": {
-        "safe-buffer": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
-          "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
-          "dev": true
-        }
-      }
-    },
-    "require-directory": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
-      "dev": true
-    },
-    "require-main-filename": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
-      "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
-      "dev": true
-    },
-    "resolve": {
-      "version": "1.10.1",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz",
-      "integrity": "sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==",
-      "dev": true,
-      "requires": {
-        "path-parse": "^1.0.6"
-      }
-    },
-    "resolve-dir": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
-      "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
-      "dev": true,
-      "requires": {
-        "expand-tilde": "^2.0.0",
-        "global-modules": "^1.0.0"
-      }
-    },
-    "resolve-options": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz",
-      "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=",
-      "dev": true,
-      "requires": {
-        "value-or-function": "^3.0.0"
-      }
-    },
     "resolve-url": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
       "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
       "dev": true
     },
-    "rimraf": {
-      "version": "2.7.1",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
-      "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
-      "dev": true,
-      "requires": {
-        "glob": "^7.1.3"
-      }
-    },
     "safe-buffer": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
         "ret": "~0.1.10"
       }
     },
-    "safer-buffer": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
-      "dev": true
-    },
-    "sass-graph": {
-      "version": "2.2.4",
-      "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
-      "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
-      "dev": true,
-      "requires": {
-        "glob": "^7.0.0",
-        "lodash": "^4.0.0",
-        "scss-tokenizer": "^0.2.3",
-        "yargs": "^7.0.0"
-      }
-    },
-    "scss-tokenizer": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
-      "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
+    "sass": {
+      "version": "1.32.0",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.0.tgz",
+      "integrity": "sha512-fhyqEbMIycQA4blrz/C0pYhv2o4x2y6FYYAH0CshBw3DXh5D5wyERgxw0ptdau1orc/GhNrhF7DFN2etyOCEng==",
       "dev": true,
       "requires": {
-        "js-base64": "^2.1.8",
-        "source-map": "^0.4.2"
-      },
-      "dependencies": {
-        "source-map": {
-          "version": "0.4.4",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
-          "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
-          "dev": true,
-          "requires": {
-            "amdefine": ">=0.0.4"
-          }
-        }
+        "chokidar": ">=2.0.0 <4.0.0"
       }
     },
     "semver": {
       "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
       "dev": true
     },
-    "semver-greatest-satisfied-range": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz",
-      "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=",
-      "dev": true,
-      "requires": {
-        "sver-compat": "^1.5.0"
-      }
-    },
-    "set-blocking": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
-      "dev": true
-    },
     "set-value": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
         }
       }
     },
-    "signal-exit": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
-      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+    "shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "dev": true,
+      "requires": {
+        "shebang-regex": "^1.0.0"
+      }
+    },
+    "shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "dev": true
+    },
+    "shell-quote": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz",
+      "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==",
       "dev": true
     },
     "snapdragon": {
         "atob": "^2.1.1",
         "decode-uri-component": "^0.2.0",
         "resolve-url": "^0.2.1",
-        "source-map-url": "^0.4.0",
-        "urix": "^0.1.0"
-      }
-    },
-    "source-map-url": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
-      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
-      "dev": true
-    },
-    "sparkles": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz",
-      "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=",
-      "dev": true
-    },
-    "spdx-correct": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
-      "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
-      "dev": true,
-      "requires": {
-        "spdx-expression-parse": "^3.0.0",
-        "spdx-license-ids": "^3.0.0"
-      }
-    },
-    "spdx-exceptions": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
-      "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
-      "dev": true
-    },
-    "spdx-expression-parse": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
-      "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
-      "dev": true,
-      "requires": {
-        "spdx-exceptions": "^2.1.0",
-        "spdx-license-ids": "^3.0.0"
-      }
-    },
-    "spdx-license-ids": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz",
-      "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==",
-      "dev": true
-    },
-    "split-string": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
-      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
-      "dev": true,
-      "requires": {
-        "extend-shallow": "^3.0.0"
-      }
-    },
-    "sshpk": {
-      "version": "1.16.1",
-      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
-      "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
-      "dev": true,
-      "requires": {
-        "asn1": "~0.2.3",
-        "assert-plus": "^1.0.0",
-        "bcrypt-pbkdf": "^1.0.0",
-        "dashdash": "^1.12.0",
-        "ecc-jsbn": "~0.1.1",
-        "getpass": "^0.1.1",
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.0.2",
-        "tweetnacl": "~0.14.0"
-      }
-    },
-    "stack-trace": {
-      "version": "0.0.10",
-      "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
-      "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=",
-      "dev": true
-    },
-    "static-extend": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
-      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
-      "dev": true,
-      "requires": {
-        "define-property": "^0.2.5",
-        "object-copy": "^0.1.0"
-      },
-      "dependencies": {
-        "define-property": {
-          "version": "0.2.5",
-          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
-          "dev": true,
-          "requires": {
-            "is-descriptor": "^0.1.0"
-          }
-        }
-      }
-    },
-    "stdout-stream": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
-      "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
-      "dev": true,
-      "requires": {
-        "readable-stream": "^2.0.1"
-      }
-    },
-    "stream-exhaust": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz",
-      "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==",
-      "dev": true
-    },
-    "stream-shift": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
-      "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
-      "dev": true
-    },
-    "string-width": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
-      "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
-      "dev": true,
-      "requires": {
-        "code-point-at": "^1.0.0",
-        "is-fullwidth-code-point": "^1.0.0",
-        "strip-ansi": "^3.0.0"
-      }
-    },
-    "string_decoder": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-      "dev": true,
-      "requires": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "strip-ansi": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
-      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
-      "dev": true,
-      "requires": {
-        "ansi-regex": "^2.0.0"
-      }
-    },
-    "strip-bom": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
-      "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
-      "dev": true,
-      "requires": {
-        "is-utf8": "^0.2.0"
+        "source-map-url": "^0.4.0",
+        "urix": "^0.1.0"
       }
     },
-    "strip-indent": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
-      "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+    "source-map-url": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+      "dev": true
+    },
+    "spdx-correct": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
+      "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
       "dev": true,
       "requires": {
-        "get-stdin": "^4.0.1"
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-license-ids": "^3.0.0"
       }
     },
-    "supports-color": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+    "spdx-exceptions": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
+      "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
       "dev": true
     },
-    "sver-compat": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz",
-      "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=",
+    "spdx-expression-parse": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+      "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
       "dev": true,
       "requires": {
-        "es6-iterator": "^2.0.1",
-        "es6-symbol": "^3.1.1"
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
       }
     },
-    "tar": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
-      "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
+    "spdx-license-ids": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz",
+      "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==",
+      "dev": true
+    },
+    "split-string": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
       "dev": true,
       "requires": {
-        "block-stream": "*",
-        "fstream": "^1.0.12",
-        "inherits": "2"
+        "extend-shallow": "^3.0.0"
       }
     },
-    "through2": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
-      "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
+    "static-extend": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
       "dev": true,
       "requires": {
-        "readable-stream": "^2.1.5",
-        "xtend": "~4.0.1"
+        "define-property": "^0.2.5",
+        "object-copy": "^0.1.0"
       },
       "dependencies": {
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "2.3.3",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
-          "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
-          "dev": true,
-          "requires": {
-            "core-util-is": "~1.0.0",
-            "inherits": "~2.0.3",
-            "isarray": "~1.0.0",
-            "process-nextick-args": "~1.0.6",
-            "safe-buffer": "~5.1.1",
-            "string_decoder": "~1.0.3",
-            "util-deprecate": "~1.0.1"
-          }
-        },
-        "string_decoder": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
-          "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
           "dev": true,
           "requires": {
-            "safe-buffer": "~5.1.0"
+            "is-descriptor": "^0.1.0"
           }
         }
       }
     },
-    "through2-filter": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz",
-      "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==",
+    "string.prototype.padend": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.1.tgz",
+      "integrity": "sha512-eCzTASPnoCr5Ht+Vn1YXgm8SB015hHKgEIMu9Nr9bQmLhRBxKRfmzSj/IQsxDFc8JInJDDFA0qXwK+xxI7wDkg==",
       "dev": true,
       "requires": {
-        "through2": "~2.0.0",
-        "xtend": "~4.0.0"
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.18.0-next.1"
       }
     },
-    "time-stamp": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
-      "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=",
-      "dev": true
+    "string.prototype.trimend": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz",
+      "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3"
+      }
     },
-    "to-absolute-glob": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
-      "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=",
+    "string.prototype.trimstart": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz",
+      "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==",
       "dev": true,
       "requires": {
-        "is-absolute": "^1.0.0",
-        "is-negated-glob": "^1.0.0"
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3"
       }
     },
     "to-object-path": {
         "repeat-string": "^1.6.1"
       }
     },
-    "to-through": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz",
-      "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=",
-      "dev": true,
-      "requires": {
-        "through2": "^2.0.3"
-      }
-    },
-    "tough-cookie": {
-      "version": "2.4.3",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
-      "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
-      "dev": true,
-      "requires": {
-        "psl": "^1.1.24",
-        "punycode": "^1.4.1"
-      },
-      "dependencies": {
-        "punycode": {
-          "version": "1.4.1",
-          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
-          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
-          "dev": true
-        }
-      }
-    },
-    "trim-newlines": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
-      "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
-      "dev": true
-    },
-    "true-case-path": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
-      "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
-      "dev": true,
-      "requires": {
-        "glob": "^7.1.2"
-      }
-    },
-    "tunnel-agent": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
-      "dev": true,
-      "requires": {
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "tweetnacl": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
-      "dev": true
-    },
-    "typedarray": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
-      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
-      "dev": true
-    },
-    "unc-path-regex": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
-      "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=",
-      "dev": true
-    },
-    "undertaker": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz",
-      "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==",
-      "dev": true,
-      "requires": {
-        "arr-flatten": "^1.0.1",
-        "arr-map": "^2.0.0",
-        "bach": "^1.0.0",
-        "collection-map": "^1.0.0",
-        "es6-weak-map": "^2.0.1",
-        "last-run": "^1.1.0",
-        "object.defaults": "^1.0.0",
-        "object.reduce": "^1.0.0",
-        "undertaker-registry": "^1.0.0"
-      }
-    },
-    "undertaker-registry": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz",
-      "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=",
-      "dev": true
-    },
     "union-value": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
         "set-value": "^2.0.1"
       }
     },
-    "unique-stream": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz",
-      "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==",
-      "dev": true,
-      "requires": {
-        "json-stable-stringify-without-jsonify": "^1.0.1",
-        "through2-filter": "^3.0.0"
-      }
-    },
     "unset-value": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
       "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==",
       "dev": true
     },
-    "uri-js": {
-      "version": "4.2.2",
-      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
-      "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
-      "dev": true,
-      "requires": {
-        "punycode": "^2.1.0"
-      }
-    },
     "urix": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
       "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
       "dev": true
     },
-    "uuid": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
-      "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==",
-      "dev": true
-    },
-    "v8flags": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.2.tgz",
-      "integrity": "sha512-MtivA7GF24yMPte9Rp/BWGCYQNaUj86zeYxV/x2RRJMKagImbbv3u8iJC57lNhWLPcGLJmHcHmFWkNsplbbLWw==",
-      "dev": true,
-      "requires": {
-        "homedir-polyfill": "^1.0.1"
-      }
-    },
     "validate-npm-package-license": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
         "spdx-expression-parse": "^3.0.0"
       }
     },
-    "value-or-function": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz",
-      "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=",
-      "dev": true
-    },
-    "verror": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
-      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
-      "dev": true,
-      "requires": {
-        "assert-plus": "^1.0.0",
-        "core-util-is": "1.0.2",
-        "extsprintf": "^1.2.0"
-      }
-    },
-    "vinyl-fs": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz",
-      "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==",
-      "dev": true,
-      "requires": {
-        "fs-mkdirp-stream": "^1.0.0",
-        "glob-stream": "^6.1.0",
-        "graceful-fs": "^4.0.0",
-        "is-valid-glob": "^1.0.0",
-        "lazystream": "^1.0.0",
-        "lead": "^1.0.0",
-        "object.assign": "^4.0.4",
-        "pumpify": "^1.3.5",
-        "readable-stream": "^2.3.3",
-        "remove-bom-buffer": "^3.0.0",
-        "remove-bom-stream": "^1.2.0",
-        "resolve-options": "^1.1.0",
-        "through2": "^2.0.0",
-        "to-through": "^2.0.0",
-        "value-or-function": "^3.0.0",
-        "vinyl": "^2.0.0",
-        "vinyl-sourcemap": "^1.1.0"
-      },
-      "dependencies": {
-        "clone": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
-          "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
-          "dev": true
-        },
-        "clone-stats": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
-          "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
-          "dev": true
-        },
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
-        },
-        "process-nextick-args": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
-          "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
-          "dev": true,
-          "requires": {
-            "core-util-is": "~1.0.0",
-            "inherits": "~2.0.3",
-            "isarray": "~1.0.0",
-            "process-nextick-args": "~2.0.0",
-            "safe-buffer": "~5.1.1",
-            "string_decoder": "~1.1.1",
-            "util-deprecate": "~1.0.1"
-          }
-        },
-        "replace-ext": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
-          "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
-          "dev": true
-        },
-        "string_decoder": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "~5.1.0"
-          }
-        },
-        "vinyl": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
-          "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
-          "dev": true,
-          "requires": {
-            "clone": "^2.1.1",
-            "clone-buffer": "^1.0.0",
-            "clone-stats": "^1.0.0",
-            "cloneable-readable": "^1.0.0",
-            "remove-trailing-separator": "^1.0.1",
-            "replace-ext": "^1.0.0"
-          }
-        }
-      }
-    },
-    "vinyl-sourcemap": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz",
-      "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=",
-      "dev": true,
-      "requires": {
-        "append-buffer": "^1.0.2",
-        "convert-source-map": "^1.5.0",
-        "graceful-fs": "^4.1.6",
-        "normalize-path": "^2.1.1",
-        "now-and-later": "^2.0.0",
-        "remove-bom-buffer": "^3.0.0",
-        "vinyl": "^2.0.0"
-      },
-      "dependencies": {
-        "clone": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
-          "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
-          "dev": true
-        },
-        "clone-stats": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
-          "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
-          "dev": true
-        },
-        "replace-ext": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
-          "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
-          "dev": true
-        },
-        "vinyl": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
-          "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
-          "dev": true,
-          "requires": {
-            "clone": "^2.1.1",
-            "clone-buffer": "^1.0.0",
-            "clone-stats": "^1.0.0",
-            "cloneable-readable": "^1.0.0",
-            "remove-trailing-separator": "^1.0.1",
-            "replace-ext": "^1.0.0"
-          }
-        }
-      }
-    },
-    "vinyl-sourcemaps-apply": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz",
-      "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=",
-      "dev": true,
-      "requires": {
-        "source-map": "^0.5.1"
-      },
-      "dependencies": {
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        }
-      }
-    },
     "which": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
       "requires": {
         "isexe": "^2.0.0"
       }
-    },
-    "which-module": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
-      "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
-      "dev": true
-    },
-    "wide-align": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
-      "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
-      "dev": true,
-      "requires": {
-        "string-width": "^1.0.2 || 2"
-      }
-    },
-    "wrap-ansi": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
-      "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
-      "dev": true,
-      "requires": {
-        "string-width": "^1.0.1",
-        "strip-ansi": "^3.0.1"
-      }
-    },
-    "wrappy": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-      "dev": true
-    },
-    "xtend": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
-      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
-      "dev": true
-    },
-    "y18n": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
-      "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
-      "dev": true
-    },
-    "yallist": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
-      "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
-      "dev": true
-    },
-    "yargs": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
-      "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
-      "dev": true,
-      "requires": {
-        "camelcase": "^3.0.0",
-        "cliui": "^3.2.0",
-        "decamelize": "^1.1.1",
-        "get-caller-file": "^1.0.1",
-        "os-locale": "^1.4.0",
-        "read-pkg-up": "^1.0.1",
-        "require-directory": "^2.1.1",
-        "require-main-filename": "^1.0.1",
-        "set-blocking": "^2.0.0",
-        "string-width": "^1.0.2",
-        "which-module": "^1.0.0",
-        "y18n": "^3.2.1",
-        "yargs-parser": "^5.0.0"
-      }
-    },
-    "yargs-parser": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
-      "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
-      "dev": true,
-      "requires": {
-        "camelcase": "^3.0.0"
-      }
     }
   }
 }
index 6275ac3501786f1c5feddf4bf78f060b89f1d763..bbc8299c594a04e10d8e157b12c1fc91f1a77eb9 100644 (file)
@@ -4,19 +4,22 @@
   "description": "The front-end site for bookstack",
   "main": "gulpfile.js",
   "scripts": {
-    "build": "gulp && hugo",
-    "serve": "hugo serve -DF",
-    "dev": "gulp watch",
+    "build:css:prod": "sass ./themes/bookstack/sass:./themes/bookstack/static/css -s compressed",
+    "build:css:dev": "sass ./themes/bookstack/sass:./themes/bookstack/static/css",
+    "build:css:watch": "sass ./themes/bookstack/sass:./themes/bookstack/static/css --watch",
+    "build:hugo:prod": "hugo",
+    "build:hugo:watch": "hugo serve -DF",
+    "build": "npm-run-all --sequential build:css:prod build:hugo:prod",
+    "serve": "npm-run-all build:hugo:watch",
+    "dev": "npm-run-all --parallel build:hugo:watch build:css:watch",
+    "deploy:server": "rsync -avx --delete --exclude '.git/' --exclude 'node_modules/' ./ sandcat:/var/www/bookstackapp.com/",
+    "deploy": "npm-run-all --sequential build:css:prod build:hugo:prod deploy:server",
     "test": "echo \"Error: no test specified\" && exit 1"
   },
   "author": "Dan Brown",
   "license": "MIT",
   "devDependencies": {
-    "gulp": "4.0.1",
-    "gulp-clean-css": "^4.2.0",
-    "gulp-plumber": "1.2.1",
-    "gulp-rename": "1.4.0",
-    "gulp-sass": "^4.0.2"
-  },
-  "dependencies": {}
+    "npm-run-all": "^4.1.5",
+    "sass": "^1.32.0"
+  }
 }
index f472f223002e6f98336b374b94518a8e7e1514fa..ff11b9cd73fc38a96c1bfb79eac64e9fcaea796a 100644 (file)
--- a/readme.md
+++ b/readme.md
@@ -14,4 +14,4 @@ This site is built using [Hugo](https://gohugo.io). Images are stored using `git
 
 The theme is custom made with snippets taken from the [hugo capser theme](https://github.com/vjeantet/hugo-theme-casper).
 
-SCSS is used for the styling and is built using gulp. Install NPM dependencies via `npm install` or `yarn` then you can use `npm run-script build` to build the css once or `npm run-script dev` to watch for changes.
+SCSS is used for the styling. Install NPM dependencies via `npm install` or `yarn` then you can use `npm run build` to build the css and site once or `npm run dev` to watch for changes.
index ee24ab1a9010298e3f990853b02e761b157b2fd8..802f40a3cf061e46a8c5924783ba62dffba2fdab 100644 (file)
Binary files a/static/images/2017/01/bookstack-includes-popover.webm and b/static/images/2017/01/bookstack-includes-popover.webm differ
diff --git a/static/images/2020/07/bookstack_website_2016_2020.png b/static/images/2020/07/bookstack_website_2016_2020.png
new file mode 100644 (file)
index 0000000..e223135
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4b489c0ee31b5af50196d8a8d9eb282af16e1ef0b9e85932225387836f482490
+size 10394
diff --git a/static/images/2020/09/api_chapters.png b/static/images/2020/09/api_chapters.png
new file mode 100644 (file)
index 0000000..1533e0a
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3074389ad4180f985fbfd23d36c6d4eeec4535094a63a1e808f8139c5d345b5d
+size 6700
diff --git a/static/images/2020/09/attachment_link_insert.png b/static/images/2020/09/attachment_link_insert.png
new file mode 100644 (file)
index 0000000..f3536fd
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bc574c73e147fce66b2088ef1f0092bc2253a77628716883f17f6942cb7607cb
+size 24812
diff --git a/static/images/2020/09/bookstack_audit_log.png b/static/images/2020/09/bookstack_audit_log.png
new file mode 100644 (file)
index 0000000..f382ae2
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bd1720ef2acb708e8908d64edbba8424395f1fc766e2895de1b114d1dc96aada
+size 87085
diff --git a/static/images/2020/09/code_block_session_saving.png b/static/images/2020/09/code_block_session_saving.png
new file mode 100644 (file)
index 0000000..d6e7f6c
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cce92f30d4d4fea7401f688ed1ef1b6b2c5cdfb6caa19a4072f077c16e5fa001
+size 22044
diff --git a/static/images/2021/01/audit_log_updates.png b/static/images/2021/01/audit_log_updates.png
new file mode 100644 (file)
index 0000000..d526e4e
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:81be5781c6f96583efedfa1f36b12c430bc20e806bf115840d21fce8c40b2eaf
+size 66858
diff --git a/static/images/2021/01/changes_view.png b/static/images/2021/01/changes_view.png
new file mode 100644 (file)
index 0000000..339b284
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f920cda591090e22e01eb138186e3e6d668e85987f03aebe25e7f04839b51e6e
+size 60215
diff --git a/static/images/2021/01/mailbag.png b/static/images/2021/01/mailbag.png
new file mode 100644 (file)
index 0000000..e07fc82
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:edc9d8b00d00d770a1fb41bf03b81bd44c65572d785d851ecb8d015ca6a20dc7
+size 117709
diff --git a/static/images/2021/01/mailchimp_tracked_links.png b/static/images/2021/01/mailchimp_tracked_links.png
new file mode 100644 (file)
index 0000000..6c5c8c3
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e844448bb21d0021e721561481b5dcb5a01517875bf57f18779efd5e1ad68206
+size 37562
diff --git a/static/images/2021/01/ownership_change.png b/static/images/2021/01/ownership_change.png
new file mode 100644 (file)
index 0000000..71f8176
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:74fdf57bbb8104976799f5ae0ad3b9c8284329d190342da23250699dff951f6d
+size 38896
diff --git a/static/images/2021/01/pages_api.png b/static/images/2021/01/pages_api.png
new file mode 100644 (file)
index 0000000..c015d1f
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9e6d22fe1de9703f988bfa747569548d228a53920861ab3b4f2e71455d0b6526
+size 79271
diff --git a/static/images/2021/01/plausible_bookstack_site_analytics.png b/static/images/2021/01/plausible_bookstack_site_analytics.png
new file mode 100644 (file)
index 0000000..5ce180d
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:252c0cb69f6594242a07708de8d100d45b450c9603048598a1da6c757f9a2cd7
+size 89077
diff --git a/static/images/2021/01/recycle_bin.png b/static/images/2021/01/recycle_bin.png
new file mode 100644 (file)
index 0000000..98c87c1
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:85922b6943d2cd00f1922edad5e85688a31c55cbed4ad8c1c978663571c40505
+size 77206
diff --git a/static/images/2021/01/recycle_bin_maintenance.png b/static/images/2021/01/recycle_bin_maintenance.png
new file mode 100644 (file)
index 0000000..99afe29
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1b23fc92b54ec1d0672bf2c9dd4650970c1aaeabaf5d0f888928db9104508812
+size 49380
diff --git a/static/images/2021/01/user_list_activity.png b/static/images/2021/01/user_list_activity.png
new file mode 100644 (file)
index 0000000..807fbc4
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1da8eaaafc29e4f8037f52d3196c17f5f7e44fbfe39865c5523625c948e1ebc8
+size 56468
diff --git a/static/images/blog-cover-images/gate-masaaki-komori.jpg b/static/images/blog-cover-images/gate-masaaki-komori.jpg
new file mode 100644 (file)
index 0000000..18782ab
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0786d328fe87139a692de1b40d077ae3b1d8469d39844af1a30f2281f2d970d8
+size 219025
diff --git a/static/images/blog-cover-images/library-priscilla-du-preez.jpg b/static/images/blog-cover-images/library-priscilla-du-preez.jpg
new file mode 100644 (file)
index 0000000..6a494cb
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:55b67d6e5c51ba73ca653c75ff99e02c8169f7beb4569e185de84f311ea0c2c1
+size 371061
diff --git a/static/images/blog-cover-images/lock-aubrey-odom.jpg b/static/images/blog-cover-images/lock-aubrey-odom.jpg
new file mode 100644 (file)
index 0000000..0aecc86
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8a4c3399a06bd59e44791dc6920e2bf03b197b38c98eb4ee3078a1d512b13abb
+size 290647
diff --git a/static/images/blog-cover-images/lock-door-waldemar-brandt.jpg b/static/images/blog-cover-images/lock-door-waldemar-brandt.jpg
new file mode 100644 (file)
index 0000000..3de0d4b
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8549305cb408ff9e41d2e306af415cdee444f3e6a20a6106d33a4fe271ba5cc1
+size 266321
diff --git a/static/images/blog-cover-images/lock-jon-moore.jpg b/static/images/blog-cover-images/lock-jon-moore.jpg
new file mode 100644 (file)
index 0000000..e08ad89
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4d1c2fb75a1de5130909f25156a4536e4d10236a0d437c9095be424361f3f09d
+size 205167
diff --git a/static/images/blog-cover-images/locks-marcos-mayer.jpg b/static/images/blog-cover-images/locks-marcos-mayer.jpg
new file mode 100644 (file)
index 0000000..e55e9c8
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:72b5a3f9c818564a0cc384e861fd408cf4430316299af5e9aade8df7964e5f90
+size 393265
diff --git a/static/images/blog-cover-images/mountains-jerry-zhang.jpg b/static/images/blog-cover-images/mountains-jerry-zhang.jpg
new file mode 100644 (file)
index 0000000..36a6348
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7c2f27a21da04c1d6885a6cbe9c4320125938277375293048d1e2acc15f20fa1
+size 238249
diff --git a/static/images/blog-cover-images/penguin-steffen-triekel.jpg b/static/images/blog-cover-images/penguin-steffen-triekel.jpg
new file mode 100644 (file)
index 0000000..c800146
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:de1fb734a90d6d92f2011ebc8df1e7e5b108186997e8f5901996c1cef5280f10
+size 264457
diff --git a/static/images/blog-cover-images/winter-fox-birger-strahl.jpg b/static/images/blog-cover-images/winter-fox-birger-strahl.jpg
new file mode 100644 (file)
index 0000000..c13171a
--- /dev/null
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:84b90df595beeb66f6ae542484edc43f58eae6b350ccf8b8915106cd247c5089
+size 519154
index 2b63f125095c53aab5d57f26c39c9e072ac706a3..b2f808dc5a4ded62c5428bd2e1b83b9254e0444d 100644 (file)
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:85ddf4d244c54bb01e133f3d1a705a23f15945c3e7719e3efc56688dad7e020f
-size 7872
+oid sha256:fd8e67a512aafcb43b594075f09dcfacc50dd4de1d33f211bf91aa45bdd11a96
+size 58067
index ac36e0622776b9ea3aff3dd3e2b43b1cdf833eed..71173d4f24d245fa18d3273c2bd3a6fa6aca6cc8 100644 (file)
@@ -1,2 +1,16 @@
 +++
+title = "{{ replace .Name "-" " " | title }}"
+date = {{ .Date }}
+categories = ["News"]
+tags = ["News"]
+author = "Dan Brown"
+image = "/images/blog-cover-images/"
+draft = true
 +++
+
+
+# Title
+
+----
+
+<span style="font-size: 0.9em;opacity:0.9;">Header Image Credits: {REPLACE THIS}</span>
\ No newline at end of file
index 720aedba2386ded34822ca57e35c7b54ce0630f5..ea4e3eb17519e1c3090ee73895895216c80a5683 100644 (file)
@@ -9,35 +9,37 @@
 
   <div class="row">
 
-    <div class="col-md-6 col-md-offset-1 col-sm-7 post-content">
-
-      <h1>{{.Title}}</h1>
-
-      <p class="post-date text-muted" datetime="{{ .Date.Format "2006-01-02T15:04:05Z07:00" | safeHTML }}">
-          {{$author := index .Site.Data.authors (or .Params.author .Site.Params.author)}}
-          {{$authorname := or $author.name .Site.Params.author }}
-          {{$authorthumbnail := or $author.thumbnail .Site.Params.author }}
-          <img class="post-avatar no-border" width="32" src="{{$authorthumbnail}}" alt="{{$authorname}}"> {{$authorname}} posted on the {{ .Date.Format "2" }}{{ if in (slice 1 21 31) .Date.Day}}st{{ else if in (slice 2 22) .Date.Day}}nd{{ else if in (slice 3 23) .Date.Day}}rd{{ else }}th{{ end }} of {{ .Date.Format "January 2006" }}
-      </p>
-
-      {{.Content}}
-
-      <div class="footer-content">
-        {{ partial "mailchimp.html" . }}
-
-        <div class="text-muted">
-          Want to let me know what you think of BookStack or this post? <br>
-          You find me on twitter <a href="https://twitter.com/ssddanbrown">@ssddanbrown</a>. <br>
-          You can <a href="https://github.com/BookStackApp/BookStack/issues">open a suggestion or issue on GitHub</a>.
+    <div class="col-md-9">
+
+      <div class="post-content">
+        <h1>{{.Title}}</h1>
+
+        <p class="post-date text-muted" datetime="{{ .Date.Format "2006-01-02T15:04:05Z07:00" | safeHTML }}">
+            {{$author := index .Site.Data.authors (or .Params.author .Site.Params.author)}}
+            {{$authorname := or $author.name .Site.Params.author }}
+            {{$authorthumbnail := or $author.thumbnail .Site.Params.author }}
+            <img class="post-avatar no-border" width="32" src="{{$authorthumbnail}}" alt="{{$authorname}}"> {{$authorname}} posted on the {{ .Date.Format "2" }}{{ if in (slice 1 21 31) .Date.Day}}st{{ else if in (slice 2 22) .Date.Day}}nd{{ else if in (slice 3 23) .Date.Day}}rd{{ else }}th{{ end }} of {{ .Date.Format "January 2006" }}
+        </p>
+  
+        {{.Content}}
+  
+        <div class="footer-content">
+          {{ partial "signup.html" . }}
+  
+          <div class="text-muted">
+            Want to let me know what you think of BookStack or this post? <br>
+            You find me on twitter <a href="https://twitter.com/ssddanbrown">@ssddanbrown</a>. <br>
+            You can <a href="https://github.com/BookStackApp/BookStack/issues">open a suggestion or issue on GitHub</a>.
+          </div>
+  
+          <br>
+          <br>
+  
         </div>
-
-        <br>
-        <br>
-
       </div>
     </div>
 
-    <div class="col-md-3 col-md-offset-1 col-sm-4 col-sm-offset-1 blog-sidebar-post-list">
+    <div class="col-md-3 blog-sidebar-post-list">
       <h4>Latest Posts</h4>
       <div class="recent-posts">
         {{ range first 8 ( where .Site.RegularPages "Section" "blog") }}
index 2ba325d9ca60d009dc5a8c4496f4316ed880bf76..255323be7c9c46a070a0b673085b5e32b21854e9 100644 (file)
@@ -30,7 +30,7 @@
         <h2 id="features">Features</h2>
         <div class="row">
             <div class="col-sm-4">
-                <h4><span class="icon">{{partial "icon/code.svg"}}</span>Free &amp; Open Source</h4>
+                <h4><span class="icon" aria-hidden="true">{{partial "icon/code.svg"}}</span>Free &amp; Open Source</h4>
                 <p>BookStack is fully free and open, MIT licensed. The source is available on GitHub. There is no cost to downloading and installing your own instance of bookstack.
                 </p>
                 <p>
                 </p>
             </div>
             <div class="col-sm-4" >
-                <h4><span class="icon">{{partial "icon/laptop_chromebook.svg"}}</span>Easy, Simple Interface</h4>
+                <h4><span class="icon" aria-hidden="true">{{partial "icon/laptop_chromebook.svg"}}</span>Easy, Simple Interface</h4>
                 <p>
                     Simplicity has been the top priority when building BookStack. The page editor has a simple WYSIWYG interface and all content is broken into three simple real world groups:
                 </p>
                 <p>
-                    <span class="icon book">{{partial "icon/book.svg"}}</span>Books &nbsp;&nbsp;<span class="icon chapter">{{partial "icon/collections_bookmark.svg"}}</span>Chapters&nbsp;&nbsp; <span class="icon page">{{partial "icon/description.svg"}}</span>Pages
+                                       <span class="icon book" aria-hidden="true">{{partial "icon/book.svg"}}</span>Books
+                                       &nbsp;&nbsp;<span class="icon chapter" aria-hidden="true">{{partial "icon/collections_bookmark.svg"}}</span>Chapters&nbsp;&nbsp;
+                                       <span class="icon page" aria-hidden="true">{{partial "icon/description.svg"}}</span>Pages
                 </p>
             </div>
             <div class="col-sm-4" >
-                <h4><span class="icon">{{partial "icon/search.svg"}}</span>Searchable and Connected</h4>
+                <h4><span class="icon" aria-hidden="true">{{partial "icon/search.svg"}}</span>Searchable and Connected</h4>
                 <p>
                     The content in BookStack is fully searchable. You are able to search at book level or across all books, chapters &amp; pages. The ability to link directly to any paragraph allows you to keep your documentation connected.
                 </p>
         </p>
         <div class="row">
             <div class="col-sm-4">
-                <h4><span class="icon">{{partial "icon/build.svg"}}</span>Configurable</h4>
+                <h4><span class="icon" aria-hidden="true">{{partial "icon/build.svg"}}</span>Configurable</h4>
                 <p>
                     Configuration options allow you to set-up BookStack to suit your use case. You can change the name, Logo and registration options. You can also change whether the whole system is publicly viewable or not.
                 </p>
             </div>
             <div class="col-sm-4" >
-                <h4><span class="icon">{{partial "icon/storage.svg"}}</span>Simple Requirements</h4>
+                <h4><span class="icon" aria-hidden="true">{{partial "icon/storage.svg"}}</span>Simple Requirements</h4>
                 <p>
                     BookStack is built using PHP, on top of the Laravel framework and it uses MySQL to store data. Performance has been kept in mind and BookStack can run happily on a $5 Digital Ocean VPS.
                 </p>
             </div>
             <div class="col-sm-4" >
-                <h4><span class="icon">{{partial "icon/directions_boat.svg"}}</span>Powerful Features</h4>
+                <h4><span class="icon" aria-hidden="true">{{partial "icon/directions_boat.svg"}}</span>Powerful Features</h4>
                 <p>
                     On top of the powerful search and linking there is also cross-book sorting, page revisions and image management. A full role and permission system allow you to lock down content and actions as required.
                 </p>
         </p>
         <div class="row">
             <div class="col-sm-4">
-                <h4><span class="icon">{{partial "icon/language.svg"}}</span>Multi-lingual</h4>
+                <h4><span class="icon" aria-hidden="true">{{partial "icon/language.svg"}}</span>Multi-lingual</h4>
                 <p>
                     BookStack users can set their preferred language. Thanks to great community contributors, Current languages built into BookStack include EN, FR, DE, ES, IT, JA, NL, PL, RU and more.
                 </p>
             </div>
             <div class="col-sm-4" >
-                <h4><span class="icon">{{partial "icon/edit.svg"}}</span>Optional Markdown Editor</h4>
+                <h4><span class="icon" aria-hidden="true">{{partial "icon/edit.svg"}}</span>Optional Markdown Editor</h4>
                 <p>
                    If you prefer to write in Markdown then BookStack supports you. A markdown editor is provided and includes a live-preview as you write your documentation.
                 </p>
             </div>
             <div class="col-sm-4" >
-                <h4><span class="icon">{{partial "icon/lock.svg"}}</span>Integrated Authentication</h4>
+                <h4><span class="icon" aria-hidden="true">{{partial "icon/lock.svg"}}</span>Integrated Authentication</h4>
                 <p>
                        As well as the default email/password login social providers such as GitHub, Google, Slack, AzureAD and more can be used. Okta and LDAP options are available for enterprise environments.
                 </p>
                        <div class="col-sm-6 text-center">
                                        <div class="demo-box text-left " >
                                                <label>Demo site url</label> <br><a href="https://demo.bookstackapp.com" target="_blank">https://demo.bookstackapp.com</a> <br>
-                                               <label>Admin email</label> <br><input type="text" onclick="this.select();" value="[email protected]" readonly="true"><br>
-                                               <label>Admin password</label> <br><input type="text" onclick="this.select();" value="password" readonly="true"> <br><br>
+                                               <label for="demo-email">Admin email</label> <br><input id="demo-email" type="text" onclick="this.select();" value="[email protected]" readonly="true"><br>
+                                               <label for="demo-password">Admin password</label> <br><input id="demo-password" type="text" onclick="this.select();" value="password" readonly="true"> <br><br>
                                                <a href="https://demo.bookstackapp.com/[email protected]&password=password" class="button" target="_blank">Open demo site</a>
                                        </div>
                        </div>
                                <div class="row">
                                        <div class="col-sm-4 col-sm-offset-0 col-xs-8 col-xs-offset-2">
                                                <h4>Page View</h4>
-                                               <p>How core content is viewed in BookStack</p>
                                                <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
+                                                       <figcaption>How core content is viewed in BookStack</figcaption>
                                                    <a href="images/screenshots/page-view.png" data-size="1666x910">
                                                        <img src="images/screenshots/thumb_page-view.png" alt="Page View" loading="lazy">
                                                    </a>
                                        </div>
                                        <div class="col-sm-4 col-sm-offset-0 col-xs-8 col-xs-offset-2">
                                                <h4>Page Editor</h4>
-                                               <p>The WYSIWYG interface for editing pages</p>
-                                               <figure  itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
+                                               <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
+                                                       <figcaption>The WYSIWYG interface for editing pages</figcaption>
                                                    <a href="images/screenshots/page-edit.png" data-size="1666x910">
                                                        <img src="images/screenshots/thumb_page-edit.png" alt="Page Editing" loading="lazy">
                                                    </a>
                                        </div>
                                        <div class="col-sm-4 col-sm-offset-0 col-xs-8 col-xs-offset-2">
                                                <h4>Image Manager</h4>
-                                               <p>How images are uploaded and managed</p>
-                                               <figure  itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
+                                               <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
+                                                       <figcaption>How images are uploaded and managed</figcaption>
                                                    <a href="images/screenshots/image-manager.png" data-size="1666x910">
                                                        <img src="images/screenshots/thumb_image-manager.png" alt="Image Manager" loading="lazy">
                                                    </a>
                                <div class="row">
                                        <div class="col-sm-4 col-sm-offset-0 col-xs-8 col-xs-offset-2">
                                                <h4>All Books Overview</h4>
-                                               <p>An overview of the top-level categorisation</p>
-                                               <figure  itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
+                                               <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
+                                                       <figcaption>An overview of the top-level categorisation</figcaption>
                                                    <a href="images/screenshots/books-view.png" data-size="1666x910">
                                                        <img src="images/screenshots/thumb_books-view.png" alt="View of all books" loading="lazy">
                                                    </a>
                                        </div>
                                        <div class="col-sm-4 col-sm-offset-0 col-xs-8 col-xs-offset-2">
                                                <h4>Book Overview</h4>
-                                               <p>A view of the main content container: A book</p>
-                                               <figure  itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
+                                               <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
+                                                       <figcaption>A view of the main content container: A book</figcaption>
                                                    <a href="images/screenshots/book-overview.png" data-size="1666x910">
                                                        <img src="images/screenshots/thumb_book-overview.png" alt="Book Overview" loading="lazy">
                                                    </a>
                                        </div>
                                        <div class="col-sm-4 col-sm-offset-0 col-xs-8 col-xs-offset-2">
                                                <h4>Book Sorting</h4>
-                                               <p>How created content can be sorted within a book</p>
-                                               <figure  itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
+                                               <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
+                                                       <figcaption>How created content can be sorted within a book</figcaption>
                                                    <a href="images/screenshots/book-sorting.png" data-size="1666x910">
                                                        <img src="images/screenshots/thumb_book-sorting.png" alt="Book Content Sorting View" loading="lazy">
                                                    </a>
                                <div class="row">
                                        <div class="col-sm-4 col-sm-offset-0 col-xs-8 col-xs-offset-2">
                                                <h4>Global Search</h4>
-                                               <p>The main interface for searching created content</p>
                                                <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
+                                                       <figcaption>The main interface for searching created content</figcaption>
                                                    <a href="images/screenshots/search.png" data-size="1666x910">
                                                        <img src="images/screenshots/thumb_search.png" alt="Searching all content" loading="lazy">
                                                    </a>
                                        </div>
                                        <div class="col-sm-4 col-sm-offset-0 col-xs-8 col-xs-offset-2">
                                                <h4>App Settings</h4>
-                                               <p>A view the of application system settings</p>
                                                <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
+                                                       <figcaption>A view the of application system settings</figcaption>
                                                    <a href="images/screenshots/settings-view.png" data-size="1666x910">
                                                        <img src="images/screenshots/thumb_settings-view.png" alt="Settings View" loading="lazy">
                                                    </a>
                                        </div>
                                        <div class="col-sm-4 col-sm-offset-0 col-xs-8 col-xs-offset-2">
                                                <h4>Profile Page</h4>
-                                               <p>A user profile page, showing their activity and content</p>
                                                <figure itemprop="associatedMedia" itemscope itemtype="http://schema.org/ImageObject">
+                                                       <figcaption>A user profile page, showing their activity and content</figcaption>
                                                    <a href="images/screenshots/profile-page.png" data-size="1666x910">
                                                        <img src="images/screenshots/thumb_profile-page.png" alt="Profile Editing Screen" loading="lazy">
                                                    </a>
index eaf1290e0fb6c21fcf4f977581817fbb8b04796e..2e1138bd0d5f37df6b9881ca65141f9bfe78dbcd 100644 (file)
@@ -4,7 +4,7 @@
         <div class="container">
             <div class="row">
                <div class="col-lg-4">
-                       <p class="muted text-small">
+                       <p class="text-small">
                            BookStack - Created By <a href="https://danb.me" title="danb.me" target="_blank" rel="noopener">Dan Brown</a> and developed with the <a href="https://github.com/BookStackApp/BookStack/graphs/contributors" target="_blank" rel="noopener">community</a>.
                         <br>
                         <!-- Thanks to <a href="https://www.browserstack.com/" target="_blank">BrowserStack</a> for providing easy cross-browser testing. <br> -->
                        </p>
                </div>
                <div class="col-lg-8 col-md-9 menu">
-                    <a href="{{.Site.BaseURL}}docs"><span class="icon">{{partial "icon/book.svg"}}</span>Documentation</a>
-                    <a href="{{.Site.BaseURL}}#features"><span class="icon">{{partial "icon/star.svg"}}</span>Features</a>
-                    <a href="{{.Site.BaseURL}}#demo"><span class="icon">{{partial "icon/touch_app.svg"}}</span>Demo</a>
-                    <a href="https://github.com/BookStackApp/BookStack" target="_blank"><span class="icon">{{partial "icon/github.svg"}}</span>Github</a>
-                    <a href="https://discord.gg/ztkBqR2" target="_blank"><span class="icon">{{partial "icon/discord.svg"}}</span>Discord</a>
-                    <a href="{{.Site.BaseURL}}blog" target="_blank"><span class="icon">{{partial "icon/rss_feed.svg"}}</span>Blog</a>
+                    <a href="{{.Site.BaseURL}}docs"><span class="icon" aria-hidden="true">{{partial "icon/book.svg"}}</span>Documentation</a>
+                    <a href="{{.Site.BaseURL}}#features"><span class="icon" aria-hidden="true">{{partial "icon/star.svg"}}</span>Features</a>
+                    <a href="{{.Site.BaseURL}}#demo"><span class="icon" aria-hidden="true">{{partial "icon/touch_app.svg"}}</span>Demo</a>
+                    <a href="https://github.com/BookStackApp/BookStack" target="_blank"><span class="icon" aria-hidden="true">{{partial "icon/github.svg"}}</span>Github</a>
+                    <a href="https://discord.gg/ztkBqR2" target="_blank"><span class="icon" aria-hidden="true">{{partial "icon/discord.svg"}}</span>Discord</a>
+                    <a href="{{.Site.BaseURL}}blog" target="_blank"><span class="icon" aria-hidden="true">{{partial "icon/rss_feed.svg"}}</span>Blog</a>
                </div>
             </div>
             <p class="text-small">
-                This website uses Google Analytics for reporting on site metrics and Algolia for providing better search. Third party cookies are not used and IP addresses Google Analytics receives are anonymized to protect your Privacy.
+                This website uses a self-hosted instance of <a href="https://plausible.io/" target="_blank" rel="noreferrer">Plausible</a> for analytics.
+                Our site stats can <a href="https://analytics.bookstackapp.com/bookstackapp.com" target="_blank" rel="noreferrer">be viewed here</a>. 
+                <br>
+                We also use <a href="https://docsearch.algolia.com/" target="_blank" rel="noreferrer">Algolia</a> for providing better search.
             </p>
         </div>
     </footer>
index 98817effd23cd75fd4f99f70d722a84406685658..0cb85b56bbf0ec0a393bb9d92ef63f497db15556 100644 (file)
@@ -52,7 +52,7 @@
     <link rel="icon" type="image/png" href="/images/favicon-96x96.png" sizes="96x96" />
     <link rel="icon" type="image/png" href="/images/favicon-32x32.png" sizes="32x32" />
 
-    <link rel="stylesheet" type="text/css" href="{{.Site.BaseURL}}css/styles.css?v=1.3" />
+    <link rel="stylesheet" type="text/css" href="{{.Site.BaseURL}}css/styles.css?v={{ now.Format "2006-01-02T15:04:05" }}" />
 
 
     {{ if .Site.Params.RSSLink}}
 
     <link rel="canonical" href="{{ .Permalink }}" />
 
-    {{with  .Site.Params.googleAnalyticsUserID }}
-    <script>
-
-        (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
-        (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
-        m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
-        })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
-
-        var GA_LOCAL_STORAGE_KEY = 'ga:clientId';
-
-        if (window.localStorage) {
-            ga('create', '{{.}}', {
-                'storage': 'none',
-                'clientId': localStorage.getItem(GA_LOCAL_STORAGE_KEY)
-            });
-            ga(function (tracker) {
-                localStorage.setItem(GA_LOCAL_STORAGE_KEY, tracker.get('clientId'));
-            });
-        }
-        else {
-            ga('create', '{{.}}', {'storage': 'none'});
-        }
-
-        ga('set', 'anonymizeIp', true);
-        ga('send', 'pageview');
-      
-    </script>
-    {{end}}
+    <script async defer data-domain="bookstackapp.com" src="https://analytics.bookstackapp.com/js/plausible.js"></script>
 
     <!-- at the end of the HEAD -->
     <link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/2/docsearch.min.css" />
                 <div class="col-md-9 col-sm-6 menu col-xs-4">
                     <button tabindex="1" id="menu-button" class="button muted" type="button">{{partial "icon/menu.svg"}}</button>
                     <div class="inner">
-                        <a href="/docs"><span class="icon">{{partial "icon/book.svg"}}</span>Documentation</a>
-                        <a href="/#features"><span class="icon">{{partial "icon/star.svg"}}</span>Features</a>
-                        <a href="/#demo"><span class="icon">{{partial "icon/touch_app.svg"}}</span>Demo</a>
-                        <a href="https://github.com/BookStackApp/BookStack" target="_blank"><span class="icon">{{partial "icon/github.svg"}}</span>Github</a>
-                        <a href="https://discord.gg/ztkBqR2" target="_blank"><span class="icon">{{partial "icon/discord.svg"}}</span>Discord</a>
-                        <a href="/blog"><span class="icon">{{partial "icon/rss_feed.svg"}}</span>Blog</a>
+                        <a href="/docs"><span class="icon" aria-hidden="true">{{partial "icon/book.svg"}}</span>Documentation</a>
+                        <a href="/#features"><span class="icon" aria-hidden="true">{{partial "icon/star.svg"}}</span>Features</a>
+                        <a href="/#demo"><span class="icon" aria-hidden="true">{{partial "icon/touch_app.svg"}}</span>Demo</a>
+                        <a href="https://github.com/BookStackApp/BookStack" target="_blank"><span class="icon" aria-hidden="true">{{partial "icon/github.svg"}}</span>Github</a>
+                        <a href="https://discord.gg/ztkBqR2" target="_blank"><span class="icon" aria-hidden="true">{{partial "icon/discord.svg"}}</span>Discord</a>
+                        <a href="/blog"><span class="icon" aria-hidden="true">{{partial "icon/rss_feed.svg"}}</span>Blog</a>
                     </div>
                 </div>
             </div>
index 962a98f42582f5949d5c589b9a3c81a4cb5c39d2..0cb11f026a509612a6aa1339d14018b6f3851d5a 100644 (file)
@@ -1,13 +1,13 @@
-<svg id="svg4200" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="61.699mm" width="65.023mm" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 230.39711 218.6199">
- <g id="layer1" stroke-linejoin="round" fill-rule="evenodd" transform="translate(-245.27 -58.434)" stroke="#0288d1" stroke-width="6" fill="#fff">
+<svg xmlns="http://www.w3.org/2000/svg" height="61.699mm" width="65.023mm" version="1.1" viewBox="0 0 230.39711 218.6199" aria-label="BookStack Logo">
+ <g stroke-linejoin="round" fill-rule="evenodd" transform="translate(-245.27 -58.434)" stroke="#0288d1" stroke-width="6" fill="#fff">
   <g stroke-linecap="round">
-   <path id="path5686" d="m343.79 238.6 128.88-74.409-92.058-53.15-128.88 74.409z"/>
-   <path id="path5688" d="m251.73 185.45v21.26l92.058 53.15 128.88-74.409v-21.26"/>
-   <path id="path5694" d="m343.79 274.03-92.058-53.15s-7.5-16.918 0-28.346l92.058 53.15 128.88-74.409v28.346l-128.88 74.409"/>
-   <path id="path5686-5" d="m343.79 188.99 128.88-74.41-92.06-53.146-128.88 74.406z"/>
-   <path id="path5692-7" d="m343.79 188.99 128.88-74.409 0.00001 28.346-128.88 74.409-92.058-53.15s-6.0714-17.632 0-28.346z"/>
-   <path id="path5694-5" d="m343.79 245.69-92.058-53.15s-7.5-16.918 0-28.346l92.058 53.15 128.88-74.409-0.00001 28.346-128.88 74.409"/>
+   <path d="m343.79 238.6 128.88-74.409-92.058-53.15-128.88 74.409z"/>
+   <path d="m251.73 185.45v21.26l92.058 53.15 128.88-74.409v-21.26"/>
+   <path d="m343.79 274.03-92.058-53.15s-7.5-16.918 0-28.346l92.058 53.15 128.88-74.409v28.346l-128.88 74.409"/>
+   <path d="m343.79 188.99 128.88-74.41-92.06-53.146-128.88 74.406z"/>
+   <path d="m343.79 188.99 128.88-74.409 0.00001 28.346-128.88 74.409-92.058-53.15s-6.0714-17.632 0-28.346z"/>
+   <path d="m343.79 245.69-92.058-53.15s-7.5-16.918 0-28.346l92.058 53.15 128.88-74.409-0.00001 28.346-128.88 74.409"/>
   </g>
-  <path id="path5831" d="m402.09 73.836-55.234 31.89 21.48 1.7716 3.0686 12.402 55.235-31.89z"/>
+  <path d="m402.09 73.836-55.234 31.89 21.48 1.7716 3.0686 12.402 55.235-31.89z"/>
  </g>
 </svg>
diff --git a/themes/bookstack/layouts/partials/mailchimp.html b/themes/bookstack/layouts/partials/mailchimp.html
deleted file mode 100644 (file)
index e1d3f9c..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<!-- Begin MailChimp Signup Form -->
-
-<div id="mc_embed_signup">
-    <form action="https://bookstackapp.us14.list-manage.com/subscribe/post?u=18917f477406e2be3f062086a&amp;id=7de4fb0c79" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>
-        <h4>Subscribe to Updates</h4>
-        <p>This is a weekly newsletter, summarising content from the blog.</p>
-        <div class="mc-field-group">
-            <input placeholder="Email address" type="email" value="" name="EMAIL" class="required email" id="mce-EMAIL">
-            <button class="button">Subscribe</button>
-        </div>
-        <div id="mce-responses" class="clear">
-            <div class="response" id="mce-error-response" style="display:none"></div>
-            <div class="response" id="mce-success-response" style="display:none"></div>
-        </div>    <!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
-        <div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_18917f477406e2be3f062086a_7de4fb0c79" tabindex="-1" value=""></div>
-        <p class="text-small">This service uses MailChimp to manage sending emails so any information provided will go into their systems. Feel free to review their <a href="https://mailchimp.com/legal/privacy" target="_blank">Privacy Policy</a> and <a href="https://mailchimp.com/legal/terms" target="_blank">Terms</a>. You'll be able to opt-out via a link in the email whenever you want. If you don't trust MailChimp or any BookStack maintainers with the data you provide or emit then please don't sign up.</p>
-        <p class="text-small">A security-specific mailing list <a href="http://eepurl.com/glIh8z" target="_blank">can be found here</a>.</p>
-    </form>
-</div>
\ No newline at end of file
diff --git a/themes/bookstack/layouts/partials/signup.html b/themes/bookstack/layouts/partials/signup.html
new file mode 100644 (file)
index 0000000..8134d28
--- /dev/null
@@ -0,0 +1,14 @@
+<!-- Begin MailChimp Signup Form -->
+
+<div id="mc_embed_signup">
+    <h4>Subscribe to Updates</h4>
+    <p>
+        There are two lists you can sign-up to for updates, A general news & updates list, sent on a weekly basis, and a security alerts list
+        that's sent when new security updates are available.
+    </p>
+    <p>
+        <a href="https://updates.bookstackapp.com/signup/bookstack-news-and-updates" target="_blank">News and Updates</a>
+        <span class="muted padded-horizontal">|</span>
+        <a href="https://updates.bookstackapp.com/signup/bookstack-security-updates" target="_blank">Security Alerts</a>
+    </p>
+</div>
\ No newline at end of file
index ac23d4747225bea2be37068196158ee31a76302b..dfee5fdedb2ec3b064089b715430bf7cbdfa559c 100644 (file)
        border: 0;
 }
 
+.post-content {
+       max-width: 700px;
+       margin: 0 auto;
+}
+
 .post-content img:not(.no-border) {
        border-radius: 3px;
        border: 1px solid #DDD;
   border-radius: 3px;
 }
 
+.post-content iframe {
+  max-width: 100%;
+}
+
 .pagination {
        text-align: center;
        font-size: 0.8em;
@@ -65,10 +74,11 @@ article.post {
 
 #mc_embed_signup {
        background: #F8F8F8;
-       padding: $-m;
+       padding: $-l;
        border: 1px solid #DDD;
        margin-bottom: $-xl;
        margin-top: $-l;
+       border-radius: 4px;
        h4 {
                margin-top: 0;
        }
index 72fa33cfedfc1f3a76244cb929f53d844d8c16c2..fc088790dcbbf9fe732a9da0cfd192f5963c5d08 100644 (file)
   &:active {
     background-color: darken($backgroundColor, 8%);
   }
+  &:focus {
+    outline: 1px solid $primary;
+    outline-offset: 3px;
+  }
 }
 
 // Button Specific Variables
@@ -31,51 +35,13 @@ $button-border-radius: 2px;
   cursor: pointer;
   transition: all ease-in-out 120ms;
   box-shadow: 0 0.5px 1.5px 0 rgba(0, 0, 0, 0.21);
-  @include generate-button-colors(#EEE, $primary);
+  @include generate-button-colors(#FFF, $primary);
 }
 
 .button, input[type="button"], input[type="submit"]  {
   @extend .button-base;
-  &.pos {
-    @include generate-button-colors(#EEE, $positive);
-  }
-  &.neg {
-    @include generate-button-colors(#EEE, $negative);
-  }
-  &.secondary {
-    @include generate-button-colors(#EEE, $secondary);
-  }
   &.muted {
-    @include generate-button-colors(#EEE, #888);
-  }
-}
-
-.text-button {
-  @extend .link;
-  background-color: transparent;
-  padding: 0;
-  margin: 0;
-  border: none;
-  &:focus, &:active {
-    outline: 0;
-  }
-  &.neg {
-    color: $negative;
-  }
-}
-
-.button-group {
-  @include clearfix;
-  .button, button[type="button"] {
-    margin: $-xs 0 $-xs 0;
-    float: left;
-    border-radius: 0;
-    &:first-child {
-      border-radius: $button-border-radius 0 0 $button-border-radius;
-    }
-    &:last-child {
-      border-radius: 0 $button-border-radius $button-border-radius 0;
-    }
+    @include generate-button-colors(#FFF, #888);
   }
 }
 
diff --git a/themes/bookstack/sass/_code.scss b/themes/bookstack/sass/_code.scss
new file mode 100644 (file)
index 0000000..2a44e3c
--- /dev/null
@@ -0,0 +1,82 @@
+/* Background */ .chroma { background-color: #F8F8F8 }
+/* Other */ .chroma .x {  }
+/* Error */ .chroma .err {  }
+/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
+/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; width: 100%; overflow: auto; display: block; }
+/* LineHighlight */ .chroma .hl { display: block; width: 100%;background-color: #ffffcc }
+/* LineNumbersTable */ .chroma .lnt { margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
+/* LineNumbers */ .chroma .ln { margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
+/* Keyword */ .chroma .k { color: #0000ff }
+/* KeywordConstant */ .chroma .kc { color: #0000ff }
+/* KeywordDeclaration */ .chroma .kd { color: #0000ff }
+/* KeywordNamespace */ .chroma .kn { color: #0000ff }
+/* KeywordPseudo */ .chroma .kp { color: #0000ff }
+/* KeywordReserved */ .chroma .kr { color: #0000ff }
+/* KeywordType */ .chroma .kt { color: #2b91af }
+/* Name */ .chroma .n {  }
+/* NameAttribute */ .chroma .na {  }
+/* NameBuiltin */ .chroma .nb {  }
+/* NameBuiltinPseudo */ .chroma .bp {  }
+/* NameClass */ .chroma .nc { color: #2b91af }
+/* NameConstant */ .chroma .no {  }
+/* NameDecorator */ .chroma .nd {  }
+/* NameEntity */ .chroma .ni {  }
+/* NameException */ .chroma .ne {  }
+/* NameFunction */ .chroma .nf {  }
+/* NameFunctionMagic */ .chroma .fm {  }
+/* NameLabel */ .chroma .nl {  }
+/* NameNamespace */ .chroma .nn {  }
+/* NameOther */ .chroma .nx {  }
+/* NameProperty */ .chroma .py {  }
+/* NameTag */ .chroma .nt {  }
+/* NameVariable */ .chroma .nv {  }
+/* NameVariableClass */ .chroma .vc {  }
+/* NameVariableGlobal */ .chroma .vg {  }
+/* NameVariableInstance */ .chroma .vi {  }
+/* NameVariableMagic */ .chroma .vm {  }
+/* Literal */ .chroma .l {  }
+/* LiteralDate */ .chroma .ld {  }
+/* LiteralString */ .chroma .s { color: #a31515 }
+/* LiteralStringAffix */ .chroma .sa { color: #a31515 }
+/* LiteralStringBacktick */ .chroma .sb { color: #a31515 }
+/* LiteralStringChar */ .chroma .sc { color: #a31515 }
+/* LiteralStringDelimiter */ .chroma .dl { color: #a31515 }
+/* LiteralStringDoc */ .chroma .sd { color: #a31515 }
+/* LiteralStringDouble */ .chroma .s2 { color: #a31515 }
+/* LiteralStringEscape */ .chroma .se { color: #a31515 }
+/* LiteralStringHeredoc */ .chroma .sh { color: #a31515 }
+/* LiteralStringInterpol */ .chroma .si { color: #a31515 }
+/* LiteralStringOther */ .chroma .sx { color: #a31515 }
+/* LiteralStringRegex */ .chroma .sr { color: #a31515 }
+/* LiteralStringSingle */ .chroma .s1 { color: #a31515 }
+/* LiteralStringSymbol */ .chroma .ss { color: #a31515 }
+/* LiteralNumber */ .chroma .m {  }
+/* LiteralNumberBin */ .chroma .mb {  }
+/* LiteralNumberFloat */ .chroma .mf {  }
+/* LiteralNumberHex */ .chroma .mh {  }
+/* LiteralNumberInteger */ .chroma .mi {  }
+/* LiteralNumberIntegerLong */ .chroma .il {  }
+/* LiteralNumberOct */ .chroma .mo {  }
+/* Operator */ .chroma .o {  }
+/* OperatorWord */ .chroma .ow { color: #0000ff }
+/* Punctuation */ .chroma .p {  }
+/* Comment */ .chroma .c { color: #008000 }
+/* CommentHashbang */ .chroma .ch { color: #008000 }
+/* CommentMultiline */ .chroma .cm { color: #008000 }
+/* CommentSingle */ .chroma .c1 { color: #008000 }
+/* CommentSpecial */ .chroma .cs { color: #008000 }
+/* CommentPreproc */ .chroma .cp { color: #0000ff }
+/* CommentPreprocFile */ .chroma .cpf { color: #0000ff }
+/* Generic */ .chroma .g {  }
+/* GenericDeleted */ .chroma .gd {  }
+/* GenericEmph */ .chroma .ge { font-style: italic }
+/* GenericError */ .chroma .gr {  }
+/* GenericHeading */ .chroma .gh { font-weight: bold }
+/* GenericInserted */ .chroma .gi {  }
+/* GenericOutput */ .chroma .go {  }
+/* GenericPrompt */ .chroma .gp { font-weight: bold }
+/* GenericStrong */ .chroma .gs { font-weight: bold }
+/* GenericSubheading */ .chroma .gu { font-weight: bold }
+/* GenericTraceback */ .chroma .gt {  }
+/* GenericUnderline */ .chroma .gl {  }
+/* TextWhitespace */ .chroma .w {  }
\ No newline at end of file
index 213ae63a3ee1c5ad624440a18232e2709365a944..65144842550b837a67df43594643ded1c0cf117e 100644 (file)
@@ -1,27 +1,3 @@
-
-/** Flexbox styling rules **/
-body.flexbox {
-  display: flex;
-  flex-direction: column;
-  align-items: stretch;
-  height: 100%;
-  min-height: 100%;
-  max-height: 100%;
-  overflow: hidden;
-  #content {
-    flex: 1;
-    display: flex;
-  }
-}
-
-.flex-fill {
-  display: flex;
-  align-items: stretch;
-  .flex, &.flex {
-    flex: 1;
-  }
-}
-
 /** Rules for all columns */
 div[class^="col-"] img {
   max-width: 100%;
@@ -41,20 +17,6 @@ div[class^="col-"] img {
   }
 }
 
-.center-box {
-  margin: $-xl auto 0 auto;
-  padding: $-m $-xxl $-xl*2 $-xxl;
-  max-width: 346px;
-  display: inline-block;
-  text-align: left;
-  vertical-align: top;
-  &.login {
-    background-color: #EEE;
-    box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.1);
-    border: 1px solid #DDD;
-  }
-}
-
 .row {
   margin-left: -$-m;
   margin-right: -$-m;
@@ -131,84 +93,6 @@ div[class^="col-"] img {
 .col-xs-1 {
   width: 8.33333333%;
 }
-.col-xs-pull-12 {
-  right: 100%;
-}
-.col-xs-pull-11 {
-  right: 91.66666667%;
-}
-.col-xs-pull-10 {
-  right: 83.33333333%;
-}
-.col-xs-pull-9 {
-  right: 75%;
-}
-.col-xs-pull-8 {
-  right: 66.66666667%;
-}
-.col-xs-pull-7 {
-  right: 58.33333333%;
-}
-.col-xs-pull-6 {
-  right: 50%;
-}
-.col-xs-pull-5 {
-  right: 41.66666667%;
-}
-.col-xs-pull-4 {
-  right: 33.33333333%;
-}
-.col-xs-pull-3 {
-  right: 25%;
-}
-.col-xs-pull-2 {
-  right: 16.66666667%;
-}
-.col-xs-pull-1 {
-  right: 8.33333333%;
-}
-.col-xs-pull-0 {
-  right: auto;
-}
-.col-xs-push-12 {
-  left: 100%;
-}
-.col-xs-push-11 {
-  left: 91.66666667%;
-}
-.col-xs-push-10 {
-  left: 83.33333333%;
-}
-.col-xs-push-9 {
-  left: 75%;
-}
-.col-xs-push-8 {
-  left: 66.66666667%;
-}
-.col-xs-push-7 {
-  left: 58.33333333%;
-}
-.col-xs-push-6 {
-  left: 50%;
-}
-.col-xs-push-5 {
-  left: 41.66666667%;
-}
-.col-xs-push-4 {
-  left: 33.33333333%;
-}
-.col-xs-push-3 {
-  left: 25%;
-}
-.col-xs-push-2 {
-  left: 16.66666667%;
-}
-.col-xs-push-1 {
-  left: 8.33333333%;
-}
-.col-xs-push-0 {
-  left: auto;
-}
 .col-xs-offset-12 {
   margin-left: 100%;
 }
@@ -288,84 +172,6 @@ div[class^="col-"] img {
   .col-sm-1 {
     width: 8.33333333%;
   }
-  .col-sm-pull-12 {
-    right: 100%;
-  }
-  .col-sm-pull-11 {
-    right: 91.66666667%;
-  }
-  .col-sm-pull-10 {
-    right: 83.33333333%;
-  }
-  .col-sm-pull-9 {
-    right: 75%;
-  }
-  .col-sm-pull-8 {
-    right: 66.66666667%;
-  }
-  .col-sm-pull-7 {
-    right: 58.33333333%;
-  }
-  .col-sm-pull-6 {
-    right: 50%;
-  }
-  .col-sm-pull-5 {
-    right: 41.66666667%;
-  }
-  .col-sm-pull-4 {
-    right: 33.33333333%;
-  }
-  .col-sm-pull-3 {
-    right: 25%;
-  }
-  .col-sm-pull-2 {
-    right: 16.66666667%;
-  }
-  .col-sm-pull-1 {
-    right: 8.33333333%;
-  }
-  .col-sm-pull-0 {
-    right: auto;
-  }
-  .col-sm-push-12 {
-    left: 100%;
-  }
-  .col-sm-push-11 {
-    left: 91.66666667%;
-  }
-  .col-sm-push-10 {
-    left: 83.33333333%;
-  }
-  .col-sm-push-9 {
-    left: 75%;
-  }
-  .col-sm-push-8 {
-    left: 66.66666667%;
-  }
-  .col-sm-push-7 {
-    left: 58.33333333%;
-  }
-  .col-sm-push-6 {
-    left: 50%;
-  }
-  .col-sm-push-5 {
-    left: 41.66666667%;
-  }
-  .col-sm-push-4 {
-    left: 33.33333333%;
-  }
-  .col-sm-push-3 {
-    left: 25%;
-  }
-  .col-sm-push-2 {
-    left: 16.66666667%;
-  }
-  .col-sm-push-1 {
-    left: 8.33333333%;
-  }
-  .col-sm-push-0 {
-    left: auto;
-  }
   .col-sm-offset-12 {
     margin-left: 100%;
   }
@@ -446,84 +252,6 @@ div[class^="col-"] img {
   .col-md-1 {
     width: 8.33333333%;
   }
-  .col-md-pull-12 {
-    right: 100%;
-  }
-  .col-md-pull-11 {
-    right: 91.66666667%;
-  }
-  .col-md-pull-10 {
-    right: 83.33333333%;
-  }
-  .col-md-pull-9 {
-    right: 75%;
-  }
-  .col-md-pull-8 {
-    right: 66.66666667%;
-  }
-  .col-md-pull-7 {
-    right: 58.33333333%;
-  }
-  .col-md-pull-6 {
-    right: 50%;
-  }
-  .col-md-pull-5 {
-    right: 41.66666667%;
-  }
-  .col-md-pull-4 {
-    right: 33.33333333%;
-  }
-  .col-md-pull-3 {
-    right: 25%;
-  }
-  .col-md-pull-2 {
-    right: 16.66666667%;
-  }
-  .col-md-pull-1 {
-    right: 8.33333333%;
-  }
-  .col-md-pull-0 {
-    right: auto;
-  }
-  .col-md-push-12 {
-    left: 100%;
-  }
-  .col-md-push-11 {
-    left: 91.66666667%;
-  }
-  .col-md-push-10 {
-    left: 83.33333333%;
-  }
-  .col-md-push-9 {
-    left: 75%;
-  }
-  .col-md-push-8 {
-    left: 66.66666667%;
-  }
-  .col-md-push-7 {
-    left: 58.33333333%;
-  }
-  .col-md-push-6 {
-    left: 50%;
-  }
-  .col-md-push-5 {
-    left: 41.66666667%;
-  }
-  .col-md-push-4 {
-    left: 33.33333333%;
-  }
-  .col-md-push-3 {
-    left: 25%;
-  }
-  .col-md-push-2 {
-    left: 16.66666667%;
-  }
-  .col-md-push-1 {
-    left: 8.33333333%;
-  }
-  .col-md-push-0 {
-    left: auto;
-  }
   .col-md-offset-12 {
     margin-left: 100%;
   }
@@ -604,84 +332,6 @@ div[class^="col-"] img {
   .col-lg-1 {
     width: 8.33333333%;
   }
-  .col-lg-pull-12 {
-    right: 100%;
-  }
-  .col-lg-pull-11 {
-    right: 91.66666667%;
-  }
-  .col-lg-pull-10 {
-    right: 83.33333333%;
-  }
-  .col-lg-pull-9 {
-    right: 75%;
-  }
-  .col-lg-pull-8 {
-    right: 66.66666667%;
-  }
-  .col-lg-pull-7 {
-    right: 58.33333333%;
-  }
-  .col-lg-pull-6 {
-    right: 50%;
-  }
-  .col-lg-pull-5 {
-    right: 41.66666667%;
-  }
-  .col-lg-pull-4 {
-    right: 33.33333333%;
-  }
-  .col-lg-pull-3 {
-    right: 25%;
-  }
-  .col-lg-pull-2 {
-    right: 16.66666667%;
-  }
-  .col-lg-pull-1 {
-    right: 8.33333333%;
-  }
-  .col-lg-pull-0 {
-    right: auto;
-  }
-  .col-lg-push-12 {
-    left: 100%;
-  }
-  .col-lg-push-11 {
-    left: 91.66666667%;
-  }
-  .col-lg-push-10 {
-    left: 83.33333333%;
-  }
-  .col-lg-push-9 {
-    left: 75%;
-  }
-  .col-lg-push-8 {
-    left: 66.66666667%;
-  }
-  .col-lg-push-7 {
-    left: 58.33333333%;
-  }
-  .col-lg-push-6 {
-    left: 50%;
-  }
-  .col-lg-push-5 {
-    left: 41.66666667%;
-  }
-  .col-lg-push-4 {
-    left: 33.33333333%;
-  }
-  .col-lg-push-3 {
-    left: 25%;
-  }
-  .col-lg-push-2 {
-    left: 16.66666667%;
-  }
-  .col-lg-push-1 {
-    left: 8.33333333%;
-  }
-  .col-lg-push-0 {
-    left: auto;
-  }
   .col-lg-offset-12 {
     margin-left: 100%;
   }
index 5618231b17b666ec8c3c67cb1abcd75a46b75a52..158798d3e358d46b601d992026758086d23faedb 100644 (file)
@@ -9,7 +9,7 @@ body {
   font-family: $text;
   font-size: $fs-m;
   line-height: 1.6;
-  color: #616161;
+  color: #555;
   overflow-x: hidden;
   max-width: 100%;
 }
index b7bc369d0dcafab3130b2719f3c6a9fc304521e1..e48cb3289c28ed6ebf651f0a28a27f1f3879be77 100644 (file)
@@ -70,7 +70,7 @@ h1, h2, h3, h4, h5 {
   font-weight: 400;
   position: relative;
   display: block;
-  color: #555;
+  color: #444;
   .subheader, small {
     font-size: 0.5em;
     line-height: 1em;
@@ -144,7 +144,6 @@ em, i, .italic {
 
 small, p.small, span.small, .text-small {
   font-size: 0.8em;
-  color: lighten($text-dark, 20%);
 }
 
 sup, .superscript {
@@ -160,7 +159,6 @@ pre {
   border-radius: 2px;
   // box-shadow: inset 1px 2px 2px rgba(10, 10, 10, 0.06);
   border: 1px solid #DDD;
-  border-top: 3px solid $primary;
   background-color: #F8F8F8;
   padding: 0;
   overflow-x: auto;
@@ -218,6 +216,7 @@ pre code {
   max-width: 100%;
   display: block;
   margin-bottom: 0;
+  padding: .5rem 1rem;
 }
 /*
  * Text colors
index 095a0e0dc24582d29eeba63e8036a7be9a6e7d14..30848c1dbec35bf16d9643f063db19ac5fa6e06f 100644 (file)
@@ -29,12 +29,12 @@ $-xxs: 3px;
 // Fonts
 $heading:  'Roboto', Helvetica, Arial, sans-serif;
 $text: 'Roboto', Helvetica, Arial, sans-serif;
-$fs-m: 15px;
+$fs-m: 16px;
 $fs-s: 14px;
 
 // Colours
-$primary: #0288D1;
-$primary-dark: #0288D1;
+$primary: #0078b9;
+$primary-dark: #0078b9;
 $secondary: #e27b41;
 $positive: #52A256;
 $negative: #E84F4F;
index 047e94068131fb56bed2b729794ff66aec839aef..593bf30554031a76e543e339e021a1c50d6a9e2c 100644 (file)
@@ -2,6 +2,7 @@
 @import "variables";
 @import "mixins";
 @import "html";
+@import "code";
 @import "codemirror";
 @import "text";
 @import "grid";
@@ -240,8 +241,15 @@ input[type=text] {
       box-shadow: 0 5px 10px 1px rgba(0, 0, 0, 0.1);
     }
   }
+  figcaption {
+    margin-bottom: .5rem;
+  }
+  h4 {
+    margin-bottom: 0;
+  }
 }
 
+
 .docs-content {
   padding-bottom: $-xxl;
   .edit-link {
@@ -329,7 +337,9 @@ h2.thin-margin {
   margin-bottom: $-m;
   width: 280px;
   background-color: #FFF;
-  border: 1px solid #DDD;
+  border-radius: 4px;
+  overflow: hidden;
+  box-shadow: 0 0 3px 1px rgba(0, 0, 0, 0.1);
   a {
     display: block;
   }
@@ -341,6 +351,9 @@ h2.thin-margin {
     padding: $-m;
     min-height: 80px;
   }
+  &:hover {
+    box-shadow: 0 0 3px 1px rgba(0, 0, 0, 0.15);
+  }
 }
 
 
index 19364df02164e40c29b69fde5a80d3a6fe006e82..0c3adb41b7d67916452cc037716400b60ce57712 100644 (file)
@@ -43,6 +43,7 @@ var modeMap = {
   'language-nginx': 'nginx',
   'language-apache': 'apache',
   'language-php': 'php',
+  'language-sql': 'text/x-mysql',
 };
 
 var codeBlocks = document.querySelectorAll('pre');
index 39efca3c2460e0e8ab1d271da09126db84ebac5b..497dba4b10cbb5f79d878270c45bdf12776d318d 100644 (file)
@@ -2533,3 +2533,321 @@ if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
   CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
 
 });
+
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: https://codemirror.net/LICENSE
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("sql", function(config, parserConfig) {
+  var client         = parserConfig.client || {},
+      atoms          = parserConfig.atoms || {"false": true, "true": true, "null": true},
+      builtin        = parserConfig.builtin || set(defaultBuiltin),
+      keywords       = parserConfig.keywords || set(sqlKeywords),
+      operatorChars  = parserConfig.operatorChars || /^[*+\-%<>!=&|~^\/]/,
+      support        = parserConfig.support || {},
+      hooks          = parserConfig.hooks || {},
+      dateSQL        = parserConfig.dateSQL || {"date" : true, "time" : true, "timestamp" : true},
+      backslashStringEscapes = parserConfig.backslashStringEscapes !== false,
+      brackets       = parserConfig.brackets || /^[\{}\(\)\[\]]/,
+      punctuation    = parserConfig.punctuation || /^[;.,:]/
+
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+
+    // call hooks from the mime type
+    if (hooks[ch]) {
+      var result = hooks[ch](stream, state);
+      if (result !== false) return result;
+    }
+
+    if (support.hexNumber &&
+      ((ch == "0" && stream.match(/^[xX][0-9a-fA-F]+/))
+      || (ch == "x" || ch == "X") && stream.match(/^'[0-9a-fA-F]+'/))) {
+      // hex
+      // ref: http://dev.mysql.com/doc/refman/5.5/en/hexadecimal-literals.html
+      return "number";
+    } else if (support.binaryNumber &&
+      (((ch == "b" || ch == "B") && stream.match(/^'[01]+'/))
+      || (ch == "0" && stream.match(/^b[01]+/)))) {
+      // bitstring
+      // ref: http://dev.mysql.com/doc/refman/5.5/en/bit-field-literals.html
+      return "number";
+    } else if (ch.charCodeAt(0) > 47 && ch.charCodeAt(0) < 58) {
+      // numbers
+      // ref: http://dev.mysql.com/doc/refman/5.5/en/number-literals.html
+      stream.match(/^[0-9]*(\.[0-9]+)?([eE][-+]?[0-9]+)?/);
+      support.decimallessFloat && stream.match(/^\.(?!\.)/);
+      return "number";
+    } else if (ch == "?" && (stream.eatSpace() || stream.eol() || stream.eat(";"))) {
+      // placeholders
+      return "variable-3";
+    } else if (ch == "'" || (ch == '"' && support.doubleQuote)) {
+      // strings
+      // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
+      state.tokenize = tokenLiteral(ch);
+      return state.tokenize(stream, state);
+    } else if ((((support.nCharCast && (ch == "n" || ch == "N"))
+        || (support.charsetCast && ch == "_" && stream.match(/[a-z][a-z0-9]*/i)))
+        && (stream.peek() == "'" || stream.peek() == '"'))) {
+      // charset casting: _utf8'str', N'str', n'str'
+      // ref: http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
+      return "keyword";
+    } else if (support.escapeConstant && (ch == "e" || ch == "E")
+        && (stream.peek() == "'" || (stream.peek() == '"' && support.doubleQuote))) {
+      // escape constant: E'str', e'str'
+      // ref: https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE
+      state.tokenize = function(stream, state) {
+        return (state.tokenize = tokenLiteral(stream.next(), true))(stream, state);
+      }
+      return "keyword";
+    } else if (support.commentSlashSlash && ch == "/" && stream.eat("/")) {
+      // 1-line comment
+      stream.skipToEnd();
+      return "comment";
+    } else if ((support.commentHash && ch == "#")
+        || (ch == "-" && stream.eat("-") && (!support.commentSpaceRequired || stream.eat(" ")))) {
+      // 1-line comments
+      // ref: https://kb.askmonty.org/en/comment-syntax/
+      stream.skipToEnd();
+      return "comment";
+    } else if (ch == "/" && stream.eat("*")) {
+      // multi-line comments
+      // ref: https://kb.askmonty.org/en/comment-syntax/
+      state.tokenize = tokenComment(1);
+      return state.tokenize(stream, state);
+    } else if (ch == ".") {
+      // .1 for 0.1
+      if (support.zerolessFloat && stream.match(/^(?:\d+(?:e[+-]?\d+)?)/i))
+        return "number";
+      if (stream.match(/^\.+/))
+        return null
+      // .table_name (ODBC)
+      // // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
+      if (support.ODBCdotTable && stream.match(/^[\w\d_$#]+/))
+        return "variable-2";
+    } else if (operatorChars.test(ch)) {
+      // operators
+      stream.eatWhile(operatorChars);
+      return "operator";
+    } else if (brackets.test(ch)) {
+      // brackets
+      return "bracket";
+    } else if (punctuation.test(ch)) {
+      // punctuation
+      stream.eatWhile(punctuation);
+      return "punctuation";
+    } else if (ch == '{' &&
+        (stream.match(/^( )*(d|D|t|T|ts|TS)( )*'[^']*'( )*}/) || stream.match(/^( )*(d|D|t|T|ts|TS)( )*"[^"]*"( )*}/))) {
+      // dates (weird ODBC syntax)
+      // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html
+      return "number";
+    } else {
+      stream.eatWhile(/^[_\w\d]/);
+      var word = stream.current().toLowerCase();
+      // dates (standard SQL syntax)
+      // ref: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html
+      if (dateSQL.hasOwnProperty(word) && (stream.match(/^( )+'[^']*'/) || stream.match(/^( )+"[^"]*"/)))
+        return "number";
+      if (atoms.hasOwnProperty(word)) return "atom";
+      if (builtin.hasOwnProperty(word)) return "builtin";
+      if (keywords.hasOwnProperty(word)) return "keyword";
+      if (client.hasOwnProperty(word)) return "string-2";
+      return null;
+    }
+  }
+
+  // 'string', with char specified in quote escaped by '\'
+  function tokenLiteral(quote, backslashEscapes) {
+    return function(stream, state) {
+      var escaped = false, ch;
+      while ((ch = stream.next()) != null) {
+        if (ch == quote && !escaped) {
+          state.tokenize = tokenBase;
+          break;
+        }
+        escaped = (backslashStringEscapes || backslashEscapes) && !escaped && ch == "\\";
+      }
+      return "string";
+    };
+  }
+  function tokenComment(depth) {
+    return function(stream, state) {
+      var m = stream.match(/^.*?(\/\*|\*\/)/)
+      if (!m) stream.skipToEnd()
+      else if (m[1] == "/*") state.tokenize = tokenComment(depth + 1)
+      else if (depth > 1) state.tokenize = tokenComment(depth - 1)
+      else state.tokenize = tokenBase
+      return "comment"
+    }
+  }
+
+  function pushContext(stream, state, type) {
+    state.context = {
+      prev: state.context,
+      indent: stream.indentation(),
+      col: stream.column(),
+      type: type
+    };
+  }
+
+  function popContext(state) {
+    state.indent = state.context.indent;
+    state.context = state.context.prev;
+  }
+
+  return {
+    startState: function() {
+      return {tokenize: tokenBase, context: null};
+    },
+
+    token: function(stream, state) {
+      if (stream.sol()) {
+        if (state.context && state.context.align == null)
+          state.context.align = false;
+      }
+      if (state.tokenize == tokenBase && stream.eatSpace()) return null;
+
+      var style = state.tokenize(stream, state);
+      if (style == "comment") return style;
+
+      if (state.context && state.context.align == null)
+        state.context.align = true;
+
+      var tok = stream.current();
+      if (tok == "(")
+        pushContext(stream, state, ")");
+      else if (tok == "[")
+        pushContext(stream, state, "]");
+      else if (state.context && state.context.type == tok)
+        popContext(state);
+      return style;
+    },
+
+    indent: function(state, textAfter) {
+      var cx = state.context;
+      if (!cx) return CodeMirror.Pass;
+      var closing = textAfter.charAt(0) == cx.type;
+      if (cx.align) return cx.col + (closing ? 0 : 1);
+      else return cx.indent + (closing ? 0 : config.indentUnit);
+    },
+
+    blockCommentStart: "/*",
+    blockCommentEnd: "*/",
+    lineComment: support.commentSlashSlash ? "//" : support.commentHash ? "#" : "--",
+    closeBrackets: "()[]{}''\"\"``"
+  };
+});
+
+  // `identifier`
+  function hookIdentifier(stream) {
+    // MySQL/MariaDB identifiers
+    // ref: http://dev.mysql.com/doc/refman/5.6/en/identifier-qualifiers.html
+    var ch;
+    while ((ch = stream.next()) != null) {
+      if (ch == "`" && !stream.eat("`")) return "variable-2";
+    }
+    stream.backUp(stream.current().length - 1);
+    return stream.eatWhile(/\w/) ? "variable-2" : null;
+  }
+
+  // "identifier"
+  function hookIdentifierDoublequote(stream) {
+    // Standard SQL /SQLite identifiers
+    // ref: http://web.archive.org/web/20160813185132/http://savage.net.au/SQL/sql-99.bnf.html#delimited%20identifier
+    // ref: http://sqlite.org/lang_keywords.html
+    var ch;
+    while ((ch = stream.next()) != null) {
+      if (ch == "\"" && !stream.eat("\"")) return "variable-2";
+    }
+    stream.backUp(stream.current().length - 1);
+    return stream.eatWhile(/\w/) ? "variable-2" : null;
+  }
+
+  // variable token
+  function hookVar(stream) {
+    // variables
+    // @@prefix.varName @varName
+    // varName can be quoted with ` or ' or "
+    // ref: http://dev.mysql.com/doc/refman/5.5/en/user-variables.html
+    if (stream.eat("@")) {
+      stream.match(/^session\./);
+      stream.match(/^local\./);
+      stream.match(/^global\./);
+    }
+
+    if (stream.eat("'")) {
+      stream.match(/^.*'/);
+      return "variable-2";
+    } else if (stream.eat('"')) {
+      stream.match(/^.*"/);
+      return "variable-2";
+    } else if (stream.eat("`")) {
+      stream.match(/^.*`/);
+      return "variable-2";
+    } else if (stream.match(/^[0-9a-zA-Z$\.\_]+/)) {
+      return "variable-2";
+    }
+    return null;
+  };
+
+  // short client keyword token
+  function hookClient(stream) {
+    // \N means NULL
+    // ref: http://dev.mysql.com/doc/refman/5.5/en/null-values.html
+    if (stream.eat("N")) {
+        return "atom";
+    }
+    // \g, etc
+    // ref: http://dev.mysql.com/doc/refman/5.5/en/mysql-commands.html
+    return stream.match(/^[a-zA-Z.#!?]/) ? "variable-2" : null;
+  }
+
+  // these keywords are used by all SQL dialects (however, a mode can still overwrite it)
+  var sqlKeywords = "alter and as asc between by count create delete desc distinct drop from group having in insert into is join like not on or order select set table union update values where limit ";
+
+  // turn a space-separated list into an array
+  function set(str) {
+    var obj = {}, words = str.split(" ");
+    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
+    return obj;
+  }
+
+  var defaultBuiltin = "bool boolean bit blob enum long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision real date datetime year unsigned signed decimal numeric"
+
+  // A generic SQL Mode. It's not a standard, it just try to support what is generally supported
+  CodeMirror.defineMIME("text/x-sql", {
+    name: "sql",
+    keywords: set(sqlKeywords + "begin"),
+    builtin: set(defaultBuiltin),
+    atoms: set("false true null unknown"),
+    dateSQL: set("date time timestamp"),
+    support: set("ODBCdotTable doubleQuote binaryNumber hexNumber")
+  });
+
+
+  CodeMirror.defineMIME("text/x-mysql", {
+    name: "sql",
+    client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"),
+    keywords: set(sqlKeywords + "accessible action add after algorithm all analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general get global grant grants group group_concat handler hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show signal slave slow smallint snapshot soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"),
+    builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"),
+    atoms: set("false true null unknown"),
+    operatorChars: /^[*+\-%<>!=&|^]/,
+    dateSQL: set("date time timestamp"),
+    support: set("ODBCdotTable decimallessFloat zerolessFloat binaryNumber hexNumber doubleQuote nCharCast charsetCast commentHash commentSpaceRequired"),
+    hooks: {
+      "@":   hookVar,
+      "`":   hookIdentifier,
+      "\\":  hookClient
+    }
+  });
+
+});
\ No newline at end of file
index ca2511b84e4d86ab634a014f552daef025f69099..2546b5f9e34dd89edaea700bdf1ff6ba37b8b28e 100644 (file)
@@ -33,7 +33,7 @@ var initPhotoSwipeFromDOM = function(gallerySelector) {
                 continue;
             }
 
-            linkEl = figureEl.children[0]; // <a> element
+            linkEl = figureEl.querySelector('a'); // <a> element
 
             size = linkEl.getAttribute('data-size').split('x');
 
@@ -45,10 +45,9 @@ var initPhotoSwipeFromDOM = function(gallerySelector) {
             };
 
 
-
             if(figureEl.children.length > 1) {
                 // <figcaption> content
-                item.title = figureEl.children[1].innerHTML; 
+                item.title = figureEl.querySelector('figcaption').innerHTML; 
             }
 
             if(linkEl.children.length > 0) {