diff --git a/.eslintignore b/.eslintignore index 6676467368..e877e0062b 100644 --- a/.eslintignore +++ b/.eslintignore @@ -13,3 +13,5 @@ vendor/ test/javascripts/test_helper.js test/javascripts/fixtures test/javascripts/helpers/assertions.js +node_modules/ +dist/ diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 15d8c36a8a..e848bdcf4c 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -23,12 +23,6 @@ acc5cbdf8ecb9293a0fa9474ee73baf499c02428 # Rename wizard from es6 -> js 1ac02422011f89716ab27250d39b0e0212e03892 -# Rename discourse-common es6 -> js -167503ca4824e37a2e93d74b3f50271556d0ba8e - -# Rename ember-addons es6 -> js -16ba50bce362c1eefe1881f86c67bec66f493abb - # Rename some root files 11938d58d4b1bea1ff43306450da7b24f05db0a @@ -40,3 +34,6 @@ b66b277dc44bcd2122dc21965dab209c30636214 # DEV: enforces double quotes ember-template-lint c4644c61d97c823b7dd940ffaf0967a104f4b58c + +# Migrate to app directory +7a2e8d3ead63c7d99e1069fc7823e933f931ba85 diff --git a/.gitignore b/.gitignore index 59ad3c0b6f..97d1a6b930 100644 --- a/.gitignore +++ b/.gitignore @@ -54,7 +54,7 @@ bootsnap-compile-cache/ !/plugins/discourse-narrative-bot !/plugins/discourse-presence !/plugins/discourse-local-dates -!/plugins/discourse-internet-explorer +!/plugins/discourse-unsupported-browser /plugins/*/auto_generated/ /spec/fixtures/plugins/my_plugin/auto_generated @@ -122,7 +122,7 @@ vendor/bundle/* *.swn # ignore nodejs files -/node_modules +node_modules /package-lock.json /vendor/data/GeoLite2-City.mmdb @@ -132,3 +132,9 @@ vendor/bundle/* # ignore auto-generated plugin js assets /app/assets/javascripts/plugins/* + +# ignore generated api documentation files +openapi/* + +# ember-cli generated +dist \ No newline at end of file diff --git a/.rubocop.yml b/.rubocop.yml index f389e688ca..0cb02e3e97 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -179,6 +179,8 @@ RSpec/DescribedClassModuleWrapping: RSpec/EmptyExampleGroup: Enabled: true + Exclude: + - 'spec/requests/api/*' RSpec/EmptyLineAfterExample: Enabled: false # TODO diff --git a/Gemfile b/Gemfile index c440694fff..742bf82d0b 100644 --- a/Gemfile +++ b/Gemfile @@ -118,7 +118,6 @@ gem 'rake' gem 'thor', require: false gem 'diffy', require: false gem 'rinku' -gem 'sanitize' gem 'sidekiq' gem 'mini_scheduler' @@ -168,17 +167,17 @@ group :test, :development do # we would like to upgrade it if possible gem 'rb-inotify', '~> 0.9', require: RUBY_PLATFORM =~ /linux/i ? 'rb-inotify' : false - # TODO once 4.0.0 is released upgrade to it, at time of writing 3.9.0 is latest - gem 'rspec-rails', '4.0.0.beta2', require: false + gem 'rspec-rails' gem 'shoulda-matchers', require: false gem 'rspec-html-matchers' - gem 'pry-nav' gem 'byebug', require: ENV['RM_INFO'].nil?, platform: :mri gem 'rubocop', require: false gem "rubocop-discourse", require: false gem "rubocop-rspec", require: false gem 'parallel_tests' + + gem 'rswag-specs' end group :development do @@ -255,10 +254,3 @@ end gem 'webpush', require: false gem 'colored2', require: false gem 'maxminddb' - -# These are not direct dependencies, but we need to restrict -# versions for compatibility with https://github.com/discourse/discourse-zendesk-plugin -# These restrictions can be removed once the zendesk_api gem is updated -# for newer versions of hashie and faraday -gem 'hashie', '< 4.0.0', require: false # https://github.com/zendesk/zendesk_api_client_rb/pull/422 -gem 'faraday', '< 1.0.0', require: false # https://github.com/zendesk/zendesk_api_client_rb/pull/421 diff --git a/Gemfile.lock b/Gemfile.lock index ab18090bea..d16ced6284 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -61,12 +61,12 @@ GEM aws-sdk-sns (1.22.0) aws-sdk-core (~> 3, >= 3.71.0) aws-sigv4 (~> 1.1) - aws-sigv4 (1.1.2) + aws-sigv4 (1.1.3) aws-eventstream (~> 1.0, >= 1.0.2) barber (0.12.2) ember-source (>= 1.0, < 3.1) execjs (>= 1.2, < 3) - better_errors (2.6.0) + better_errors (2.7.0) coderay (>= 1.0.0) erubi (>= 1.0.0) rack (>= 0.9.0) @@ -78,7 +78,7 @@ GEM bullet (6.1.0) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) - byebug (11.1.2) + byebug (11.1.3) cbor (0.5.9.6) certified (1.0.0) chunky_png (1.3.11) @@ -126,7 +126,7 @@ GEM exifr (1.3.6) fabrication (2.21.1) fakeweb (1.3.0) - faraday (0.17.3) + faraday (1.0.1) multipart-post (>= 1.2, < 3) fast_blank (1.0.0) fast_xor (1.1.3) @@ -142,7 +142,7 @@ GEM activesupport (>= 4.2.0) guess_html_encoding (0.0.11) hashdiff (1.0.1) - hashie (3.6.0) + hashie (4.1.0) highline (1.7.10) hkdf (0.3.0) htmlentities (4.3.4) @@ -158,6 +158,8 @@ GEM railties (>= 4.2.0) thor (>= 0.14, < 2.0) json (2.3.0) + json-schema (2.8.1) + addressable (>= 2.4) jwt (2.2.1) kgio (2.11.3) libv8 (7.3.492.27.1) @@ -182,9 +184,9 @@ GEM mini_mime (>= 0.1.1) maxminddb (0.1.22) memory_profiler (0.9.14) - message_bus (2.2.4) + message_bus (3.1.0) rack (>= 1.1.3) - method_source (0.9.2) + method_source (1.0.0) mini_mime (1.0.2) mini_portile2 (2.4.0) mini_racer (0.2.10) @@ -251,15 +253,13 @@ GEM parallel (1.19.1) parallel_tests (2.32.0) parallel - parser (2.7.1.1) + parser (2.7.1.2) ast (~> 2.4.0) pg (1.2.3) progress (3.5.2) - pry (0.12.2) - coderay (~> 1.1.0) - method_source (~> 0.9.0) - pry-nav (0.3.0) - pry (>= 0.9.10, < 0.13.0) + pry (0.13.1) + coderay (~> 1.1) + method_source (~> 1.0) pry-rails (0.3.9) pry (>= 0.10.4) public_suffix (4.0.4) @@ -292,7 +292,7 @@ GEM rake (13.0.1) rake-compiler (1.1.0) rake - rb-fsevent (0.10.3) + rb-fsevent (0.10.4) rb-inotify (0.10.1) ffi (~> 1.0) rbtrace (0.4.12) @@ -300,7 +300,7 @@ GEM msgpack (>= 0.4.3) optimist (>= 3.0.0) rchardet (1.8.0) - redis (4.1.3) + redis (4.1.4) redis-namespace (1.7.0) redis (>= 3.0.4) request_store (1.5.0) @@ -312,13 +312,13 @@ GEM rqrcode (1.1.2) chunky_png (~> 1.0) rqrcode_core (~> 0.1) - rqrcode_core (0.1.1) + rqrcode_core (0.1.2) rspec (3.9.0) rspec-core (~> 3.9.0) rspec-expectations (~> 3.9.0) rspec-mocks (~> 3.9.0) - rspec-core (3.9.1) - rspec-support (~> 3.9.1) + rspec-core (3.9.2) + rspec-support (~> 3.9.3) rspec-expectations (3.9.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.9.0) @@ -328,15 +328,19 @@ GEM rspec-mocks (3.9.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.9.0) - rspec-rails (4.0.0.beta2) + rspec-rails (4.0.0) actionpack (>= 4.2) activesupport (>= 4.2) railties (>= 4.2) - rspec-core (~> 3.8) - rspec-expectations (~> 3.8) - rspec-mocks (~> 3.8) - rspec-support (~> 3.8) - rspec-support (3.9.2) + rspec-core (~> 3.9) + rspec-expectations (~> 3.9) + rspec-mocks (~> 3.9) + rspec-support (~> 3.9) + rspec-support (3.9.3) + rswag-specs (2.3.1) + activesupport (>= 3.1, < 7.0) + json-schema (~> 2.2) + railties (>= 3.1, < 7.0) rtlit (0.0.5) rubocop (0.82.0) jaro_winkler (~> 1.5.1) @@ -346,9 +350,10 @@ GEM rexml ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 2.0) - rubocop-discourse (2.0.1) + rubocop-discourse (2.1.2) rubocop (>= 0.69.0) - rubocop-rspec (1.38.1) + rubocop-rspec (>= 1.39.0) + rubocop-rspec (1.39.0) rubocop (>= 0.68.1) ruby-prof (1.3.2) ruby-progressbar (1.10.1) @@ -405,7 +410,7 @@ GEM unf_ext unf_ext (0.0.7.7) unicode-display_width (1.7.0) - unicorn (5.5.4) + unicorn (5.5.5) kgio (~> 2.6) raindrops (~> 0.7) uniform_notifier (1.13.0) @@ -457,14 +462,12 @@ DEPENDENCIES execjs fabrication fakeweb - faraday (< 1.0.0) fast_blank fast_xor fast_xs fastimage flamegraph gc_tracer - hashie (< 4.0.0) highline (~> 1.7.0) htmlentities http_accept_language @@ -502,7 +505,6 @@ DEPENDENCIES onebox parallel_tests pg - pry-nav pry-rails puma r2 @@ -523,7 +525,8 @@ DEPENDENCIES rqrcode rspec rspec-html-matchers - rspec-rails (= 4.0.0.beta2) + rspec-rails + rswag-specs rtlit rubocop rubocop-discourse @@ -531,7 +534,6 @@ DEPENDENCIES ruby-prof ruby-readability rubyzip - sanitize sassc (= 2.0.1) sassc-rails seed-fu diff --git a/README.md b/README.md index ddf32ba126..fce15c577d 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ Plus *lots* of Ruby Gems, a complete list of which is at [/master/Gemfile](https ## Contributing -[![Build Status](https://api.travis-ci.org/discourse/discourse.svg?branch=master)](https://travis-ci.org/discourse/discourse) +[![Build Status](https://github.com/discourse/discourse/workflows/CI/badge.svg)](https://github.com/discourse/discourse/actions) Discourse is **100% free** and **open source**. We encourage and support an active, healthy community that accepts contributions from the public – including you! diff --git a/app/assets/javascripts/admin/components/admin-report.js b/app/assets/javascripts/admin/components/admin-report.js index 178bef98f2..757a90a7db 100644 --- a/app/assets/javascripts/admin/components/admin-report.js +++ b/app/assets/javascripts/admin/components/admin-report.js @@ -1,7 +1,7 @@ import discourseComputed from "discourse-common/utils/decorators"; import { makeArray } from "discourse-common/lib/helpers"; -import { alias, or, and, reads, equal, notEmpty } from "@ember/object/computed"; -import EmberObject from "@ember/object"; +import { alias, or, and, equal, notEmpty, not } from "@ember/object/computed"; +import EmberObject, { computed, action } from "@ember/object"; import { next } from "@ember/runloop"; import Component from "@ember/component"; import ReportLoader from "discourse/lib/reports-loader"; @@ -9,6 +9,7 @@ import { exportEntity } from "discourse/lib/export-csv"; import { outputExportResult } from "discourse/lib/export-result"; import Report, { SCHEMA_VERSION } from "admin/models/report"; import ENV from "discourse-common/config/environment"; +import { isPresent } from "@ember/utils"; const TABLE_OPTIONS = { perPage: 8, @@ -40,7 +41,12 @@ function collapseWeekly(data, average) { } export default Component.extend({ - classNameBindings: ["isEnabled", "isLoading", "dasherizedDataSourceName"], + classNameBindings: [ + "isVisible", + "isEnabled", + "isLoading", + "dasherizedDataSourceName" + ], classNames: ["admin-report"], isEnabled: true, disabledLabel: I18n.t("admin.dashboard.disabled"), @@ -62,6 +68,7 @@ export default Component.extend({ showDatesOptions: alias("model.dates_filtering"), showRefresh: or("showDatesOptions", "model.available_filters.length"), shouldDisplayTrend: and("showTrend", "model.prev_period"), + isVisible: not("isHidden"), init() { this._super(...arguments); @@ -69,8 +76,28 @@ export default Component.extend({ this._reports = []; }, - startDate: reads("filters.startDate"), - endDate: reads("filters.endDate"), + isHidden: computed("siteSettings.dashboard_hidden_reports", function() { + return (this.siteSettings.dashboard_hidden_reports || "") + .split("|") + .filter(Boolean) + .includes(this.dataSourceName); + }), + + startDate: computed("filters.startDate", function() { + if (this.filters && isPresent(this.filters.startDate)) { + return moment(this.filters.startDate, "YYYY-MM-DD"); + } else { + return moment(); + } + }), + + endDate: computed("filters.endDate", function() { + if (this.filters && isPresent(this.filters.endDate)) { + return moment(this.filters.endDate, "YYYY-MM-DD"); + } else { + return moment(); + } + }), didReceiveAttrs() { this._super(...arguments); @@ -126,39 +153,18 @@ export default Component.extend({ return `admin-report-${currentMode.replace(/_/g, "-")}`; }, - @discourseComputed("startDate") - normalizedStartDate(startDate) { - return startDate && typeof startDate.isValid === "function" - ? moment - .utc(startDate.toISOString()) - .locale("en") - .format("YYYYMMDD") - : moment(startDate) - .locale("en") - .format("YYYYMMDD"); - }, - - @discourseComputed("endDate") - normalizedEndDate(endDate) { - return endDate && typeof endDate.isValid === "function" - ? moment - .utc(endDate.toISOString()) - .locale("en") - .format("YYYYMMDD") - : moment(endDate) - .locale("en") - .format("YYYYMMDD"); - }, - @discourseComputed( "dataSourceName", - "normalizedStartDate", - "normalizedEndDate", + "startDate", + "endDate", "filters.customFilters" ) reportKey(dataSourceName, startDate, endDate, customFilters) { if (!dataSourceName || !startDate || !endDate) return null; + startDate = startDate.toISOString(true).split("T")[0]; + endDate = endDate.toISOString(true).split("T")[0]; + let reportKey = "reports:"; reportKey += [ dataSourceName, @@ -179,74 +185,61 @@ export default Component.extend({ return reportKey; }, - actions: { - onChangeEndDate(date) { - const startDate = moment(this.startDate); - const newEndDate = moment(date).endOf("day"); + @action + onChangeDateRange(range) { + this.send("refreshReport", { + startDate: range.from, + endDate: range.to + }); + }, - if (newEndDate.isSameOrAfter(startDate)) { - this.set("endDate", newEndDate.format("YYYY-MM-DD")); - } else { - this.set("endDate", startDate.endOf("day").format("YYYY-MM-DD")); - } + @action + applyFilter(id, value) { + let customFilters = this.get("filters.customFilters") || {}; - this.send("refreshReport"); - }, - - onChangeStartDate(date) { - const endDate = moment(this.endDate); - const newStartDate = moment(date).startOf("day"); - - if (newStartDate.isSameOrBefore(endDate)) { - this.set("startDate", newStartDate.format("YYYY-MM-DD")); - } else { - this.set("startDate", endDate.startOf("day").format("YYYY-MM-DD")); - } - - this.send("refreshReport"); - }, - - applyFilter(id, value) { - let customFilters = this.get("filters.customFilters") || {}; - - if (typeof value === "undefined") { - delete customFilters[id]; - } else { - customFilters[id] = value; - } - - this.attrs.onRefresh({ - type: this.get("model.type"), - startDate: this.startDate, - endDate: this.endDate, - filters: customFilters - }); - }, - - refreshReport() { - this.attrs.onRefresh({ - type: this.get("model.type"), - startDate: this.startDate, - endDate: this.endDate, - filters: this.get("filters.customFilters") - }); - }, - - exportCsv() { - const customFilters = this.get("filters.customFilters") || {}; - - exportEntity("report", { - name: this.get("model.type"), - start_date: this.startDate, - end_date: this.endDate, - category_id: customFilters.category, - group_id: customFilters.group - }).then(outputExportResult); - }, - - changeMode(mode) { - this.set("currentMode", mode); + if (typeof value === "undefined") { + delete customFilters[id]; + } else { + customFilters[id] = value; } + + this.send("refreshReport", { + filters: customFilters + }); + }, + + @action + refreshReport(options = {}) { + this.attrs.onRefresh({ + type: this.get("model.type"), + startDate: + typeof options.startDate === "undefined" + ? this.startDate + : options.startDate, + endDate: + typeof options.endDate === "undefined" ? this.endDate : options.endDate, + filters: + typeof options.filters === "undefined" + ? this.get("filters.customFilters") + : options.filters + }); + }, + + @action + exportCsv() { + const customFilters = this.get("filters.customFilters") || {}; + exportEntity("report", { + name: this.get("model.type"), + start_date: this.startDate.toISOString(true).split("T")[0], + end_date: this.endDate.toISOString(true).split("T")[0], + category_id: customFilters.category, + group_id: customFilters.group + }).then(outputExportResult); + }, + + @action + changeMode(mode) { + this.set("currentMode", mode); }, _computeReport() { @@ -276,10 +269,8 @@ export default Component.extend({ if (!this.startDate || !this.endDate) { report = sort(filteredReports)[0]; } else { - const reportKey = this.reportKey; - report = sort( - filteredReports.filter(r => r.report_key.includes(reportKey)) + filteredReports.filter(r => r.report_key.includes(this.reportKey)) )[0]; if (!report) return; @@ -339,15 +330,15 @@ export default Component.extend({ let payload = { data: { cache: true, facets } }; if (this.startDate) { - payload.data.start_date = moment - .utc(this.startDate, "YYYY-MM-DD") - .toISOString(); + payload.data.start_date = moment(this.startDate) + .toISOString(true) + .split("T")[0]; } if (this.endDate) { - payload.data.end_date = moment - .utc(this.endDate, "YYYY-MM-DD") - .toISOString(); + payload.data.end_date = moment(this.endDate) + .toISOString(true) + .split("T")[0]; } if (this.get("reportOptions.table.limit")) { diff --git a/app/assets/javascripts/admin/components/site-settings/tag-list.js b/app/assets/javascripts/admin/components/site-settings/tag-list.js index c8a8e0a06f..011c734b7d 100644 --- a/app/assets/javascripts/admin/components/site-settings/tag-list.js +++ b/app/assets/javascripts/admin/components/site-settings/tag-list.js @@ -1,15 +1,17 @@ import discourseComputed from "discourse-common/utils/decorators"; import Component from "@ember/component"; +import { action } from "@ember/object"; export default Component.extend({ @discourseComputed("value") selectedTags: { get(value) { - return value.split("|"); - }, - set(value) { - this.set("value", value.join("|")); - return value; + return value.split("|").filter(Boolean); } + }, + + @action + changeSelectedTags(tags) { + this.set("value", tags.join("|")); } }); diff --git a/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js b/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js index 006f1728da..5440c4260a 100644 --- a/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js +++ b/app/assets/javascripts/admin/controllers/admin-customize-themes-show.js @@ -31,6 +31,7 @@ export default Controller.extend({ availableComponentsNames: mapBy("availableChildThemes", "name"), availableActiveComponentsNames: mapBy("availableActiveChildThemes", "name"), childThemesNames: mapBy("model.childThemes", "name"), + extraFiles: filterBy("model.theme_fields", "target", "extra_js"), @discourseComputed("model.editedFields") editedFieldsFormatted() { diff --git a/app/assets/javascripts/admin/controllers/admin-dashboard-general.js b/app/assets/javascripts/admin/controllers/admin-dashboard-general.js index b77e3e0288..5f2ea86819 100644 --- a/app/assets/javascripts/admin/controllers/admin-dashboard-general.js +++ b/app/assets/javascripts/admin/controllers/admin-dashboard-general.js @@ -23,9 +23,44 @@ export default Controller.extend(PeriodComputationMixin, { @discourseComputed("siteSettings.dashboard_general_tab_activity_metrics") activityMetrics(metrics) { - return (metrics || "").split("|").filter(m => m); + return (metrics || "").split("|").filter(Boolean); }, + hiddenReports: computed("siteSettings.dashboard_hidden_reports", function() { + return (this.siteSettings.dashboard_hidden_reports || "") + .split("|") + .filter(Boolean); + }), + + isActivityMetricsVisible: computed( + "activityMetrics", + "hiddenReports", + function() { + return ( + this.activityMetrics.length && + this.activityMetrics.some(x => !this.hiddenReports.includes(x)) + ); + } + ), + + isSearchReportsVisible: computed("hiddenReports", function() { + return ["top_referred_topics", "trending_search"].some( + x => !this.hiddenReports.includes(x) + ); + }), + + isCommunityHealthVisible: computed("hiddenReports", function() { + return [ + "consolidated_page_views", + "signups", + "topics", + "posts", + "dau_by_mau", + "daily_engaged_users", + "new_contributors" + ].some(x => !this.hiddenReports.includes(x)); + }), + @discourseComputed activityMetricsFilters() { return { diff --git a/app/assets/javascripts/admin/controllers/admin-dashboard-moderation.js b/app/assets/javascripts/admin/controllers/admin-dashboard-moderation.js index 8925825fba..95f820b598 100644 --- a/app/assets/javascripts/admin/controllers/admin-dashboard-moderation.js +++ b/app/assets/javascripts/admin/controllers/admin-dashboard-moderation.js @@ -1,6 +1,7 @@ import discourseComputed from "discourse-common/utils/decorators"; import Controller from "@ember/controller"; import PeriodComputationMixin from "admin/mixins/period-computation"; +import { computed } from "@ember/object"; export default Controller.extend(PeriodComputationMixin, { @discourseComputed @@ -13,6 +14,16 @@ export default Controller.extend(PeriodComputationMixin, { }; }, + isModeratorsActivityVisible: computed( + "siteSettings.dashboard_hidden_reports", + function() { + return !(this.siteSettings.dashboard_hidden_reports || "") + .split("|") + .filter(Boolean) + .includes("moderators_activity"); + } + ), + @discourseComputed userFlaggingRatioOptions() { return { diff --git a/app/assets/javascripts/admin/controllers/admin-dashboard-reports.js b/app/assets/javascripts/admin/controllers/admin-dashboard-reports.js index d6e15496f7..c096c3e763 100644 --- a/app/assets/javascripts/admin/controllers/admin-dashboard-reports.js +++ b/app/assets/javascripts/admin/controllers/admin-dashboard-reports.js @@ -8,17 +8,27 @@ const { get } = Ember; export default Controller.extend({ filter: null, - @discourseComputed("model.[]", "filter") + @discourseComputed( + "model.[]", + "filter", + "siteSettings.dashboard_hidden_reports" + ) filterReports(reports, filter) { if (filter) { filter = filter.toLowerCase(); - return reports.filter(report => { + reports = reports.filter(report => { return ( (get(report, "title") || "").toLowerCase().indexOf(filter) > -1 || (get(report, "description") || "").toLowerCase().indexOf(filter) > -1 ); }); } + + const hiddenReports = (this.siteSettings.dashboard_hidden_reports || "") + .split("|") + .filter(Boolean); + reports = reports.filter(report => !hiddenReports.includes(report.type)); + return reports; }, diff --git a/app/assets/javascripts/admin/controllers/admin-dashboard.js b/app/assets/javascripts/admin/controllers/admin-dashboard.js index bd8561abc1..5946a1736d 100644 --- a/app/assets/javascripts/admin/controllers/admin-dashboard.js +++ b/app/assets/javascripts/admin/controllers/admin-dashboard.js @@ -1,7 +1,7 @@ import discourseComputed from "discourse-common/utils/decorators"; -import { inject } from "@ember/controller"; -import Controller from "@ember/controller"; +import Controller, { inject } from "@ember/controller"; import { setting } from "discourse/lib/computed"; +import { computed } from "@ember/object"; import AdminDashboard from "admin/models/admin-dashboard"; import VersionCheck from "admin/models/version-check"; @@ -18,6 +18,24 @@ export default Controller.extend({ return this.currentUser.get("admin") && (problemsLength || 0) > 0; }, + visibleTabs: computed("siteSettings.dashboard_visible_tabs", function() { + return (this.siteSettings.dashboard_visible_tabs || "") + .split("|") + .filter(Boolean); + }), + + isModerationTabVisible: computed("visibleTabs", function() { + return this.visibleTabs.includes("moderation"); + }), + + isSecurityTabVisible: computed("visibleTabs", function() { + return this.visibleTabs.includes("security"); + }), + + isReportsTabVisible: computed("visibleTabs", function() { + return this.visibleTabs.includes("reports"); + }), + fetchProblems() { if (this.isLoadingProblems) return; diff --git a/app/assets/javascripts/admin/controllers/modals/admin-badge-preview.js b/app/assets/javascripts/admin/controllers/modals/admin-badge-preview.js index 84325f90d1..c5baa8eb9a 100644 --- a/app/assets/javascripts/admin/controllers/modals/admin-badge-preview.js +++ b/app/assets/javascripts/admin/controllers/modals/admin-badge-preview.js @@ -42,7 +42,7 @@ export default Controller.extend({ if (grant.post_id) { i18nKey += "_post"; i18nParams.link = ` - ${Handlebars.Utils.escapeExpression(grant.title)} + ${escapeExpression(grant.title)} `; } diff --git a/app/assets/javascripts/admin/controllers/modals/admin-merge-users-confirmation.js b/app/assets/javascripts/admin/controllers/modals/admin-merge-users-confirmation.js index 2195c29631..91dbe7d072 100644 --- a/app/assets/javascripts/admin/controllers/modals/admin-merge-users-confirmation.js +++ b/app/assets/javascripts/admin/controllers/modals/admin-merge-users-confirmation.js @@ -2,6 +2,7 @@ import Controller, { inject as controller } from "@ember/controller"; import ModalFunctionality from "discourse/mixins/modal-functionality"; import discourseComputed from "discourse-common/utils/decorators"; import { alias } from "@ember/object/computed"; +import { action } from "@ember/object"; export default Controller.extend(ModalFunctionality, { adminUserIndex: controller(), @@ -14,7 +15,10 @@ export default Controller.extend(ModalFunctionality, { @discourseComputed("username", "targetUsername") text(username, targetUsername) { - return `transfer @${username} to @${targetUsername}`; + return I18n.t(`admin.user.merge.confirmation.text`, { + username, + targetUsername + }); }, @discourseComputed("value", "text") @@ -22,14 +26,14 @@ export default Controller.extend(ModalFunctionality, { return !value || text !== value; }, - actions: { - merge() { - this.adminUserIndex.send("merge", this.targetUsername); - this.send("closeModal"); - }, + @action + confirm() { + this.adminUserIndex.send("merge", this.targetUsername); + this.send("closeModal"); + }, - cancel() { - this.send("closeModal"); - } + @action + close() { + this.send("closeModal"); } }); diff --git a/app/assets/javascripts/admin/controllers/modals/admin-merge-users-prompt.js b/app/assets/javascripts/admin/controllers/modals/admin-merge-users-prompt.js index 535870cd6f..28fd6058e4 100644 --- a/app/assets/javascripts/admin/controllers/modals/admin-merge-users-prompt.js +++ b/app/assets/javascripts/admin/controllers/modals/admin-merge-users-prompt.js @@ -2,6 +2,7 @@ import Controller, { inject as controller } from "@ember/controller"; import ModalFunctionality from "discourse/mixins/modal-functionality"; import discourseComputed from "discourse-common/utils/decorators"; import { alias } from "@ember/object/computed"; +import { action } from "@ember/object"; export default Controller.extend(ModalFunctionality, { adminUserIndex: controller(), @@ -16,14 +17,14 @@ export default Controller.extend(ModalFunctionality, { return !targetUsername || username === targetUsername; }, - actions: { - merge() { - this.send("closeModal"); - this.adminUserIndex.send("showMergeConfirmation", this.targetUsername); - }, + @action + showConfirmation() { + this.send("closeModal"); + this.adminUserIndex.send("showMergeConfirmation", this.targetUsername); + }, - cancel() { - this.send("closeModal"); - } + @action + close() { + this.send("closeModal"); } }); diff --git a/app/assets/javascripts/admin/helpers/check-icon.js b/app/assets/javascripts/admin/helpers/check-icon.js index 88cddc3d4d..4641a15fa2 100644 --- a/app/assets/javascripts/admin/helpers/check-icon.js +++ b/app/assets/javascripts/admin/helpers/check-icon.js @@ -1,7 +1,8 @@ import { registerUnbound } from "discourse-common/lib/helpers"; import { renderIcon } from "discourse-common/lib/icon-library"; +import { htmlSafe } from "@ember/template"; registerUnbound("check-icon", function(value) { let icon = value ? "check" : "times"; - return new Handlebars.SafeString(renderIcon("string", icon)); + return htmlSafe(renderIcon("string", icon)); }); diff --git a/app/assets/javascripts/admin/mixins/setting-component.js b/app/assets/javascripts/admin/mixins/setting-component.js index 200ec00c1f..e7afc119f2 100644 --- a/app/assets/javascripts/admin/mixins/setting-component.js +++ b/app/assets/javascripts/admin/mixins/setting-component.js @@ -7,6 +7,7 @@ import Mixin from "@ember/object/mixin"; import showModal from "discourse/lib/show-modal"; import { Promise } from "rsvp"; import { ajax } from "discourse/lib/ajax"; +import { htmlSafe } from "@ember/template"; const CUSTOM_TYPES = [ "bool", @@ -63,7 +64,7 @@ export default Mixin.create({ } let preview = setting.get("preview"); if (preview) { - return new Handlebars.SafeString( + return htmlSafe( "
" + preview.replace(/\{\{value\}\}/g, value) + "
" diff --git a/app/assets/javascripts/admin/models/admin-user.js b/app/assets/javascripts/admin/models/admin-user.js index 454daf4b19..1ddb7a52ff 100644 --- a/app/assets/javascripts/admin/models/admin-user.js +++ b/app/assets/javascripts/admin/models/admin-user.js @@ -5,7 +5,7 @@ import { ajax } from "discourse/lib/ajax"; import { propertyNotEqual } from "discourse/lib/computed"; import { popupAjaxError } from "discourse/lib/ajax-error"; import Group from "discourse/models/group"; -import { userPath } from "discourse/lib/url"; +import DiscourseURL, { userPath } from "discourse/lib/url"; import { Promise } from "rsvp"; import User from "discourse/models/user"; @@ -514,16 +514,16 @@ const AdminUser = User.extend({ formData["target_username"] = opts.targetUsername; } - return ajax(`/admin/users/${user.get("id")}/merge.json`, { + return ajax(`/admin/users/${user.id}/merge.json`, { type: "POST", data: formData }) - .then(function(data) { + .then(data => { if (data.merged) { if (/^\/admin\/users\/list\//.test(location)) { - document.location = location; + DiscourseURL.redirectTo(location); } else { - document.location = Discourse.getURL( + DiscourseURL.redirectTo( `/admin/users/${data.user.id}/${data.user.username}` ); } @@ -534,8 +534,8 @@ const AdminUser = User.extend({ } } }) - .catch(function() { - AdminUser.find(user.get("id")).then(u => user.setProperties(u)); + .catch(() => { + AdminUser.find(user.id).then(u => user.setProperties(u)); bootbox.alert(I18n.t("admin.user.merge_failed")); }); }, diff --git a/app/assets/javascripts/admin/routes/admin-reports-show.js b/app/assets/javascripts/admin/routes/admin-reports-show.js index 1fa8bc739d..3a8a5430a9 100644 --- a/app/assets/javascripts/admin/routes/admin-reports-show.js +++ b/app/assets/javascripts/admin/routes/admin-reports-show.js @@ -13,8 +13,7 @@ export default DiscourseRoute.extend({ params.startDate = params.start_date || - moment - .utc() + moment() .subtract(1, "day") .subtract(1, "month") .startOf("day") @@ -23,8 +22,7 @@ export default DiscourseRoute.extend({ params.endDate = params.end_date || - moment - .utc() + moment() .endOf("day") .format("YYYY-MM-DD"); delete params.end_date; @@ -56,9 +54,13 @@ export default DiscourseRoute.extend({ onParamsChange(params) { const queryParams = { type: params.type, - start_date: params.startDate, + start_date: params.startDate + ? params.startDate.toISOString(true).split("T")[0] + : null, filters: params.filters, end_date: params.endDate + ? params.endDate.toISOString(true).split("T")[0] + : null }; this.transitionTo("adminReports.show", { queryParams }); diff --git a/app/assets/javascripts/admin/templates/components/admin-report.hbs b/app/assets/javascripts/admin/templates/components/admin-report.hbs index ab0c1a6398..be075dbd2d 100644 --- a/app/assets/javascripts/admin/templates/components/admin-report.hbs +++ b/app/assets/javascripts/admin/templates/components/admin-report.hbs @@ -1,205 +1,197 @@ -{{#if isEnabled}} - {{#conditional-loading-section isLoading=isLoading}} - {{#if showHeader}} -
- {{#if showTitle}} - + {{/if}} + + {{#if shouldDisplayTrend}} +
+ + {{#if model.average}} + {{number model.currentAverage}}{{#if model.percent}}%{{/if}} {{else}} - {{i18n "admin.dashboard.reports.no_data"}} + {{number model.currentTotal noTitle="true"}}{{#if model.percent}}%{{/if}} {{/if}} -
- {{/if}} - {{/if}} - {{/if}} -
- {{#if showFilteringUI}} -
- {{#if showModes}} -
- {{#each displayedModes as |displayedMode|}} - {{d-button - action=(action "changeMode") - actionParam=displayedMode.mode - class=displayedMode.cssClass - icon=displayedMode.icon}} - {{/each}} -
- {{/if}} - - {{#if showDatesOptions}} -
- - {{i18n "admin.dashboard.reports.start_date"}} + {{#if model.trendIcon}} + {{d-icon model.trendIcon class="icon"}} + {{/if}} - -
- {{date-input - date=startDate - onChange=(action "onChangeStartDate") - }} -
-
- -
- - {{i18n "admin.dashboard.reports.end_date"}} - - -
- {{date-input - date=endDate - onChange=(action "onChangeEndDate") - }} -
-
- {{/if}} - - {{#each model.available_filters as |filter|}} -
- - {{i18n (concat "admin.dashboard.reports.filters." filter.id ".label")}} - - -
- {{component - (concat "report-filters/" filter.type) - model=model - filter=filter - applyFilter=(action "applyFilter")}} -
-
- {{/each}} - -
-
- {{d-button - class="btn-default export-csv-btn" - action=(action "exportCsv") - label="admin.export_csv.button_text" - icon="download"}} -
-
- - {{#if showRefresh}} -
-
- {{d-button - class="refresh-report-btn btn-primary" - action=(action "refreshReport") - label="admin.dashboard.reports.refresh_report" - icon="sync"}} -
{{/if}}
{{/if}} + +
+
+ {{#if showError}} + {{#if showTimeoutError}} +
+ {{d-icon "exclamation-triangle"}} + {{i18n "admin.dashboard.timeout_error"}} +
+ {{/if}} + + {{#if showExceptionError}} +
+ {{d-icon "exclamation-triangle"}} + {{i18n "admin.dashboard.exception_error"}} +
+ {{/if}} + + {{#if showNotFoundError}} +
+ {{d-icon "exclamation-triangle"}} + {{i18n "admin.dashboard.not_found_error"}} +
+ {{/if}} + {{else}} + {{#if hasData}} + {{#if currentMode}} + {{component modeComponent model=model options=options}} + + {{#if model.relatedReport}} + {{admin-report showFilteringUI=false dataSourceName=model.relatedReport.type}} + {{/if}} + {{/if}} + {{else}} + {{#if rateLimitationString}} +
+ {{d-icon "thermometer-three-quarters"}} + {{rateLimitationString}} +
+ {{else}} +
+ {{d-icon "chart-pie"}} + {{#if model.reportUrl}} + + + {{#if model.title}} + {{model.title}} — + {{/if}} + {{i18n "admin.dashboard.reports.no_data"}} + + + {{else}} + {{i18n "admin.dashboard.reports.no_data"}} + {{/if}} +
+ {{/if}} + {{/if}} + {{/if}} +
+ + {{#if showFilteringUI}} +
+ {{#if showModes}} +
+ {{#each displayedModes as |displayedMode|}} + {{d-button + action=(action "changeMode") + actionParam=displayedMode.mode + class=displayedMode.cssClass + icon=displayedMode.icon}} + {{/each}} +
+ {{/if}} + + {{#if showDatesOptions}} +
+ + {{i18n "admin.dashboard.reports.dates"}} + + +
+ {{date-time-input-range + from=startDate + to=endDate + onChange=(action "onChangeDateRange") + showFromTime=false + showToTime=false + }} +
+
+ {{/if}} + + {{#each model.available_filters as |filter|}} +
+ + {{i18n (concat "admin.dashboard.reports.filters." filter.id ".label")}} + + +
+ {{component + (concat "report-filters/" filter.type) + model=model + filter=filter + applyFilter=(action "applyFilter")}} +
+
+ {{/each}} + +
+
+ {{d-button + class="btn-default export-csv-btn" + action=(action "exportCsv") + label="admin.export_csv.button_text" + icon="download"}} +
+
+ + {{#if showRefresh}} +
+
+ {{d-button + class="refresh-report-btn btn-primary" + action=(action "refreshReport") + label="admin.dashboard.reports.refresh_report" + icon="sync"}} +
+
+ {{/if}} +
+ {{/if}} +
+ {{/conditional-loading-section}} + {{else}} +
+ {{html-safe disabledLabel}}
- {{/conditional-loading-section}} -{{else}} -
- {{html-safe disabledLabel}} -
-{{/if}} + {{/if}} +{{/unless}} diff --git a/app/assets/javascripts/admin/templates/components/site-settings/tag-list.hbs b/app/assets/javascripts/admin/templates/components/site-settings/tag-list.hbs index f7519e770d..7efd7421ce 100644 --- a/app/assets/javascripts/admin/templates/components/site-settings/tag-list.hbs +++ b/app/assets/javascripts/admin/templates/components/site-settings/tag-list.hbs @@ -1,3 +1,9 @@ -{{tag-chooser tags=selectedTags allowCreate=false}} +{{tag-chooser + tags=selectedTags + onChange=(action "changeSelectedTags") + options=(hash + allowAny=false + ) +}}
{{html-safe setting.description}}
{{setting-validation-message message=validationMessage}} diff --git a/app/assets/javascripts/admin/templates/customize-themes-show.hbs b/app/assets/javascripts/admin/templates/customize-themes-show.hbs index 9f46d47d69..0e452a960c 100644 --- a/app/assets/javascripts/admin/templates/customize-themes-show.hbs +++ b/app/assets/javascripts/admin/templates/customize-themes-show.hbs @@ -126,6 +126,15 @@ {{/if}} + {{else}} +
+ {{i18n "admin.customize.theme.creator"}} + + {{#user-link user=model.user}} + {{format-username model.user.username}} + {{/user-link}} + +
{{/if}} {{#unless model.component}} @@ -219,6 +228,26 @@ {{#d-button action=(action "addUploadModal") class="btn-default" icon="plus"}}{{i18n "admin.customize.theme.add"}}{{/d-button}} + {{#if extraFiles.length}} +
+
{{i18n "admin.customize.theme.extra_files"}}
+
+ + {{#if model.remote_theme}} + {{i18n "admin.customize.theme.extra_files_remote"}} + {{else}} + {{i18n "admin.customize.theme.extra_files_upload"}} + {{/if}} + + +
+
+ {{/if}} + {{#if hasSettings}}
{{i18n "admin.customize.theme.theme_settings"}}
diff --git a/app/assets/javascripts/admin/templates/dashboard.hbs b/app/assets/javascripts/admin/templates/dashboard.hbs index cbbd34b4b2..0e4f4beec2 100644 --- a/app/assets/javascripts/admin/templates/dashboard.hbs +++ b/app/assets/javascripts/admin/templates/dashboard.hbs @@ -3,7 +3,7 @@ {{#if showVersionChecks}}
- {{version-checks versionCheck=versionCheck}} + {{version-checks versionCheck=versionCheck tagName=""}}
{{/if}} @@ -22,21 +22,30 @@ {{i18n "admin.dashboard.general_tab"}} {{/link-to}} - - - + + {{#if isModerationTabVisible}} + + {{/if}} + + {{#if isSecurityTabVisible}} + + {{/if}} + + {{#if isReportsTabVisible}} + + {{/if}} {{outlet}} diff --git a/app/assets/javascripts/admin/templates/dashboard_general.hbs b/app/assets/javascripts/admin/templates/dashboard_general.hbs index 16214a92e3..5566271a20 100644 --- a/app/assets/javascripts/admin/templates/dashboard_general.hbs +++ b/app/assets/javascripts/admin/templates/dashboard_general.hbs @@ -1,97 +1,101 @@ {{#conditional-loading-spinner condition=isLoading}} {{plugin-outlet name="admin-dashboard-general-top"}} -
-
-
-

- - {{i18n "admin.dashboard.community_health"}} - -

- {{period-chooser period=period action=(action "changePeriod") content=availablePeriods fullDay=true}} -
+ {{#if isCommunityHealthVisible}} +
+
+
+

+ + {{i18n "admin.dashboard.community_health"}} + +

+ {{period-chooser period=period action=(action "changePeriod") content=availablePeriods fullDay=true}} +
-
-
- {{admin-report - dataSourceName="consolidated_page_views" - forcedModes="stacked-chart" - filters=filters}} +
+
+ {{admin-report + dataSourceName="consolidated_page_views" + forcedModes="stacked-chart" + filters=filters}} - {{admin-report - dataSourceName="signups" - showTrend=true - forcedModes="chart" - filters=filters}} + {{admin-report + dataSourceName="signups" + showTrend=true + forcedModes="chart" + filters=filters}} - {{admin-report - dataSourceName="topics" - showTrend=true - forcedModes="chart" - filters=filters}} + {{admin-report + dataSourceName="topics" + showTrend=true + forcedModes="chart" + filters=filters}} - {{admin-report - dataSourceName="posts" - showTrend=true - forcedModes="chart" - filters=filters}} + {{admin-report + dataSourceName="posts" + showTrend=true + forcedModes="chart" + filters=filters}} - {{admin-report - dataSourceName="dau_by_mau" - showTrend=true - forcedModes="chart" - filters=filters}} + {{admin-report + dataSourceName="dau_by_mau" + showTrend=true + forcedModes="chart" + filters=filters}} - {{admin-report - dataSourceName="daily_engaged_users" - showTrend=true - forcedModes="chart" - filters=filters}} + {{admin-report + dataSourceName="daily_engaged_users" + showTrend=true + forcedModes="chart" + filters=filters}} - {{admin-report - dataSourceName="new_contributors" - showTrend=true - forcedModes="chart" - filters=filters}} + {{admin-report + dataSourceName="new_contributors" + showTrend=true + forcedModes="chart" + filters=filters}} +
-
+ {{/if}}
- {{#if activityMetrics.length}} -
-
- -
-
-
-
-
-
{{i18n "admin.dashboard.reports.today"}}
-
{{i18n "admin.dashboard.reports.yesterday"}}
-
{{i18n "admin.dashboard.reports.last_7_days"}}
-
{{i18n "admin.dashboard.reports.last_30_days"}}
-
+ {{#if isActivityMetricsVisible}} + {{#if activityMetrics.length}} +
+
+ +
+
+
+
+
+
{{i18n "admin.dashboard.reports.today"}}
+
{{i18n "admin.dashboard.reports.yesterday"}}
+
{{i18n "admin.dashboard.reports.last_7_days"}}
+
{{i18n "admin.dashboard.reports.last_30_days"}}
+
- {{#each activityMetrics as |metric|}} - {{admin-report - showHeader=false - filters=activityMetricsFilters - forcedModes="counters" - dataSourceName=metric}} - {{/each}} + {{#each activityMetrics as |metric|}} + {{admin-report + showHeader=false + filters=activityMetricsFilters + forcedModes="counters" + dataSourceName=metric}} + {{/each}} +
-
+ {{/if}} {{/if}}
@@ -130,20 +134,22 @@
-
- {{admin-report - filters=topReferredTopicsFilters - dataSourceName="top_referred_topics" - reportOptions=topReferredTopicsOptions}} + {{#if isSearchReportsVisible}} +
+ {{admin-report + filters=topReferredTopicsFilters + dataSourceName="top_referred_topics" + reportOptions=topReferredTopicsOptions}} - {{admin-report - dataSourceName="trending_search" - reportOptions=trendingSearchOptions - filters=trendingSearchFilters - isEnabled=logSearchQueriesEnabled - disabledLabel=trendingSearchDisabledLabel}} - {{html-safe (i18n "admin.dashboard.reports.trending_search.more" basePath=basePath)}} -
+ {{admin-report + dataSourceName="trending_search" + reportOptions=trendingSearchOptions + filters=trendingSearchFilters + isEnabled=logSearchQueriesEnabled + disabledLabel=trendingSearchDisabledLabel}} + {{html-safe (i18n "admin.dashboard.reports.trending_search.more" basePath=basePath)}} +
+ {{/if}}
{{plugin-outlet name="admin-dashboard-general-bottom"}} diff --git a/app/assets/javascripts/admin/templates/dashboard_moderation.hbs b/app/assets/javascripts/admin/templates/dashboard_moderation.hbs index 06ae3567f6..a6566b78e6 100644 --- a/app/assets/javascripts/admin/templates/dashboard_moderation.hbs +++ b/app/assets/javascripts/admin/templates/dashboard_moderation.hbs @@ -1,27 +1,29 @@
{{plugin-outlet name="admin-dashboard-moderation-top"}} -
-
-

- - {{i18n "admin.dashboard.moderators_activity"}} - -

- {{period-chooser - period=period - action=(action "changePeriod") - content=availablePeriods - fullDay=true}} -
+ {{#if isModeratorsActivityVisible}} +
+
+

+ + {{i18n "admin.dashboard.moderators_activity"}} + +

+ {{period-chooser + period=period + action=(action "changePeriod") + content=availablePeriods + fullDay=true}} +
-
- {{admin-report - filters=filters - showHeader=false - dataSourceName="moderators_activity"}} +
+ {{admin-report + filters=filters + showHeader=false + dataSourceName="moderators_activity"}} +
-
+ {{/if}}
{{admin-report diff --git a/app/assets/javascripts/admin/templates/modal/admin-merge-users-confirmation.hbs b/app/assets/javascripts/admin/templates/modal/admin-merge-users-confirmation.hbs index 119cd3ad08..b2522607b5 100644 --- a/app/assets/javascripts/admin/templates/modal/admin-merge-users-confirmation.hbs +++ b/app/assets/javascripts/admin/templates/modal/admin-merge-users-confirmation.hbs @@ -7,14 +7,14 @@ diff --git a/app/assets/javascripts/admin/templates/modal/admin-merge-users-prompt.hbs b/app/assets/javascripts/admin/templates/modal/admin-merge-users-prompt.hbs index 69bdd69403..71f7a404bc 100644 --- a/app/assets/javascripts/admin/templates/modal/admin-merge-users-prompt.hbs +++ b/app/assets/javascripts/admin/templates/modal/admin-merge-users-prompt.hbs @@ -10,14 +10,14 @@ diff --git a/app/assets/javascripts/admin/templates/user-index.hbs b/app/assets/javascripts/admin/templates/user-index.hbs index adbe7e50e9..1353ed0d78 100644 --- a/app/assets/javascripts/admin/templates/user-index.hbs +++ b/app/assets/javascripts/admin/templates/user-index.hbs @@ -686,8 +686,8 @@ {{/if}} {{#if model.can_be_merged}} - {{d-button label="admin.user.merge.transfer_and_delete" - icon="trash-alt" + {{d-button label="admin.user.merge.button" + icon="arrows-alt-h" class="btn-danger" action=(action "promptTargetUser")}} {{/if}} diff --git a/app/assets/javascripts/app-boot.js b/app/assets/javascripts/app-boot.js new file mode 100644 index 0000000000..d744e7f649 --- /dev/null +++ b/app/assets/javascripts/app-boot.js @@ -0,0 +1,11 @@ +// discourse-skip-module + +(function() { + if (window.unsupportedBrowser) { + throw "Unsupported browser detected"; + } + let Discourse = requirejs("discourse/app").default; + + // ensure Discourse is added as a global + window.Discourse = Discourse; +})(); diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 6a6cc8ac41..d7f9c0d96b 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -1,104 +1,101 @@ -//= require_tree ./ember-addons/utils -//= require_tree ./discourse-common -//= require ./ember-addons/decorator-alias -//= require ./ember-addons/macro-alias -//= require ./ember-addons/fmt +//= require_tree ./discourse-common/addon //= require ./polyfills //= require_tree ./select-kit -//= require ./discourse -//= require ./deprecated +//= require ./discourse/app/app +//= require ./app-boot // Stuff we need to load first -//= require ./discourse/lib/to-markdown -//= require ./discourse/lib/utilities -//= require ./discourse/lib/user-presence -//= require ./discourse/lib/logout -//= require ./discourse/mixins/singleton -//= require ./discourse/models/rest -//= require ./discourse/models/session -//= require ./discourse/lib/ajax -//= require ./discourse/lib/text -//= require ./discourse/lib/hash -//= require ./discourse/lib/load-script -//= require ./discourse/lib/notification-levels -//= require ./discourse/services/app-events -//= require ./discourse/lib/offset-calculator -//= require ./discourse/lib/lock-on -//= require ./discourse/lib/url -//= require ./discourse/lib/debounce -//= require ./discourse/lib/quote -//= require ./discourse/lib/key-value-store -//= require ./discourse/lib/computed -//= require ./discourse/lib/formatter -//= require ./discourse/lib/text-direction -//= require ./discourse/lib/eyeline -//= require ./discourse/lib/show-modal -//= require ./discourse/mixins/scrolling -//= require ./discourse/lib/ajax-error -//= require ./discourse/models/result-set -//= require ./discourse/models/store -//= require ./discourse/models/action-summary -//= require ./discourse/models/permission-type -//= require ./discourse/models/category -//= require ./discourse/models/topic -//= require ./discourse/models/draft -//= require ./discourse/models/composer -//= require ./discourse/models/badge-grouping -//= require ./discourse/models/badge -//= require ./discourse/models/permission-type -//= require ./discourse/models/user-action-group -//= require ./discourse/models/trust-level -//= require ./discourse/lib/search -//= require ./discourse/lib/user-search -//= require ./discourse/lib/export-csv -//= require ./discourse/lib/autocomplete -//= require ./discourse/lib/after-transition -//= require ./discourse/lib/safari-hacks -//= require ./discourse/lib/put-cursor-at-end -//= require_tree ./discourse/adapters -//= require ./discourse/models/post-action-type -//= require ./discourse/models/post -//= require ./discourse/lib/posts-with-placeholders -//= require ./discourse/models/post-stream -//= require ./discourse/models/topic-details -//= require ./discourse/models/topic -//= require ./discourse/models/user-action -//= require ./discourse/models/draft -//= require ./discourse/models/composer -//= require ./discourse/models/user-badge -//= require_tree ./discourse/lib -//= require_tree ./discourse/mixins -//= require ./discourse/models/invite -//= require ./discourse/controllers/discovery-sortable -//= require ./discourse/controllers/navigation/default -//= require ./discourse/components/edit-category-panel -//= require ./discourse/lib/link-mentions -//= require ./discourse/components/site-header -//= require ./discourse/components/d-editor -//= require ./discourse/lib/screen-track -//= require ./discourse/routes/discourse -//= require ./discourse/routes/build-topic-route -//= require ./discourse/routes/restricted-user -//= require ./discourse/routes/user-topic-list -//= require ./discourse/routes/user-activity-stream -//= require ./discourse/routes/topic-from-params -//= require ./discourse/components/text-field -//= require ./discourse/components/conditional-loading-spinner -//= require ./discourse/helpers/user-avatar -//= require ./discourse/helpers/cold-age-class -//= require ./discourse/helpers/loading-spinner -//= require ./discourse/helpers/category-link -//= require ./discourse/lib/export-result -//= require ./discourse/mapping-router +//= require ./discourse/app/lib/to-markdown +//= require ./discourse/app/lib/utilities +//= require ./discourse/app/lib/user-presence +//= require ./discourse/app/lib/logout +//= require ./discourse/app/mixins/singleton +//= require ./discourse/app/models/rest +//= require ./discourse/app/models/session +//= require ./discourse/app/lib/ajax +//= require ./discourse/app/lib/text +//= require ./discourse/app/lib/hash +//= require ./discourse/app/lib/load-script +//= require ./discourse/app/lib/notification-levels +//= require ./discourse/app/services/app-events +//= require ./discourse/app/lib/offset-calculator +//= require ./discourse/app/lib/lock-on +//= require ./discourse/app/lib/url +//= require ./discourse/app/lib/debounce +//= require ./discourse/app/lib/quote +//= require ./discourse/app/lib/key-value-store +//= require ./discourse/app/lib/computed +//= require ./discourse/app/lib/formatter +//= require ./discourse/app/lib/text-direction +//= require ./discourse/app/lib/eyeline +//= require ./discourse/app/lib/show-modal +//= require ./discourse/app/mixins/scrolling +//= require ./discourse/app/lib/ajax-error +//= require ./discourse/app/models/result-set +//= require ./discourse/app/models/store +//= require ./discourse/app/models/action-summary +//= require ./discourse/app/models/permission-type +//= require ./discourse/app/models/category +//= require ./discourse/app/models/topic +//= require ./discourse/app/models/draft +//= require ./discourse/app/models/composer +//= require ./discourse/app/models/badge-grouping +//= require ./discourse/app/models/badge +//= require ./discourse/app/models/permission-type +//= require ./discourse/app/models/user-action-group +//= require ./discourse/app/models/trust-level +//= require ./discourse/app/lib/search +//= require ./discourse/app/lib/user-search +//= require ./discourse/app/lib/export-csv +//= require ./discourse/app/lib/autocomplete +//= require ./discourse/app/lib/after-transition +//= require ./discourse/app/lib/safari-hacks +//= require ./discourse/app/lib/put-cursor-at-end +//= require_tree ./discourse/app/adapters +//= require ./discourse/app/models/post-action-type +//= require ./discourse/app/models/post +//= require ./discourse/app/lib/posts-with-placeholders +//= require ./discourse/app/models/post-stream +//= require ./discourse/app/models/topic-details +//= require ./discourse/app/models/topic +//= require ./discourse/app/models/user-action +//= require ./discourse/app/models/draft +//= require ./discourse/app/models/composer +//= require ./discourse/app/models/user-badge +//= require_tree ./discourse/app/lib +//= require_tree ./discourse/app/mixins +//= require ./discourse/app/models/invite +//= require ./discourse/app/controllers/discovery-sortable +//= require ./discourse/app/controllers/navigation/default +//= require ./discourse/app/components/edit-category-panel +//= require ./discourse/app/lib/link-mentions +//= require ./discourse/app/components/site-header +//= require ./discourse/app/components/d-editor +//= require ./discourse/app/lib/screen-track +//= require ./discourse/app/routes/discourse +//= require ./discourse/app/routes/build-topic-route +//= require ./discourse/app/routes/restricted-user +//= require ./discourse/app/routes/user-topic-list +//= require ./discourse/app/routes/user-activity-stream +//= require ./discourse/app/routes/topic-from-params +//= require ./discourse/app/components/text-field +//= require ./discourse/app/components/conditional-loading-spinner +//= require ./discourse/app/helpers/user-avatar +//= require ./discourse/app/helpers/cold-age-class +//= require ./discourse/app/helpers/loading-spinner +//= require ./discourse/app/helpers/category-link +//= require ./discourse/app/lib/export-result +//= require ./discourse/app/mapping-router -//= require_tree ./discourse/controllers -//= require_tree ./discourse/models -//= require_tree ./discourse/components -//= require_tree ./discourse/raw-views -//= require_tree ./discourse/helpers -//= require_tree ./discourse/templates -//= require_tree ./discourse/routes -//= require_tree ./discourse/pre-initializers -//= require_tree ./discourse/initializers -//= require_tree ./discourse/services -//= require_tree ./discourse/widgets +//= require_tree ./discourse/app/controllers +//= require_tree ./discourse/app/models +//= require_tree ./discourse/app/components +//= require_tree ./discourse/app/raw-views +//= require_tree ./discourse/app/helpers +//= require_tree ./discourse/app/templates +//= require_tree ./discourse/app/routes +//= require_tree ./discourse/app/pre-initializers +//= require_tree ./discourse/app/initializers +//= require_tree ./discourse/app/services + +//= require_tree ./discourse/app/widgets diff --git a/app/assets/javascripts/browser-detect.js b/app/assets/javascripts/browser-detect.js index bdbbc27b3e..c13298dbb4 100644 --- a/app/assets/javascripts/browser-detect.js +++ b/app/assets/javascripts/browser-detect.js @@ -1,3 +1,12 @@ if (!window.WeakMap || !window.Promise) { window.unsupportedBrowser = true; +} else { + // Some implementations of `WeakMap.prototype.has` do not accept false + // values and Ember's `isClassicDecorator` sometimes does that (it only + // checks for `null` and `undefined`). + try { + new WeakMap().has(0); + } catch (err) { + window.unsupportedBrowser = true; + } } diff --git a/app/assets/javascripts/deprecated.js b/app/assets/javascripts/deprecated.js deleted file mode 100644 index b660024fec..0000000000 --- a/app/assets/javascripts/deprecated.js +++ /dev/null @@ -1,4 +0,0 @@ -// ensure Discourse is added as a global -(function() { - window.Discourse = requirejs("discourse").default; -})(); diff --git a/app/assets/javascripts/template_include.js.erb b/app/assets/javascripts/discourse-common/addon/.gitkeep similarity index 100% rename from app/assets/javascripts/template_include.js.erb rename to app/assets/javascripts/discourse-common/addon/.gitkeep diff --git a/app/assets/javascripts/discourse-common/addon/config/environment.js b/app/assets/javascripts/discourse-common/addon/config/environment.js new file mode 100644 index 0000000000..18ce3cc976 --- /dev/null +++ b/app/assets/javascripts/discourse-common/addon/config/environment.js @@ -0,0 +1,3 @@ +export const INPUT_DELAY = 250; + +export default { environment: Ember.testing ? "test" : "development" }; diff --git a/app/assets/javascripts/discourse-common/helpers/bound-i18n.js b/app/assets/javascripts/discourse-common/addon/helpers/bound-i18n.js similarity index 100% rename from app/assets/javascripts/discourse-common/helpers/bound-i18n.js rename to app/assets/javascripts/discourse-common/addon/helpers/bound-i18n.js diff --git a/app/assets/javascripts/discourse-common/helpers/component-for-collection.js b/app/assets/javascripts/discourse-common/addon/helpers/component-for-collection.js similarity index 100% rename from app/assets/javascripts/discourse-common/helpers/component-for-collection.js rename to app/assets/javascripts/discourse-common/addon/helpers/component-for-collection.js diff --git a/app/assets/javascripts/discourse-common/helpers/component-for-row.js b/app/assets/javascripts/discourse-common/addon/helpers/component-for-row.js similarity index 100% rename from app/assets/javascripts/discourse-common/helpers/component-for-row.js rename to app/assets/javascripts/discourse-common/addon/helpers/component-for-row.js diff --git a/app/assets/javascripts/discourse-common/addon/helpers/d-icon.js b/app/assets/javascripts/discourse-common/addon/helpers/d-icon.js new file mode 100644 index 0000000000..97f93273d9 --- /dev/null +++ b/app/assets/javascripts/discourse-common/addon/helpers/d-icon.js @@ -0,0 +1,7 @@ +import { registerUnbound } from "discourse-common/lib/helpers"; +import { renderIcon } from "discourse-common/lib/icon-library"; +import { htmlSafe } from "@ember/template"; + +registerUnbound("d-icon", function(id, params) { + return htmlSafe(renderIcon("string", id, params)); +}); diff --git a/app/assets/javascripts/discourse-common/addon/helpers/fa-icon.js b/app/assets/javascripts/discourse-common/addon/helpers/fa-icon.js new file mode 100644 index 0000000000..12b1823ced --- /dev/null +++ b/app/assets/javascripts/discourse-common/addon/helpers/fa-icon.js @@ -0,0 +1,13 @@ +import { registerUnbound } from "discourse-common/lib/helpers"; +import { renderIcon } from "discourse-common/lib/icon-library"; +import deprecated from "discourse-common/lib/deprecated"; +import { htmlSafe } from "@ember/template"; + +export function iconHTML(id, params) { + return renderIcon("string", id, params); +} + +registerUnbound("fa-icon", function(icon, params) { + deprecated("Use `{{d-icon}}` instead of `{{fa-icon}}"); + return htmlSafe(iconHTML(icon, params)); +}); diff --git a/app/assets/javascripts/discourse-common/helpers/get-url.js b/app/assets/javascripts/discourse-common/addon/helpers/get-url.js similarity index 100% rename from app/assets/javascripts/discourse-common/helpers/get-url.js rename to app/assets/javascripts/discourse-common/addon/helpers/get-url.js diff --git a/app/assets/javascripts/discourse-common/helpers/html-safe.js b/app/assets/javascripts/discourse-common/addon/helpers/html-safe.js similarity index 100% rename from app/assets/javascripts/discourse-common/helpers/html-safe.js rename to app/assets/javascripts/discourse-common/addon/helpers/html-safe.js diff --git a/app/assets/javascripts/discourse-common/helpers/i18n.js b/app/assets/javascripts/discourse-common/addon/helpers/i18n.js similarity index 100% rename from app/assets/javascripts/discourse-common/helpers/i18n.js rename to app/assets/javascripts/discourse-common/addon/helpers/i18n.js diff --git a/app/assets/javascripts/discourse-common/helpers/popular-themes.js b/app/assets/javascripts/discourse-common/addon/helpers/popular-themes.js similarity index 100% rename from app/assets/javascripts/discourse-common/helpers/popular-themes.js rename to app/assets/javascripts/discourse-common/addon/helpers/popular-themes.js diff --git a/app/assets/javascripts/discourse-common/lib/attribute-hook.js b/app/assets/javascripts/discourse-common/addon/lib/attribute-hook.js similarity index 100% rename from app/assets/javascripts/discourse-common/lib/attribute-hook.js rename to app/assets/javascripts/discourse-common/addon/lib/attribute-hook.js diff --git a/app/assets/javascripts/discourse-common/lib/deprecated.js b/app/assets/javascripts/discourse-common/addon/lib/deprecated.js similarity index 100% rename from app/assets/javascripts/discourse-common/lib/deprecated.js rename to app/assets/javascripts/discourse-common/addon/lib/deprecated.js diff --git a/app/assets/javascripts/discourse-common/lib/get-owner.js b/app/assets/javascripts/discourse-common/addon/lib/get-owner.js similarity index 100% rename from app/assets/javascripts/discourse-common/lib/get-owner.js rename to app/assets/javascripts/discourse-common/addon/lib/get-owner.js diff --git a/app/assets/javascripts/discourse-common/lib/get-url.js b/app/assets/javascripts/discourse-common/addon/lib/get-url.js similarity index 100% rename from app/assets/javascripts/discourse-common/lib/get-url.js rename to app/assets/javascripts/discourse-common/addon/lib/get-url.js diff --git a/app/assets/javascripts/discourse-common/addon/lib/helpers.js b/app/assets/javascripts/discourse-common/addon/lib/helpers.js new file mode 100644 index 0000000000..759cc8995a --- /dev/null +++ b/app/assets/javascripts/discourse-common/addon/lib/helpers.js @@ -0,0 +1,94 @@ +import { get } from "@ember/object"; +import Helper from "@ember/component/helper"; +import RawHandlebars from "discourse-common/lib/raw-handlebars"; +import { htmlSafe } from "@ember/template"; + +export function makeArray(obj) { + if (obj === null || obj === undefined) { + return []; + } + return Array.isArray(obj) ? obj : [obj]; +} + +export function htmlHelper(fn) { + return Helper.helper(function(...args) { + args = + args.length > 1 ? args[0].concat({ hash: args[args.length - 1] }) : args; + return htmlSafe(fn.apply(this, args) || ""); + }); +} + +const _helpers = {}; + +function rawGet(ctx, property, options) { + if (options.types && options.data.view) { + var view = options.data.view; + return view.getStream + ? view.getStream(property).value() + : view.getAttr(property); + } else { + return get(ctx, property); + } +} + +export function registerHelper(name, fn) { + _helpers[name] = Helper.helper(fn); +} + +export function findHelper(name) { + return _helpers[name] || _helpers[name.dasherize()]; +} + +export function registerHelpers(registry) { + Object.keys(_helpers).forEach(name => { + registry.register(`helper:${name}`, _helpers[name], { singleton: false }); + }); +} + +function resolveParams(ctx, options) { + let params = {}; + const hash = options.hash; + + if (hash) { + if (options.hashTypes) { + Object.keys(hash).forEach(function(k) { + const type = options.hashTypes[k]; + if ( + type === "STRING" || + type === "StringLiteral" || + type === "SubExpression" + ) { + params[k] = hash[k]; + } else if (type === "ID" || type === "PathExpression") { + params[k] = rawGet(ctx, hash[k], options); + } + }); + } else { + params = hash; + } + } + return params; +} + +export function registerUnbound(name, fn) { + const func = function(...args) { + const options = args.pop(); + const properties = args; + + for (let i = 0; i < properties.length; i++) { + if ( + options.types && + (options.types[i] === "ID" || options.types[i] === "PathExpression") + ) { + properties[i] = rawGet(this, properties[i], options); + } + } + + return fn.call(this, ...properties, resolveParams(this, options)); + }; + + _helpers[name] = Helper.extend({ + compute: (params, args) => fn(...params, args) + }); + RawHandlebars.registerHelper(name, func); +} diff --git a/app/assets/javascripts/discourse-common/lib/icon-library.js b/app/assets/javascripts/discourse-common/addon/lib/icon-library.js similarity index 100% rename from app/assets/javascripts/discourse-common/lib/icon-library.js rename to app/assets/javascripts/discourse-common/addon/lib/icon-library.js diff --git a/app/assets/javascripts/discourse-common/lib/raw-handlebars-helpers.js b/app/assets/javascripts/discourse-common/addon/lib/raw-handlebars-helpers.js similarity index 100% rename from app/assets/javascripts/discourse-common/lib/raw-handlebars-helpers.js rename to app/assets/javascripts/discourse-common/addon/lib/raw-handlebars-helpers.js diff --git a/app/assets/javascripts/discourse-common/addon/lib/raw-handlebars.js b/app/assets/javascripts/discourse-common/addon/lib/raw-handlebars.js new file mode 100644 index 0000000000..6fe7591746 --- /dev/null +++ b/app/assets/javascripts/discourse-common/addon/lib/raw-handlebars.js @@ -0,0 +1,132 @@ +import Handlebars from "handlebars"; + +// This is a mechanism for quickly rendering templates which is Ember aware +// templates are highly compatible with Ember so you don't need to worry about calling "get" +// and discourseComputed properties function, additionally it uses stringParams like Ember does +const RawHandlebars = Handlebars.create(); + +function buildPath(blk, args) { + var result = { + type: "PathExpression", + data: false, + depth: blk.path.depth, + loc: blk.path.loc + }; + + // Server side precompile doesn't have jquery.extend + Object.keys(args).forEach(function(a) { + result[a] = args[a]; + }); + + return result; +} + +function replaceGet(ast) { + var visitor = new Handlebars.Visitor(); + visitor.mutating = true; + + visitor.MustacheStatement = function(mustache) { + if (!(mustache.params.length || mustache.hash)) { + mustache.params[0] = mustache.path; + mustache.path = buildPath(mustache, { + parts: ["get"], + original: "get", + strict: true, + falsy: true + }); + } + return Handlebars.Visitor.prototype.MustacheStatement.call(this, mustache); + }; + + // rewrite `each x as |y|` as each y in x` + // This allows us to use the same syntax in all templates + visitor.BlockStatement = function(block) { + if (block.path.original === "each" && block.params.length === 1) { + var paramName = block.program.blockParams[0]; + block.params = [ + buildPath(block, { original: paramName }), + { type: "CommentStatement", value: "in" }, + block.params[0] + ]; + delete block.program.blockParams; + } + + return Handlebars.Visitor.prototype.BlockStatement.call(this, block); + }; + + visitor.accept(ast); +} + +if (Handlebars.Compiler) { + RawHandlebars.Compiler = function() {}; + RawHandlebars.Compiler.prototype = Object.create( + Handlebars.Compiler.prototype + ); + RawHandlebars.Compiler.prototype.compiler = RawHandlebars.Compiler; + + RawHandlebars.JavaScriptCompiler = function() {}; + + RawHandlebars.JavaScriptCompiler.prototype = Object.create( + Handlebars.JavaScriptCompiler.prototype + ); + RawHandlebars.JavaScriptCompiler.prototype.compiler = + RawHandlebars.JavaScriptCompiler; + RawHandlebars.JavaScriptCompiler.prototype.namespace = "RawHandlebars"; + + RawHandlebars.precompile = function(value, asObject) { + var ast = Handlebars.parse(value); + replaceGet(ast); + + var options = { + knownHelpers: { + get: true + }, + data: true, + stringParams: true + }; + + asObject = asObject === undefined ? true : asObject; + + var environment = new RawHandlebars.Compiler().compile(ast, options); + return new RawHandlebars.JavaScriptCompiler().compile( + environment, + options, + undefined, + asObject + ); + }; + + RawHandlebars.compile = function(string) { + var ast = Handlebars.parse(string); + replaceGet(ast); + + // this forces us to rewrite helpers + var options = { data: true, stringParams: true }; + var environment = new RawHandlebars.Compiler().compile(ast, options); + var templateSpec = new RawHandlebars.JavaScriptCompiler().compile( + environment, + options, + undefined, + true + ); + + var t = RawHandlebars.template(templateSpec); + t.isMethod = false; + + return t; + }; +} + +export function template() { + return RawHandlebars.template.apply(this, arguments); +} + +export function precompile() { + return RawHandlebars.precompile.apply(this, arguments); +} + +export function compile() { + return RawHandlebars.compile.apply(this, arguments); +} + +export default RawHandlebars; diff --git a/app/assets/javascripts/discourse-common/mixins/focus-event.js b/app/assets/javascripts/discourse-common/addon/mixins/focus-event.js similarity index 100% rename from app/assets/javascripts/discourse-common/mixins/focus-event.js rename to app/assets/javascripts/discourse-common/addon/mixins/focus-event.js diff --git a/app/assets/javascripts/discourse-common/resolver.js b/app/assets/javascripts/discourse-common/addon/resolver.js similarity index 100% rename from app/assets/javascripts/discourse-common/resolver.js rename to app/assets/javascripts/discourse-common/addon/resolver.js diff --git a/app/assets/javascripts/discourse-common/addon/utils/decorator-alias.js b/app/assets/javascripts/discourse-common/addon/utils/decorator-alias.js new file mode 100644 index 0000000000..c483a1cc4f --- /dev/null +++ b/app/assets/javascripts/discourse-common/addon/utils/decorator-alias.js @@ -0,0 +1,22 @@ +import extractValue from "discourse-common/utils/extract-value"; + +export default function decoratorAlias(fn, errorMessage) { + return function(...params) { + // determine if user called as @discourseComputed('blah', 'blah') or @discourseComputed + if (params.length === 0) { + throw new Error(errorMessage); + } else { + return function(target, key, desc) { + return { + enumerable: desc.enumerable, + configurable: desc.configurable, + writable: desc.writable, + initializer: function() { + var value = extractValue(desc); + return fn.apply(null, params.concat(value)); + } + }; + }; + } + }; +} diff --git a/app/assets/javascripts/discourse-common/addon/utils/decorators.js b/app/assets/javascripts/discourse-common/addon/utils/decorators.js new file mode 100644 index 0000000000..2b6548ed1d --- /dev/null +++ b/app/assets/javascripts/discourse-common/addon/utils/decorators.js @@ -0,0 +1,78 @@ +import handleDescriptor from "discourse-common/utils/handle-descriptor"; +import isDescriptor from "discourse-common/utils/is-descriptor"; +import extractValue from "discourse-common/utils/extract-value"; +import decoratorAlias from "discourse-common/utils/decorator-alias"; +import macroAlias from "discourse-common/utils/macro-alias"; +import { schedule, next } from "@ember/runloop"; + +export default function discourseComputedDecorator(...params) { + // determine if user called as @discourseComputed('blah', 'blah') or @discourseComputed + if (isDescriptor(params[params.length - 1])) { + return handleDescriptor(...arguments); + } else { + return function(/* target, key, desc */) { + return handleDescriptor(...arguments, params); + }; + } +} + +export function afterRender(target, name, descriptor) { + const originalFunction = descriptor.value; + descriptor.value = function() { + next(() => { + schedule("afterRender", () => { + if (this.element && !this.isDestroying && !this.isDestroyed) { + return originalFunction.apply(this, arguments); + } + }); + }); + }; +} + +export function readOnly(target, name, desc) { + return { + writable: false, + enumerable: desc.enumerable, + configurable: desc.configurable, + initializer: function() { + var value = extractValue(desc); + return value.readOnly(); + } + }; +} + +/* eslint-disable */ +export var on = decoratorAlias(Ember.on, "Can not `on` without event names"); +export var observes = decoratorAlias( + Ember.observer, + "Can not `observe` without property names" +); + +export var alias = macroAlias(Ember.computed.alias); +export var and = macroAlias(Ember.computed.and); +export var bool = macroAlias(Ember.computed.bool); +export var collect = macroAlias(Ember.computed.collect); +export var empty = macroAlias(Ember.computed.empty); +export var equal = macroAlias(Ember.computed.equal); +export var filter = macroAlias(Ember.computed.filter); +export var filterBy = macroAlias(Ember.computed.filterBy); +export var gt = macroAlias(Ember.computed.gt); +export var gte = macroAlias(Ember.computed.gte); +export var lt = macroAlias(Ember.computed.lt); +export var lte = macroAlias(Ember.computed.lte); +export var map = macroAlias(Ember.computed.map); +export var mapBy = macroAlias(Ember.computed.mapBy); +export var match = macroAlias(Ember.computed.match); +export var max = macroAlias(Ember.computed.max); +export var min = macroAlias(Ember.computed.min); +export var none = macroAlias(Ember.computed.none); +export var not = macroAlias(Ember.computed.not); +export var notEmpty = macroAlias(Ember.computed.notEmpty); +export var oneWay = macroAlias(Ember.computed.oneWay); +export var or = macroAlias(Ember.computed.or); +export var reads = macroAlias(Ember.computed.reads); +export var setDiff = macroAlias(Ember.computed.setDiff); +export var sort = macroAlias(Ember.computed.sort); +export var sum = macroAlias(Ember.computed.sum); +export var union = macroAlias(Ember.computed.union); +export var uniq = macroAlias(Ember.computed.uniq); diff --git a/app/assets/javascripts/discourse-common/addon/utils/extract-value.js b/app/assets/javascripts/discourse-common/addon/utils/extract-value.js new file mode 100644 index 0000000000..839d2e924c --- /dev/null +++ b/app/assets/javascripts/discourse-common/addon/utils/extract-value.js @@ -0,0 +1,5 @@ +export default function extractValue(desc) { + return ( + desc.value || (typeof desc.initializer === "function" && desc.initializer()) + ); +} diff --git a/app/assets/javascripts/discourse-common/addon/utils/handle-descriptor.js b/app/assets/javascripts/discourse-common/addon/utils/handle-descriptor.js new file mode 100644 index 0000000000..e4899c938e --- /dev/null +++ b/app/assets/javascripts/discourse-common/addon/utils/handle-descriptor.js @@ -0,0 +1,71 @@ +import { computed, get } from "@ember/object"; +import extractValue from "./extract-value"; + +export default function handleDescriptor(target, key, desc, params = []) { + return { + enumerable: desc.enumerable, + configurable: desc.configurable, + writeable: desc.writeable, + initializer: function() { + let computedDescriptor; + + if (desc.writable) { + var val = extractValue(desc); + if (typeof val === "object") { + let value = {}; + if (val.get) { + value.get = callUserSuppliedGet(params, val.get); + } + if (val.set) { + value.set = callUserSuppliedSet(params, val.set); + } + computedDescriptor = value; + } else { + computedDescriptor = callUserSuppliedGet(params, val); + } + } else { + throw new Error( + "ember-computed-decorators does not support using getters and setters" + ); + } + + return computed.apply(null, params.concat(computedDescriptor)); + } + }; +} + +function niceAttr(attr) { + const parts = attr.split("."); + let i; + + for (i = 0; i < parts.length; i++) { + if ( + parts[i] === "@each" || + parts[i] === "[]" || + parts[i].indexOf("{") !== -1 + ) { + break; + } + } + + return parts.slice(0, i).join("."); +} + +function callUserSuppliedGet(params, func) { + params = params.map(niceAttr); + return function() { + let paramValues = params.map(p => get(this, p)); + + return func.apply(this, paramValues); + }; +} + +function callUserSuppliedSet(params, func) { + params = params.map(niceAttr); + return function(key, value) { + let paramValues = params.map(p => get(this, p)); + paramValues.unshift(value); + + return func.apply(this, paramValues); + }; +} diff --git a/app/assets/javascripts/discourse-common/addon/utils/is-descriptor.js b/app/assets/javascripts/discourse-common/addon/utils/is-descriptor.js new file mode 100644 index 0000000000..2e64777f70 --- /dev/null +++ b/app/assets/javascripts/discourse-common/addon/utils/is-descriptor.js @@ -0,0 +1,9 @@ +export default function isDescriptor(item) { + return ( + item && + typeof item === "object" && + "writable" in item && + "enumerable" in item && + "configurable" in item + ); +} diff --git a/app/assets/javascripts/discourse-common/addon/utils/macro-alias.js b/app/assets/javascripts/discourse-common/addon/utils/macro-alias.js new file mode 100644 index 0000000000..5d6223f108 --- /dev/null +++ b/app/assets/javascripts/discourse-common/addon/utils/macro-alias.js @@ -0,0 +1,24 @@ +import isDescriptor from "discourse-common/utils/is-descriptor"; + +function handleDescriptor(target, property, desc, fn, params = []) { + return { + enumerable: desc.enumerable, + configurable: desc.configurable, + writable: desc.writable, + initializer: function() { + return fn(...params); + } + }; +} + +export default function macroAlias(fn) { + return function(...params) { + if (isDescriptor(params[params.length - 1])) { + return handleDescriptor(...params, fn); + } else { + return function(target, property, desc) { + return handleDescriptor(target, property, desc, fn, params); + }; + } + }; +} diff --git a/app/assets/javascripts/discourse-common/app/.gitkeep b/app/assets/javascripts/discourse-common/app/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/assets/javascripts/discourse-common/config/ember-try.js b/app/assets/javascripts/discourse-common/config/ember-try.js new file mode 100644 index 0000000000..bcae42888f --- /dev/null +++ b/app/assets/javascripts/discourse-common/config/ember-try.js @@ -0,0 +1,89 @@ +"use strict"; + +const getChannelURL = require("ember-source-channel-url"); + +module.exports = async function() { + return { + useYarn: true, + scenarios: [ + { + name: "ember-lts-3.8", + npm: { + devDependencies: { + "ember-source": "~3.8.0" + } + } + }, + { + name: "ember-lts-3.12", + npm: { + devDependencies: { + "ember-source": "~3.12.0" + } + } + }, + { + name: "ember-release", + npm: { + devDependencies: { + "ember-source": await getChannelURL("release") + } + } + }, + { + name: "ember-beta", + npm: { + devDependencies: { + "ember-source": await getChannelURL("beta") + } + } + }, + { + name: "ember-canary", + npm: { + devDependencies: { + "ember-source": await getChannelURL("canary") + } + } + }, + // The default `.travis.yml` runs this scenario via `yarn test`, + // not via `ember try`. It's still included here so that running + // `ember try:each` manually or from a customized CI config will run it + // along with all the other scenarios. + { + name: "ember-default", + npm: { + devDependencies: {} + } + }, + { + name: "ember-default-with-jquery", + env: { + EMBER_OPTIONAL_FEATURES: JSON.stringify({ + "jquery-integration": true + }) + }, + npm: { + devDependencies: { + "@ember/jquery": "^0.5.1" + } + } + }, + { + name: "ember-classic", + env: { + EMBER_OPTIONAL_FEATURES: JSON.stringify({ + "application-template-wrapper": true, + "default-async-observers": false, + "template-only-glimmer-components": false + }) + }, + npm: { + ember: { + edition: "classic" + } + } + } + ] + }; +}; diff --git a/app/assets/javascripts/discourse-common/config/environment.js b/app/assets/javascripts/discourse-common/config/environment.js index 18ce3cc976..352093f4ed 100644 --- a/app/assets/javascripts/discourse-common/config/environment.js +++ b/app/assets/javascripts/discourse-common/config/environment.js @@ -1,3 +1,5 @@ -export const INPUT_DELAY = 250; +"use strict"; -export default { environment: Ember.testing ? "test" : "development" }; +module.exports = function(/* environment, appConfig */) { + return {}; +}; diff --git a/app/assets/javascripts/discourse-common/ember-cli-build.js b/app/assets/javascripts/discourse-common/ember-cli-build.js new file mode 100644 index 0000000000..cbf921270c --- /dev/null +++ b/app/assets/javascripts/discourse-common/ember-cli-build.js @@ -0,0 +1,9 @@ +"use strict"; + +const EmberAddon = require("ember-cli/lib/broccoli/ember-addon"); + +module.exports = function(defaults) { + let app = new EmberAddon(defaults, {}); + + return app.toTree(); +}; diff --git a/app/assets/javascripts/discourse-common/helpers/d-icon.js b/app/assets/javascripts/discourse-common/helpers/d-icon.js deleted file mode 100644 index 454bb224b0..0000000000 --- a/app/assets/javascripts/discourse-common/helpers/d-icon.js +++ /dev/null @@ -1,6 +0,0 @@ -import { registerUnbound } from "discourse-common/lib/helpers"; -import { renderIcon } from "discourse-common/lib/icon-library"; - -registerUnbound("d-icon", function(id, params) { - return new Handlebars.SafeString(renderIcon("string", id, params)); -}); diff --git a/app/assets/javascripts/discourse-common/helpers/fa-icon.js b/app/assets/javascripts/discourse-common/helpers/fa-icon.js deleted file mode 100644 index 1d657d086f..0000000000 --- a/app/assets/javascripts/discourse-common/helpers/fa-icon.js +++ /dev/null @@ -1,12 +0,0 @@ -import { registerUnbound } from "discourse-common/lib/helpers"; -import { renderIcon } from "discourse-common/lib/icon-library"; -import deprecated from "discourse-common/lib/deprecated"; - -export function iconHTML(id, params) { - return renderIcon("string", id, params); -} - -registerUnbound("fa-icon", function(icon, params) { - deprecated("Use `{{d-icon}}` instead of `{{fa-icon}}"); - return new Handlebars.SafeString(iconHTML(icon, params)); -}); diff --git a/app/assets/javascripts/discourse-common/index.js b/app/assets/javascripts/discourse-common/index.js new file mode 100644 index 0000000000..7ad7fe9113 --- /dev/null +++ b/app/assets/javascripts/discourse-common/index.js @@ -0,0 +1,12 @@ +"use strict"; + +module.exports = { + name: require("./package").name, + options: { + autoImport: { + alias: { + handlebars: "handlebars/dist/cjs/handlebars.js" + } + } + } +}; diff --git a/app/assets/javascripts/discourse-common/lib/helpers.js b/app/assets/javascripts/discourse-common/lib/helpers.js deleted file mode 100644 index 0f87040d95..0000000000 --- a/app/assets/javascripts/discourse-common/lib/helpers.js +++ /dev/null @@ -1,93 +0,0 @@ -import { get } from "@ember/object"; -import Helper from "@ember/component/helper"; -import RawHandlebars from "discourse-common/lib/raw-handlebars"; - -export function makeArray(obj) { - if (obj === null || obj === undefined) { - return []; - } - return Array.isArray(obj) ? obj : [obj]; -} - -export function htmlHelper(fn) { - return Helper.helper(function(...args) { - args = - args.length > 1 ? args[0].concat({ hash: args[args.length - 1] }) : args; - return new Handlebars.SafeString(fn.apply(this, args) || ""); - }); -} - -const _helpers = {}; - -function rawGet(ctx, property, options) { - if (options.types && options.data.view) { - var view = options.data.view; - return view.getStream - ? view.getStream(property).value() - : view.getAttr(property); - } else { - return get(ctx, property); - } -} - -export function registerHelper(name, fn) { - _helpers[name] = Helper.helper(fn); -} - -export function findHelper(name) { - return _helpers[name] || _helpers[name.dasherize()]; -} - -export function registerHelpers(registry) { - Object.keys(_helpers).forEach(name => { - registry.register(`helper:${name}`, _helpers[name], { singleton: false }); - }); -} - -function resolveParams(ctx, options) { - let params = {}; - const hash = options.hash; - - if (hash) { - if (options.hashTypes) { - Object.keys(hash).forEach(function(k) { - const type = options.hashTypes[k]; - if ( - type === "STRING" || - type === "StringLiteral" || - type === "SubExpression" - ) { - params[k] = hash[k]; - } else if (type === "ID" || type === "PathExpression") { - params[k] = rawGet(ctx, hash[k], options); - } - }); - } else { - params = hash; - } - } - return params; -} - -export function registerUnbound(name, fn) { - const func = function(...args) { - const options = args.pop(); - const properties = args; - - for (let i = 0; i < properties.length; i++) { - if ( - options.types && - (options.types[i] === "ID" || options.types[i] === "PathExpression") - ) { - properties[i] = rawGet(this, properties[i], options); - } - } - - return fn.call(this, ...properties, resolveParams(this, options)); - }; - - _helpers[name] = Helper.extend({ - compute: (params, args) => fn(...params, args) - }); - RawHandlebars.registerHelper(name, func); -} diff --git a/app/assets/javascripts/discourse-common/lib/raw-handlebars.js b/app/assets/javascripts/discourse-common/lib/raw-handlebars.js deleted file mode 100644 index ca08cfd476..0000000000 --- a/app/assets/javascripts/discourse-common/lib/raw-handlebars.js +++ /dev/null @@ -1,131 +0,0 @@ -// This is a mechanism for quickly rendering templates which is Ember aware -// templates are highly compatible with Ember so you don't need to worry about calling "get" -// and discourseComputed properties function, additionally it uses stringParams like Ember does - -const RawHandlebars = Handlebars.create(); - -function buildPath(blk, args) { - var result = { - type: "PathExpression", - data: false, - depth: blk.path.depth, - loc: blk.path.loc - }; - - // Server side precompile doesn't have jquery.extend - Object.keys(args).forEach(function(a) { - result[a] = args[a]; - }); - - return result; -} - -function replaceGet(ast) { - var visitor = new Handlebars.Visitor(); - visitor.mutating = true; - - visitor.MustacheStatement = function(mustache) { - if (!(mustache.params.length || mustache.hash)) { - mustache.params[0] = mustache.path; - mustache.path = buildPath(mustache, { - parts: ["get"], - original: "get", - strict: true, - falsy: true - }); - } - return Handlebars.Visitor.prototype.MustacheStatement.call(this, mustache); - }; - - // rewrite `each x as |y|` as each y in x` - // This allows us to use the same syntax in all templates - visitor.BlockStatement = function(block) { - if (block.path.original === "each" && block.params.length === 1) { - var paramName = block.program.blockParams[0]; - block.params = [ - buildPath(block, { original: paramName }), - { type: "CommentStatement", value: "in" }, - block.params[0] - ]; - delete block.program.blockParams; - } - - return Handlebars.Visitor.prototype.BlockStatement.call(this, block); - }; - - visitor.accept(ast); -} - -if (Handlebars.Compiler) { - RawHandlebars.Compiler = function() {}; - RawHandlebars.Compiler.prototype = Object.create( - Handlebars.Compiler.prototype - ); - RawHandlebars.Compiler.prototype.compiler = RawHandlebars.Compiler; - - RawHandlebars.JavaScriptCompiler = function() {}; - - RawHandlebars.JavaScriptCompiler.prototype = Object.create( - Handlebars.JavaScriptCompiler.prototype - ); - RawHandlebars.JavaScriptCompiler.prototype.compiler = - RawHandlebars.JavaScriptCompiler; - RawHandlebars.JavaScriptCompiler.prototype.namespace = "RawHandlebars"; - - RawHandlebars.precompile = function(value, asObject) { - var ast = Handlebars.parse(value); - replaceGet(ast); - - var options = { - knownHelpers: { - get: true - }, - data: true, - stringParams: true - }; - - asObject = asObject === undefined ? true : asObject; - - var environment = new RawHandlebars.Compiler().compile(ast, options); - return new RawHandlebars.JavaScriptCompiler().compile( - environment, - options, - undefined, - asObject - ); - }; - - RawHandlebars.compile = function(string) { - var ast = Handlebars.parse(string); - replaceGet(ast); - - // this forces us to rewrite helpers - var options = { data: true, stringParams: true }; - var environment = new RawHandlebars.Compiler().compile(ast, options); - var templateSpec = new RawHandlebars.JavaScriptCompiler().compile( - environment, - options, - undefined, - true - ); - - var t = RawHandlebars.template(templateSpec); - t.isMethod = false; - - return t; - }; -} - -export function template() { - return RawHandlebars.template.apply(this, arguments); -} - -export function precompile() { - return RawHandlebars.precompile.apply(this, arguments); -} - -export function compile() { - return RawHandlebars.compile.apply(this, arguments); -} - -export default RawHandlebars; diff --git a/app/assets/javascripts/discourse-common/package.json b/app/assets/javascripts/discourse-common/package.json new file mode 100644 index 0000000000..bdd317efb4 --- /dev/null +++ b/app/assets/javascripts/discourse-common/package.json @@ -0,0 +1,55 @@ +{ + "name": "discourse-common", + "version": "1.0.0", + "description": "Shared code between discourse apps", + "author": "Discourse", + "license": "GPLv2", + "keywords": [ + "ember-addon" + ], + "repository": "", + "license": "", + "author": "", + "scripts": { + "build": "ember build", + "lint:hbs": "ember-template-lint .", + "lint:js": "eslint .", + "start": "ember serve" + }, + "dependencies": { + "ember-cli-babel": "^7.13.0", + "ember-cli-htmlbars": "^4.2.0", + "ember-auto-import": "^1.5.3", + "handlebars": "^4.7.0" + }, + "devDependencies": { + "@ember/optional-features": "^1.1.0", + "@glimmer/component": "^1.0.0", + "babel-eslint": "^10.0.3", + "broccoli-asset-rev": "^3.0.0", + "ember-cli": "~3.15.2", + "ember-cli-dependency-checker": "^3.2.0", + "ember-cli-eslint": "^5.1.0", + "ember-cli-inject-live-reload": "^2.0.1", + "ember-cli-sri": "^2.1.1", + "ember-cli-template-lint": "^1.0.0-beta.3", + "ember-cli-uglify": "^3.0.0", + "ember-disable-prototype-extensions": "^1.1.3", + "ember-export-application-global": "^2.0.1", + "ember-load-initializers": "^2.1.1", + "ember-maybe-import-regenerator": "^0.1.6", + "ember-resolver": "^7.0.0", + "ember-source": "~3.15.0", + "ember-source-channel-url": "^2.0.1", + "ember-try": "^1.4.0", + "eslint-plugin-ember": "^7.7.1", + "eslint-plugin-node": "^10.0.0", + "loader.js": "^4.7.0" + }, + "engines": { + "node": "8.* || >= 10.*" + }, + "ember": { + "edition": "octane" + } +} diff --git a/app/assets/javascripts/discourse-common/utils/decorators.js b/app/assets/javascripts/discourse-common/utils/decorators.js deleted file mode 100644 index 36e537a063..0000000000 --- a/app/assets/javascripts/discourse-common/utils/decorators.js +++ /dev/null @@ -1,80 +0,0 @@ -import handleDescriptor from "ember-addons/utils/handle-descriptor"; -import isDescriptor from "ember-addons/utils/is-descriptor"; -import extractValue from "ember-addons/utils/extract-value"; -import { schedule, next } from "@ember/runloop"; - -export default function discourseComputedDecorator(...params) { - // determine if user called as @discourseComputed('blah', 'blah') or @discourseComputed - if (isDescriptor(params[params.length - 1])) { - return handleDescriptor(...arguments); - } else { - return function(/* target, key, desc */) { - return handleDescriptor(...arguments, params); - }; - } -} - -export function afterRender(target, name, descriptor) { - const originalFunction = descriptor.value; - descriptor.value = function() { - next(() => { - schedule("afterRender", () => { - if (this.element && !this.isDestroying && !this.isDestroyed) { - return originalFunction.apply(this, arguments); - } - }); - }); - }; -} - -export function readOnly(target, name, desc) { - return { - writable: false, - enumerable: desc.enumerable, - configurable: desc.configurable, - initializer: function() { - var value = extractValue(desc); - return value.readOnly(); - } - }; -} - -import decoratorAlias from "ember-addons/decorator-alias"; - -/* eslint-disable */ -export var on = decoratorAlias(Ember.on, "Can not `on` without event names"); -export var observes = decoratorAlias( - Ember.observer, - "Can not `observe` without property names" -); - -import macroAlias from "ember-addons/macro-alias"; - -export var alias = macroAlias(Ember.computed.alias); -export var and = macroAlias(Ember.computed.and); -export var bool = macroAlias(Ember.computed.bool); -export var collect = macroAlias(Ember.computed.collect); -export var empty = macroAlias(Ember.computed.empty); -export var equal = macroAlias(Ember.computed.equal); -export var filter = macroAlias(Ember.computed.filter); -export var filterBy = macroAlias(Ember.computed.filterBy); -export var gt = macroAlias(Ember.computed.gt); -export var gte = macroAlias(Ember.computed.gte); -export var lt = macroAlias(Ember.computed.lt); -export var lte = macroAlias(Ember.computed.lte); -export var map = macroAlias(Ember.computed.map); -export var mapBy = macroAlias(Ember.computed.mapBy); -export var match = macroAlias(Ember.computed.match); -export var max = macroAlias(Ember.computed.max); -export var min = macroAlias(Ember.computed.min); -export var none = macroAlias(Ember.computed.none); -export var not = macroAlias(Ember.computed.not); -export var notEmpty = macroAlias(Ember.computed.notEmpty); -export var oneWay = macroAlias(Ember.computed.oneWay); -export var or = macroAlias(Ember.computed.or); -export var reads = macroAlias(Ember.computed.reads); -export var setDiff = macroAlias(Ember.computed.setDiff); -export var sort = macroAlias(Ember.computed.sort); -export var sum = macroAlias(Ember.computed.sum); -export var union = macroAlias(Ember.computed.union); -export var uniq = macroAlias(Ember.computed.uniq); diff --git a/app/assets/javascripts/discourse-common/vendor/.gitkeep b/app/assets/javascripts/discourse-common/vendor/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/assets/javascripts/discourse-common/yarn.lock b/app/assets/javascripts/discourse-common/yarn.lock new file mode 100644 index 0000000000..fc099710ca --- /dev/null +++ b/app/assets/javascripts/discourse-common/yarn.lock @@ -0,0 +1,10485 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" + integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== + dependencies: + "@babel/highlight" "^7.8.3" + +"@babel/compat-data@^7.8.6", "@babel/compat-data@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.9.0.tgz#04815556fc90b0c174abd2c0c1bb966faa036a6c" + integrity sha512-zeFQrr+284Ekvd9e7KAX954LkapWiOmQtsfHirhxqfdlX6MEC32iRE+pqUGlYIBchdevaCwvzxWGSy/YBNI85g== + dependencies: + browserslist "^4.9.1" + invariant "^2.2.4" + semver "^5.5.0" + +"@babel/core@^7.1.6", "@babel/core@^7.2.2", "@babel/core@^7.3.4", "@babel/core@^7.7.2", "@babel/core@^7.8.3", "@babel/core@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" + integrity sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.0" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helpers" "^7.9.0" + "@babel/parser" "^7.9.0" + "@babel/template" "^7.8.6" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.9.0", "@babel/generator@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.5.tgz#27f0917741acc41e6eaaced6d68f96c3fa9afaf9" + integrity sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ== + dependencies: + "@babel/types" "^7.9.5" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz#60bc0bc657f63a0924ff9a4b4a0b24a13cf4deee" + integrity sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz#c84097a427a061ac56a1c30ebf54b7b22d241503" + integrity sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-compilation-targets@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz#dac1eea159c0e4bd46e309b5a1b04a66b53c1dde" + integrity sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw== + dependencies: + "@babel/compat-data" "^7.8.6" + browserslist "^4.9.1" + invariant "^2.2.4" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/helper-create-class-features-plugin@^7.5.5", "@babel/helper-create-class-features-plugin@^7.8.3": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.9.5.tgz#79753d44017806b481017f24b02fd4113c7106ea" + integrity sha512-IipaxGaQmW4TfWoXdqjY0TzoXQ1HRS0kPpEgvjosb3u7Uedcq297xFqDQiCcQtRRwzIMif+N1MLVI8C5a4/PAA== + dependencies: + "@babel/helper-function-name" "^7.9.5" + "@babel/helper-member-expression-to-functions" "^7.8.3" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-split-export-declaration" "^7.8.3" + +"@babel/helper-create-regexp-features-plugin@^7.8.3", "@babel/helper-create-regexp-features-plugin@^7.8.8": + version "7.8.8" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz#5d84180b588f560b7864efaeea89243e58312087" + integrity sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-regex" "^7.8.3" + regexpu-core "^4.7.0" + +"@babel/helper-define-map@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz#a0655cad5451c3760b726eba875f1cd8faa02c15" + integrity sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g== + dependencies: + "@babel/helper-function-name" "^7.8.3" + "@babel/types" "^7.8.3" + lodash "^4.17.13" + +"@babel/helper-explode-assignable-expression@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz#a728dc5b4e89e30fc2dfc7d04fa28a930653f982" + integrity sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw== + dependencies: + "@babel/traverse" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-function-name@^7.8.3", "@babel/helper-function-name@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz#2b53820d35275120e1874a82e5aabe1376920a5c" + integrity sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw== + dependencies: + "@babel/helper-get-function-arity" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/types" "^7.9.5" + +"@babel/helper-get-function-arity@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" + integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-hoist-variables@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz#1dbe9b6b55d78c9b4183fc8cdc6e30ceb83b7134" + integrity sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-member-expression-to-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz#659b710498ea6c1d9907e0c73f206eee7dadc24c" + integrity sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz#7fe39589b39c016331b6b8c3f441e8f0b1419498" + integrity sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-transforms@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz#43b34dfe15961918707d247327431388e9fe96e5" + integrity sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-simple-access" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/template" "^7.8.6" + "@babel/types" "^7.9.0" + lodash "^4.17.13" + +"@babel/helper-optimise-call-expression@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz#7ed071813d09c75298ef4f208956006b6111ecb9" + integrity sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670" + integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ== + +"@babel/helper-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.8.3.tgz#139772607d51b93f23effe72105b319d2a4c6965" + integrity sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ== + dependencies: + lodash "^4.17.13" + +"@babel/helper-remap-async-to-generator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz#273c600d8b9bf5006142c1e35887d555c12edd86" + integrity sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-wrap-function" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-replace-supers@^7.8.3", "@babel/helper-replace-supers@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8" + integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.8.3" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/traverse" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/helper-simple-access@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz#7f8109928b4dab4654076986af575231deb639ae" + integrity sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw== + dependencies: + "@babel/template" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helper-split-export-declaration@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" + integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-validator-identifier@^7.9.0", "@babel/helper-validator-identifier@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" + integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g== + +"@babel/helper-wrap-function@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz#9dbdb2bb55ef14aaa01fe8c99b629bd5352d8610" + integrity sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ== + dependencies: + "@babel/helper-function-name" "^7.8.3" + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.8.3" + "@babel/types" "^7.8.3" + +"@babel/helpers@^7.9.0": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.2.tgz#b42a81a811f1e7313b88cba8adc66b3d9ae6c09f" + integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA== + dependencies: + "@babel/template" "^7.8.3" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + +"@babel/highlight@^7.8.3": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" + integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== + dependencies: + "@babel/helper-validator-identifier" "^7.9.0" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.3.4", "@babel/parser@^7.4.5", "@babel/parser@^7.7.0", "@babel/parser@^7.8.6", "@babel/parser@^7.9.0": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8" + integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA== + +"@babel/plugin-proposal-async-generator-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz#bad329c670b382589721b27540c7d288601c6e6f" + integrity sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-remap-async-to-generator" "^7.8.3" + "@babel/plugin-syntax-async-generators" "^7.8.0" + +"@babel/plugin-proposal-class-properties@^7.1.0", "@babel/plugin-proposal-class-properties@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz#5e06654af5cd04b608915aada9b2a6788004464e" + integrity sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-proposal-decorators@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.8.3.tgz#2156860ab65c5abf068c3f67042184041066543e" + integrity sha512-e3RvdvS4qPJVTe288DlXjwKflpfy1hr0j5dz5WpIYYeP7vQZg2WfAEIp8k5/Lwis/m5REXEteIz6rrcDtXXG7w== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-decorators" "^7.8.3" + +"@babel/plugin-proposal-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz#38c4fe555744826e97e2ae930b0fb4cc07e66054" + integrity sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + +"@babel/plugin-proposal-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz#da5216b238a98b58a1e05d6852104b10f9a70d6b" + integrity sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.0" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz#e4572253fdeed65cddeecfdab3f928afeb2fd5d2" + integrity sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + +"@babel/plugin-proposal-numeric-separator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz#5d6769409699ec9b3b68684cd8116cedff93bad8" + integrity sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + +"@babel/plugin-proposal-object-rest-spread@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.5.tgz#3fd65911306d8746014ec0d0cf78f0e39a149116" + integrity sha512-VP2oXvAf7KCYTthbUHwBlewbl1Iq059f6seJGsxMizaCdgHIeczOr7FBqELhSqfkIl04Fi8okzWzl63UKbQmmg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.9.5" + +"@babel/plugin-proposal-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz#9dee96ab1650eed88646ae9734ca167ac4a9c5c9" + integrity sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + +"@babel/plugin-proposal-optional-chaining@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz#31db16b154c39d6b8a645292472b98394c292a58" + integrity sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + +"@babel/plugin-proposal-unicode-property-regex@^7.4.4", "@babel/plugin-proposal-unicode-property-regex@^7.8.3": + version "7.8.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz#ee3a95e90cdc04fe8cd92ec3279fa017d68a0d1d" + integrity sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.8" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-async-generators@^7.8.0": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-decorators@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.8.3.tgz#8d2c15a9f1af624b0025f961682a9d53d3001bda" + integrity sha512-8Hg4dNNT9/LcA1zQlfwuKR8BUc/if7Q7NkTam9sGTcJphLwpf2g4S42uhspQrIrR+dpzE0dtTqBVFoHl8GtnnQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-dynamic-import@^7.2.0", "@babel/plugin-syntax-dynamic-import@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-json-strings@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.0", "@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz#0e3fb63e09bea1b11e96467271c8308007e7c41f" + integrity sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-object-rest-spread@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz#3acdece695e6b13aaf57fc291d1a800950c71391" + integrity sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-typescript@^7.2.0", "@babel/plugin-syntax-typescript@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.8.3.tgz#c1f659dda97711a569cef75275f7e15dcaa6cabc" + integrity sha512-GO1MQ/SGGGoiEXY0e0bSpHimJvxqB7lktLLIq2pv8xG7WZ8IMEle74jIe1FhprHBWjwjZtXHkycDLZXIWM5Wfg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-arrow-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz#82776c2ed0cd9e1a49956daeb896024c9473b8b6" + integrity sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-async-to-generator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz#4308fad0d9409d71eafb9b1a6ee35f9d64b64086" + integrity sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-remap-async-to-generator" "^7.8.3" + +"@babel/plugin-transform-block-scoped-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz#437eec5b799b5852072084b3ae5ef66e8349e8a3" + integrity sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-block-scoping@^7.6.2", "@babel/plugin-transform-block-scoping@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz#97d35dab66857a437c166358b91d09050c868f3a" + integrity sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + lodash "^4.17.13" + +"@babel/plugin-transform-classes@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.5.tgz#800597ddb8aefc2c293ed27459c1fcc935a26c2c" + integrity sha512-x2kZoIuLC//O5iA7PEvecB105o7TLzZo8ofBVhP79N+DO3jaX+KYfww9TQcfBEZD0nikNyYcGB1IKtRq36rdmg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-define-map" "^7.8.3" + "@babel/helper-function-name" "^7.9.5" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-split-export-declaration" "^7.8.3" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz#96d0d28b7f7ce4eb5b120bb2e0e943343c86f81b" + integrity sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-destructuring@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.9.5.tgz#72c97cf5f38604aea3abf3b935b0e17b1db76a50" + integrity sha512-j3OEsGel8nHL/iusv/mRd5fYZ3DrOxWC82x0ogmdN/vHfAP4MYw+AFKYanzWlktNwikKvlzUV//afBW5FTp17Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-dotall-regex@^7.4.4", "@babel/plugin-transform-dotall-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz#c3c6ec5ee6125c6993c5cbca20dc8621a9ea7a6e" + integrity sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-duplicate-keys@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz#8d12df309aa537f272899c565ea1768e286e21f1" + integrity sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-exponentiation-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz#581a6d7f56970e06bf51560cd64f5e947b70d7b7" + integrity sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-for-of@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz#0f260e27d3e29cd1bb3128da5e76c761aa6c108e" + integrity sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-function-name@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz#279373cb27322aaad67c2683e776dfc47196ed8b" + integrity sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ== + dependencies: + "@babel/helper-function-name" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz#aef239823d91994ec7b68e55193525d76dbd5dc1" + integrity sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-member-expression-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz#963fed4b620ac7cbf6029c755424029fa3a40410" + integrity sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-modules-amd@^7.5.0", "@babel/plugin-transform-modules-amd@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz#19755ee721912cf5bb04c07d50280af3484efef4" + integrity sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q== + dependencies: + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + babel-plugin-dynamic-import-node "^2.3.0" + +"@babel/plugin-transform-modules-commonjs@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz#e3e72f4cbc9b4a260e30be0ea59bdf5a39748940" + integrity sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g== + dependencies: + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-simple-access" "^7.8.3" + babel-plugin-dynamic-import-node "^2.3.0" + +"@babel/plugin-transform-modules-systemjs@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz#e9fd46a296fc91e009b64e07ddaa86d6f0edeb90" + integrity sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ== + dependencies: + "@babel/helper-hoist-variables" "^7.8.3" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + babel-plugin-dynamic-import-node "^2.3.0" + +"@babel/plugin-transform-modules-umd@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz#e909acae276fec280f9b821a5f38e1f08b480697" + integrity sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ== + dependencies: + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz#a2a72bffa202ac0e2d0506afd0939c5ecbc48c6c" + integrity sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.3" + +"@babel/plugin-transform-new-target@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz#60cc2ae66d85c95ab540eb34babb6434d4c70c43" + integrity sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-object-assign@^7.2.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.8.3.tgz#dc3b8dd50ef03837868a37b7df791f64f288538e" + integrity sha512-i3LuN8tPDqUCRFu3dkzF2r1Nx0jp4scxtm7JxtIqI9he9Vk20YD+/zshdzR9JLsoBMlJlNR82a62vQExNEVx/Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-object-super@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz#ebb6a1e7a86ffa96858bd6ac0102d65944261725" + integrity sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.3" + +"@babel/plugin-transform-parameters@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.5.tgz#173b265746f5e15b2afe527eeda65b73623a0795" + integrity sha512-0+1FhHnMfj6lIIhVvS4KGQJeuhe1GI//h5uptK4PvLt+BGBxsoUJbd3/IW002yk//6sZPlFgsG1hY6OHLcy6kA== + dependencies: + "@babel/helper-get-function-arity" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-property-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz#33194300d8539c1ed28c62ad5087ba3807b98263" + integrity sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-regenerator@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz#5e46a0dca2bee1ad8285eb0527e6abc9c37672f8" + integrity sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA== + dependencies: + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz#9a0635ac4e665d29b162837dd3cc50745dfdf1f5" + integrity sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-runtime@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.0.tgz#45468c0ae74cc13204e1d3b1f4ce6ee83258af0b" + integrity sha512-pUu9VSf3kI1OqbWINQ7MaugnitRss1z533436waNXp+0N3ur3zfut37sXiQMxkuCF4VUjwZucen/quskCh7NHw== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + resolve "^1.8.1" + semver "^5.5.1" + +"@babel/plugin-transform-shorthand-properties@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz#28545216e023a832d4d3a1185ed492bcfeac08c8" + integrity sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz#9c8ffe8170fdfb88b114ecb920b82fb6e95fe5e8" + integrity sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-sticky-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz#be7a1290f81dae767475452199e1f76d6175b100" + integrity sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-regex" "^7.8.3" + +"@babel/plugin-transform-template-literals@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz#7bfa4732b455ea6a43130adc0ba767ec0e402a80" + integrity sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-typeof-symbol@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz#ede4062315ce0aaf8a657a920858f1a2f35fc412" + integrity sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-transform-typescript@^7.9.0": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.9.4.tgz#4bb4dde4f10bbf2d787fce9707fb09b483e33359" + integrity sha512-yeWeUkKx2auDbSxRe8MusAG+n4m9BFY/v+lPjmQDgOFX5qnySkUY5oXzkp6FwPdsYqnKay6lorXYdC0n3bZO7w== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-syntax-typescript" "^7.8.3" + +"@babel/plugin-transform-typescript@~7.4.0": + version "7.4.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.4.5.tgz#ab3351ba35307b79981993536c93ff8be050ba28" + integrity sha512-RPB/YeGr4ZrFKNwfuQRlMf2lxoCUaU01MTw39/OFE/RiL8HDjtn68BwEPft1P7JN4akyEmjGWAMNldOV7o9V2g== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-typescript" "^7.2.0" + +"@babel/plugin-transform-typescript@~7.5.0": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.5.tgz#6d862766f09b2da1cb1f7d505fe2aedab6b7d4b8" + integrity sha512-pehKf4m640myZu5B2ZviLaiBlxMCjSZ1qTEO459AXKX5GnPueyulJeCqZFs1nz/Ya2dDzXQ1NxZ/kKNWyD4h6w== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.5.5" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-typescript" "^7.2.0" + +"@babel/plugin-transform-unicode-regex@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz#0cef36e3ba73e5c57273effb182f46b91a1ecaad" + integrity sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/polyfill@^7.8.3", "@babel/polyfill@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.8.7.tgz#151ec24c7135481336168c3bd8b8bf0cf91c032f" + integrity sha512-LeSfP9bNZH2UOZgcGcZ0PIHUt1ZuHub1L3CVmEyqLxCeDLm4C5Gi8jRH8ZX2PNpDhQCo0z6y/+DIs2JlliXW8w== + dependencies: + core-js "^2.6.5" + regenerator-runtime "^0.13.4" + +"@babel/preset-env@^7.0.0", "@babel/preset-env@^7.9.0": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.9.5.tgz#8ddc76039bc45b774b19e2fc548f6807d8a8919f" + integrity sha512-eWGYeADTlPJH+wq1F0wNfPbVS1w1wtmMJiYk55Td5Yu28AsdR9AsC97sZ0Qq8fHqQuslVSIYSGJMcblr345GfQ== + dependencies: + "@babel/compat-data" "^7.9.0" + "@babel/helper-compilation-targets" "^7.8.7" + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-proposal-async-generator-functions" "^7.8.3" + "@babel/plugin-proposal-dynamic-import" "^7.8.3" + "@babel/plugin-proposal-json-strings" "^7.8.3" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-proposal-numeric-separator" "^7.8.3" + "@babel/plugin-proposal-object-rest-spread" "^7.9.5" + "@babel/plugin-proposal-optional-catch-binding" "^7.8.3" + "@babel/plugin-proposal-optional-chaining" "^7.9.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.8.3" + "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.8.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + "@babel/plugin-transform-arrow-functions" "^7.8.3" + "@babel/plugin-transform-async-to-generator" "^7.8.3" + "@babel/plugin-transform-block-scoped-functions" "^7.8.3" + "@babel/plugin-transform-block-scoping" "^7.8.3" + "@babel/plugin-transform-classes" "^7.9.5" + "@babel/plugin-transform-computed-properties" "^7.8.3" + "@babel/plugin-transform-destructuring" "^7.9.5" + "@babel/plugin-transform-dotall-regex" "^7.8.3" + "@babel/plugin-transform-duplicate-keys" "^7.8.3" + "@babel/plugin-transform-exponentiation-operator" "^7.8.3" + "@babel/plugin-transform-for-of" "^7.9.0" + "@babel/plugin-transform-function-name" "^7.8.3" + "@babel/plugin-transform-literals" "^7.8.3" + "@babel/plugin-transform-member-expression-literals" "^7.8.3" + "@babel/plugin-transform-modules-amd" "^7.9.0" + "@babel/plugin-transform-modules-commonjs" "^7.9.0" + "@babel/plugin-transform-modules-systemjs" "^7.9.0" + "@babel/plugin-transform-modules-umd" "^7.9.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.8.3" + "@babel/plugin-transform-new-target" "^7.8.3" + "@babel/plugin-transform-object-super" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.9.5" + "@babel/plugin-transform-property-literals" "^7.8.3" + "@babel/plugin-transform-regenerator" "^7.8.7" + "@babel/plugin-transform-reserved-words" "^7.8.3" + "@babel/plugin-transform-shorthand-properties" "^7.8.3" + "@babel/plugin-transform-spread" "^7.8.3" + "@babel/plugin-transform-sticky-regex" "^7.8.3" + "@babel/plugin-transform-template-literals" "^7.8.3" + "@babel/plugin-transform-typeof-symbol" "^7.8.4" + "@babel/plugin-transform-unicode-regex" "^7.8.3" + "@babel/preset-modules" "^0.1.3" + "@babel/types" "^7.9.5" + browserslist "^4.9.1" + core-js-compat "^3.6.2" + invariant "^2.2.2" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/preset-modules@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72" + integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/runtime@^7.8.4", "@babel/runtime@^7.9.0": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" + integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.8.3", "@babel/template@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" + integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/parser" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/traverse@^7.1.6", "@babel/traverse@^7.2.4", "@babel/traverse@^7.3.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.5.tgz#6e7c56b44e2ac7011a948c21e283ddd9d9db97a2" + integrity sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.5" + "@babel/helper-function-name" "^7.9.5" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/parser" "^7.9.0" + "@babel/types" "^7.9.5" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/types@^7.1.6", "@babel/types@^7.3.2", "@babel/types@^7.3.4", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0", "@babel/types@^7.9.5": + version "7.9.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.5.tgz#89231f82915a8a566a703b3b20133f73da6b9444" + integrity sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg== + dependencies: + "@babel/helper-validator-identifier" "^7.9.5" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@cnakazawa/watch@^1.0.3": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" + integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== + dependencies: + exec-sh "^0.3.2" + minimist "^1.2.0" + +"@ember-data/rfc395-data@^0.0.4": + version "0.0.4" + resolved "https://registry.yarnpkg.com/@ember-data/rfc395-data/-/rfc395-data-0.0.4.tgz#ecb86efdf5d7733a76ff14ea651a1b0ed1f8a843" + integrity sha512-tGRdvgC9/QMQSuSuJV45xoyhI0Pzjm7A9o/MVVA3HakXIImJbbzx/k/6dO9CUEQXIyS2y0fW6C1XaYOG7rY0FQ== + +"@ember/edition-utils@^1.1.1", "@ember/edition-utils@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ember/edition-utils/-/edition-utils-1.2.0.tgz#a039f542dc14c8e8299c81cd5abba95e2459cfa6" + integrity sha512-VmVq/8saCaPdesQmftPqbFtxJWrzxNGSQ+e8x8LLe3Hjm36pJ04Q8LeORGZkAeOhldoUX9seLGmSaHeXkIqoog== + +"@ember/optional-features@^1.1.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@ember/optional-features/-/optional-features-1.3.0.tgz#d7da860417b85a56cec88419f30da5ee1dde2756" + integrity sha512-Lrfojy4xKwTX+J4EAylmxZY2TO6bQtP4Lg5C8/z2priVqiT0X5fVB1+4WQCJbRBetctO1lMDnqjmhWCVKB8bmQ== + dependencies: + chalk "^3.0.0" + ember-cli-version-checker "^3.1.3" + glob "^7.1.6" + inquirer "^7.0.1" + mkdirp "^0.5.1" + silent-error "^1.1.1" + util.promisify "^1.0.0" + +"@ember/test-helpers@^1.7.1": + version "1.7.1" + resolved "https://registry.yarnpkg.com/@ember/test-helpers/-/test-helpers-1.7.1.tgz#cc22a954b3b46856518f034bd492a74e0482389f" + integrity sha512-+ioumnanSRJzZ0ZH30FIkB0r41UhVyuWQ9R9Yp1phDWJQDLumxg+25WDr40relwcH6z0Cn6LIEzeTVujO/0Rww== + dependencies: + broccoli-debug "^0.6.5" + broccoli-funnel "^2.0.2" + ember-assign-polyfill "^2.6.0" + ember-cli-babel "^7.7.3" + ember-cli-htmlbars-inline-precompile "^2.1.0" + ember-test-waiters "^1.1.1" + +"@embroider/core@0.4.3", "@embroider/core@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@embroider/core/-/core-0.4.3.tgz#117973b9761d68aee14d820bbaefeb05d5984ba8" + integrity sha512-n24WU/dGuGDqZrljWoX8raK2wFX3R8iJG0rfCWx+1kW87IvB+ZgS3j4KiZ/S788BA07udrYsrgecYnciG2bBMg== + dependencies: + "@babel/core" "^7.2.2" + "@babel/parser" "^7.3.4" + "@babel/plugin-syntax-dynamic-import" "^7.2.0" + "@babel/traverse" "^7.3.4" + "@babel/types" "^7.3.4" + "@embroider/macros" "0.4.3" + assert-never "^1.1.0" + babel-plugin-syntax-dynamic-import "^6.18.0" + broccoli-persistent-filter "^2.2.2" + broccoli-plugin "^1.3.0" + broccoli-source "^1.1.0" + debug "^3.1.0" + fast-sourcemap-concat "^1.4.0" + filesize "^4.1.2" + fs-extra "^7.0.1" + fs-tree-diff "^2.0.0" + handlebars "^4.0.11" + js-string-escape "^1.0.1" + jsdom "^12.0.0" + json-stable-stringify "^1.0.1" + lodash "^4.17.10" + pkg-up "^2.0.0" + resolve "^1.8.1" + resolve-package-path "^1.2.2" + semver "^5.5.0" + strip-bom "^3.0.0" + typescript-memoize "^1.0.0-alpha.3" + walk-sync "^1.1.3" + +"@embroider/macros@0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@embroider/macros/-/macros-0.4.3.tgz#ea5604b8bd578520f15886a428a6c4fa9481abc0" + integrity sha512-vq/Ny2ULpKxq60Sv5usSrz651dXFM5phP/O5G5MWDY8YOodIkRLGqtub34sB0OmwxpCuTntUzl9P/I4wkyQ3Kw== + dependencies: + "@babel/core" "^7.2.2" + "@babel/traverse" "^7.2.4" + "@babel/types" "^7.3.2" + "@embroider/core" "0.4.3" + resolve "^1.8.1" + semver "^5.6.0" + +"@glimmer/component@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@glimmer/component/-/component-1.0.0.tgz#f9052c8e99fb7b3d48d27c65891c5f0e59084a82" + integrity sha512-1ERZYNLZRuC8RYbcfkJeAWn3Ly7W2VdoHLQIHCmhQH/m7ubkNOdLQcTnUzje7OnRUs9EJ6DjfoN57XRX9Ux4rA== + dependencies: + "@glimmer/di" "^0.1.9" + "@glimmer/env" "^0.1.7" + "@glimmer/util" "^0.44.0" + broccoli-file-creator "^2.1.1" + broccoli-merge-trees "^3.0.2" + ember-cli-babel "^7.7.3" + ember-cli-get-component-path-option "^1.0.0" + ember-cli-is-package-missing "^1.0.0" + ember-cli-normalize-entity-name "^1.0.0" + ember-cli-path-utils "^1.0.0" + ember-cli-string-utils "^1.1.0" + ember-cli-typescript "3.0.0" + ember-compatibility-helpers "^1.1.2" + +"@glimmer/di@^0.1.9": + version "0.1.11" + resolved "https://registry.yarnpkg.com/@glimmer/di/-/di-0.1.11.tgz#a6878c07a13a2c2c76fcde598a5c97637bfc4280" + integrity sha1-poeMB6E6LCx2/N5ZilyXY3v8QoA= + +"@glimmer/env@0.1.7", "@glimmer/env@^0.1.7": + version "0.1.7" + resolved "https://registry.yarnpkg.com/@glimmer/env/-/env-0.1.7.tgz#fd2d2b55a9029c6b37a6c935e8c8871ae70dfa07" + integrity sha1-/S0rVakCnGs3psk16MiHGucN+gc= + +"@glimmer/interfaces@^0.47.9": + version "0.47.9" + resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.47.9.tgz#4c50b5343815045318bba38915f780ae39f14590" + integrity sha512-xne80DHkPC70u08LKV9g0+PboAmIw0A+vDXjJXMrDoRcNzCR4dXR6nvKD/Een+wbwwBaRawCIn45Rnk5+Dyvrg== + dependencies: + "@simple-dom/interface" "^1.4.0" + +"@glimmer/syntax@^0.47.9": + version "0.47.9" + resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.47.9.tgz#f3d141efc97f601928335771721d1f27eb1ed7d2" + integrity sha512-ld3x2bTkAr/BXOkI1b3cDVBwMl0BTYtBNKODks0Fi/1DLx+F1jl4abpKJ5cww1k2iQ75jgG31IhBwb7YC2PmFA== + dependencies: + "@glimmer/interfaces" "^0.47.9" + "@glimmer/util" "^0.47.9" + handlebars "^4.5.1" + simple-html-tokenizer "^0.5.9" + +"@glimmer/util@^0.44.0": + version "0.44.0" + resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.44.0.tgz#45df98d73812440206ae7bda87cfe04aaae21ed9" + integrity sha512-duAsm30uVK9jSysElCbLyU6QQYO2X9iLDLBIBUcCqck9qN1o3tK2qWiHbGK5d6g8E2AJ4H88UrfElkyaJlGrwg== + +"@glimmer/util@^0.47.9": + version "0.47.9" + resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.47.9.tgz#ad3085eba3975bcbc74d28aefc871becbe800417" + integrity sha512-MJEumozi3TKmx+kzTpqPdC0jLEIuWSS3JNdBXceqTGRZQGmE5Zxqd8ydH5KOYpsKSfURHGCi2vU6+X/Q4z2b6g== + dependencies: + "@glimmer/env" "0.1.7" + "@simple-dom/interface" "^1.4.0" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.scandir@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" + integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== + dependencies: + "@nodelib/fs.stat" "2.0.3" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" + integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" + integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== + dependencies: + "@nodelib/fs.scandir" "2.1.3" + fastq "^1.6.0" + +"@simple-dom/interface@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@simple-dom/interface/-/interface-1.4.0.tgz#e8feea579232017f89b0138e2726facda6fbb71f" + integrity sha512-l5qumKFWU0S+4ZzMaLXFU8tQZsicHEMEyAxI5kDFGhJsRqDwe0a7/iPA/GdxlGyDKseQQAgIz5kzU7eXTrlSpA== + +"@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== + +"@types/body-parser@*": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" + integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/chai-as-promised@^7.1.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.2.tgz#2f564420e81eaf8650169e5a3a6b93e096e5068b" + integrity sha512-PO2gcfR3Oxa+u0QvECLe1xKXOqYTzCmWf0FhLhjREoW3fPAVamjihL7v1MOVLJLsnAMdLcjkfrs01yvDMwVK4Q== + dependencies: + "@types/chai" "*" + +"@types/chai@*", "@types/chai@^4.2.9": + version "4.2.11" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.11.tgz#d3614d6c5f500142358e6ed24e1bf16657536c50" + integrity sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw== + +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + +"@types/connect@*": + version "3.4.33" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" + integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== + dependencies: + "@types/node" "*" + +"@types/events@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" + integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== + +"@types/express-serve-static-core@*": + version "4.17.5" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.5.tgz#a00ac7dadd746ae82477443e4d480a6a93ea083c" + integrity sha512-578YH5Lt88AKoADy0b2jQGwJtrBxezXtVe/MBqWXKZpqx91SnC0pVkVCcxcytz3lWW+cHBYDi3Ysh0WXc+rAYw== + dependencies: + "@types/node" "*" + "@types/range-parser" "*" + +"@types/express@^4.17.2": + version "4.17.6" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.6.tgz#6bce49e49570507b86ea1b07b806f04697fac45e" + integrity sha512-n/mr9tZI83kd4azlPG5y997C/M4DNABK9yErhFM6hKdym4kkmd9j0vtsJyjFIwfRBxtrxZtAfGZCNRIBMFLK5w== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/fs-extra@^5.0.5": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.1.0.tgz#2a325ef97901504a3828718c390d34b8426a10a1" + integrity sha512-AInn5+UBFIK9FK5xc9yP5e3TQSPNNgjHByqYcj9g5elVBnDQcQL7PlO1CIRy2gWlbwK7UPYqi7vRvFA44dCmYQ== + dependencies: + "@types/node" "*" + +"@types/glob@*", "@types/glob@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" + integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== + dependencies: + "@types/events" "*" + "@types/minimatch" "*" + "@types/node" "*" + +"@types/mime@*": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d" + integrity sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw== + +"@types/minimatch@*", "@types/minimatch@^3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + +"@types/node@*": + version "13.13.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.4.tgz#1581d6c16e3d4803eb079c87d4ac893ee7501c2c" + integrity sha512-x26ur3dSXgv5AwKS0lNfbjpCakGIduWU1DU91Zz58ONRWrIKGunmZBNv4P7N+e27sJkiGDsw/3fT4AtsqQBrBA== + +"@types/qs@*": + version "6.9.1" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.1.tgz#937fab3194766256ee09fcd40b781740758617e7" + integrity sha512-lhbQXx9HKZAPgBkISrBcmAcMpZsmpe/Cd/hY7LGZS5OfkySUBItnPZHgQPssWYUET8elF+yCFBbP1Q0RZPTdaw== + +"@types/range-parser@*": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" + integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== + +"@types/rimraf@^2.0.2": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-2.0.4.tgz#403887b0b53c6100a6c35d2ab24f6ccc042fec46" + integrity sha512-8gBudvllD2A/c0CcEX/BivIDorHFt5UI5m46TsNj8DjWCCTTZT74kEe4g+QsY7P/B9WdO98d82zZgXO/RQzu2Q== + dependencies: + "@types/glob" "*" + "@types/node" "*" + +"@types/serve-static@*": + version "1.13.3" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.3.tgz#eb7e1c41c4468272557e897e9171ded5e2ded9d1" + integrity sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g== + dependencies: + "@types/express-serve-static-core" "*" + "@types/mime" "*" + +"@types/symlink-or-copy@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@types/symlink-or-copy/-/symlink-or-copy-1.2.0.tgz#4151a81b4052c80bc2becbae09f3a9ec010a9c7a" + integrity sha512-Lja2xYuuf2B3knEsga8ShbOdsfNOtzT73GyJmZyY7eGl2+ajOqrs8yM5ze0fsSoYwvA6bw7/Qr7OZ7PEEmYwWg== + +"@webassemblyjs/ast@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace" + integrity sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA== + dependencies: + "@webassemblyjs/helper-module-context" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/wast-parser" "1.7.11" + +"@webassemblyjs/floating-point-hex-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz#a69f0af6502eb9a3c045555b1a6129d3d3f2e313" + integrity sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg== + +"@webassemblyjs/helper-api-error@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz#c7b6bb8105f84039511a2b39ce494f193818a32a" + integrity sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg== + +"@webassemblyjs/helper-buffer@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz#3122d48dcc6c9456ed982debe16c8f37101df39b" + integrity sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w== + +"@webassemblyjs/helper-code-frame@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz#cf8f106e746662a0da29bdef635fcd3d1248364b" + integrity sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw== + dependencies: + "@webassemblyjs/wast-printer" "1.7.11" + +"@webassemblyjs/helper-fsm@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz#df38882a624080d03f7503f93e3f17ac5ac01181" + integrity sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A== + +"@webassemblyjs/helper-module-context@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz#d874d722e51e62ac202476935d649c802fa0e209" + integrity sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg== + +"@webassemblyjs/helper-wasm-bytecode@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz#dd9a1e817f1c2eb105b4cf1013093cb9f3c9cb06" + integrity sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ== + +"@webassemblyjs/helper-wasm-section@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz#9c9ac41ecf9fbcfffc96f6d2675e2de33811e68a" + integrity sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + +"@webassemblyjs/ieee754@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz#c95839eb63757a31880aaec7b6512d4191ac640b" + integrity sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.7.11.tgz#d7267a1ee9c4594fd3f7e37298818ec65687db63" + integrity sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw== + dependencies: + "@xtuc/long" "4.2.1" + +"@webassemblyjs/utf8@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.7.11.tgz#06d7218ea9fdc94a6793aa92208160db3d26ee82" + integrity sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA== + +"@webassemblyjs/wasm-edit@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz#8c74ca474d4f951d01dbae9bd70814ee22a82005" + integrity sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/helper-wasm-section" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + "@webassemblyjs/wasm-opt" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + "@webassemblyjs/wast-printer" "1.7.11" + +"@webassemblyjs/wasm-gen@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz#9bbba942f22375686a6fb759afcd7ac9c45da1a8" + integrity sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/ieee754" "1.7.11" + "@webassemblyjs/leb128" "1.7.11" + "@webassemblyjs/utf8" "1.7.11" + +"@webassemblyjs/wasm-opt@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz#b331e8e7cef8f8e2f007d42c3a36a0580a7d6ca7" + integrity sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + +"@webassemblyjs/wasm-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz#6e3d20fa6a3519f6b084ef9391ad58211efb0a1a" + integrity sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-api-error" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/ieee754" "1.7.11" + "@webassemblyjs/leb128" "1.7.11" + "@webassemblyjs/utf8" "1.7.11" + +"@webassemblyjs/wast-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz#25bd117562ca8c002720ff8116ef9072d9ca869c" + integrity sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/floating-point-hex-parser" "1.7.11" + "@webassemblyjs/helper-api-error" "1.7.11" + "@webassemblyjs/helper-code-frame" "1.7.11" + "@webassemblyjs/helper-fsm" "1.7.11" + "@xtuc/long" "4.2.1" + +"@webassemblyjs/wast-printer@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz#c4245b6de242cb50a2cc950174fdbf65c78d7813" + integrity sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/wast-parser" "1.7.11" + "@xtuc/long" "4.2.1" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.1.tgz#5c85d662f76fa1d34575766c5dcd6615abcd30d8" + integrity sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g== + +abab@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" + integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-dynamic-import@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" + integrity sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg== + dependencies: + acorn "^5.0.0" + +acorn-globals@^4.3.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" + integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== + dependencies: + acorn "^6.0.1" + acorn-walk "^6.0.1" + +acorn-jsx@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" + integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== + +acorn-walk@^6.0.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" + integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== + +acorn@^5.0.0, acorn@^5.6.2: + version "5.7.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" + integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== + +acorn@^6.0.1, acorn@^6.0.2, acorn@^6.0.7: + version "6.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" + integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== + +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= + +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" + integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== + +ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.5.5, ajv@^6.9.1: + version "6.12.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" + integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +amd-name-resolver@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/amd-name-resolver/-/amd-name-resolver-1.2.0.tgz#fc41b3848824b557313897d71f8d5a0184fbe679" + integrity sha512-hlSTWGS1t6/xq5YCed7YALg7tKZL3rkl7UwEZ/eCIkn8JxmM6fU6Qs/1hwtjQqfuYxlffuUcgYEm0f5xP4YKaA== + dependencies: + ensure-posix-path "^1.0.1" + +amd-name-resolver@^1.2.1, amd-name-resolver@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/amd-name-resolver/-/amd-name-resolver-1.3.1.tgz#ffe71c683c6e7191fc4ae1bb3aaed15abea135d9" + integrity sha512-26qTEWqZQ+cxSYygZ4Cf8tsjDBLceJahhtewxtKZA3SRa4PluuqYCuheemDQD+7Mf5B7sr+zhTDWAHDh02a1Dw== + dependencies: + ensure-posix-path "^1.0.1" + object-hash "^1.3.1" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + +ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-escapes@^4.2.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" + integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== + dependencies: + type-fest "^0.11.0" + +ansi-html@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.0.0, ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + +ansi-to-html@^0.6.6: + version "0.6.14" + resolved "https://registry.yarnpkg.com/ansi-to-html/-/ansi-to-html-0.6.14.tgz#65fe6d08bba5dd9db33f44a20aec331e0010dad8" + integrity sha512-7ZslfB1+EnFSDO5Ju+ue5Y6It19DRnZXWv8jrGHgIlPna5Mh4jz7BV5jCbQneXNFurQcKoolaaAjHtgSBfOIuA== + dependencies: + entities "^1.1.2" + +ansicolors@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.2.1.tgz#be089599097b74a5c9c4a84a0cdbcdb62bd87aef" + integrity sha1-vgiVmQl7dKXJxKhKDNvNtivYeu8= + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +aot-test-generators@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/aot-test-generators/-/aot-test-generators-0.1.0.tgz#43f0f615f97cb298d7919c1b0b4e6b7310b03cd0" + integrity sha1-Q/D2Ffl8spjXkZwbC05rcxCwPNA= + dependencies: + jsesc "^2.5.0" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-to-error@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-to-error/-/array-to-error-1.1.1.tgz#d68812926d14097a205579a667eeaf1856a44c07" + integrity sha1-1ogSkm0UCXogVXmmZ+6vGFakTAc= + dependencies: + array-to-sentence "^1.1.0" + +array-to-sentence@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-to-sentence/-/array-to-sentence-1.1.0.tgz#c804956dafa53232495b205a9452753a258d39fc" + integrity sha1-yASVba+lMjJJWyBalFJ1OiWNOfw= + +array-union@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arraybuffer.slice@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" + integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-never@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.2.0.tgz#e6597ed9e357f7e62c074dfa7c71e30ed7b67a8b" + integrity sha512-61QPxh2lfV5j2dBsEtwhz8/sUj+baAIuCpQxeWorGeMxlTkbeyGyq7igxJB8yij1JdzUhyoiekNHMXrMYnkjvA== + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +ast-types@0.13.3: + version "0.13.3" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.3.tgz#50da3f28d17bdbc7969a3a2d83a0e4a72ae755a7" + integrity sha512-XTZ7xGML849LkQP86sWdQzfhwbt3YwIO6MqbX9mUNYY98VKaaVZP7YNNm70IpwecbkkxmfC5IYAzOQ/2p29zRA== + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +async-disk-cache@^1.2.1: + version "1.3.5" + resolved "https://registry.yarnpkg.com/async-disk-cache/-/async-disk-cache-1.3.5.tgz#cc6206ed79bb6982b878fc52e0505e4f52b62a02" + integrity sha512-VZpqfR0R7CEOJZ/0FOTgWq70lCrZyS1rkI8PXugDUkTKyyAUgZ2zQ09gLhMkEn+wN8LYeUTPxZdXtlX/kmbXKQ== + dependencies: + debug "^2.1.3" + heimdalljs "^0.2.3" + istextorbinary "2.1.0" + mkdirp "^0.5.0" + rimraf "^2.5.3" + rsvp "^3.0.18" + username-sync "^1.0.2" + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + +async-promise-queue@^1.0.3, async-promise-queue@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/async-promise-queue/-/async-promise-queue-1.0.5.tgz#cb23bce9fce903a133946a700cc85f27f09ea49d" + integrity sha512-xi0aQ1rrjPWYmqbwr18rrSKbSaXIeIwSd1J4KAgVfkq8utNbdZoht7GfvfY6swFUAMJ9obkc4WPJmtGwl+B8dw== + dependencies: + async "^2.4.1" + debug "^2.6.8" + +async@^2.4.1, async@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +async@~0.2.9: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E= + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" + integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== + +babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.26.0, babel-core@^6.26.3: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-eslint@^10.0.3: + version "10.1.0" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" + integrity sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" + eslint-visitor-keys "^1.0.0" + resolve "^1.12.0" + +babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-loader@^8.0.6: + version "8.1.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" + integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw== + dependencies: + find-cache-dir "^2.1.0" + loader-utils "^1.4.0" + mkdirp "^0.5.3" + pify "^4.0.1" + schema-utils "^2.6.5" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-debug-macros@^0.2.0, babel-plugin-debug-macros@^0.2.0-beta.6: + version "0.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-debug-macros/-/babel-plugin-debug-macros-0.2.0.tgz#0120ac20ce06ccc57bf493b667cf24b85c28da7a" + integrity sha512-Wpmw4TbhR3Eq2t3W51eBAQSdKlr+uAyF0GI4GtPfMCD12Y4cIdpKC9l0RjNTH/P9isFypSqqewMPm7//fnZlNA== + dependencies: + semver "^5.3.0" + +babel-plugin-debug-macros@^0.3.0, babel-plugin-debug-macros@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-debug-macros/-/babel-plugin-debug-macros-0.3.3.tgz#29c3449d663f61c7385f5b8c72d8015b069a5cb7" + integrity sha512-E+NI8TKpxJDBbVkdWkwHrKgJi696mnRL8XYrOPYw82veNHPDORM9WIQifl6TpIo8PNy2tU2skPqbfkmHXrHKQA== + dependencies: + semver "^5.3.0" + +babel-plugin-dynamic-import-node@^2.3.0: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + +babel-plugin-ember-data-packages-polyfill@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/babel-plugin-ember-data-packages-polyfill/-/babel-plugin-ember-data-packages-polyfill-0.1.2.tgz#21154c095ddc703722b1fb8bb06c126c0b6d77dc" + integrity sha512-kTHnOwoOXfPXi00Z8yAgyD64+jdSXk3pknnS7NlqnCKAU6YDkXZ4Y7irl66kaZjZn0FBBt0P4YOZFZk85jYOww== + dependencies: + "@ember-data/rfc395-data" "^0.0.4" + +babel-plugin-ember-modules-api-polyfill@^2.12.0, babel-plugin-ember-modules-api-polyfill@^2.6.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/babel-plugin-ember-modules-api-polyfill/-/babel-plugin-ember-modules-api-polyfill-2.12.0.tgz#a5e703205ba4e625a7fab9bb1aea64ef3222cf75" + integrity sha512-ZQU4quX0TJ1yYyosPy5PFigKdCFEVHJ6H0b3hwjxekIP9CDwzk0OhQuKhCOPti+d52VWjjCjxu2BrXEih29mFw== + dependencies: + ember-rfc176-data "^0.3.12" + +babel-plugin-filter-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-filter-imports/-/babel-plugin-filter-imports-3.0.0.tgz#a849683837ad29960da17492fb32789ab6b09a11" + integrity sha512-p/chjzVTgCxUqyLM0q/pfWVZS7IJTwGQMwNg0LOvuQpKiTftQgZDtkGB8XvETnUw19rRcL7bJCTopSwibTN2tA== + dependencies: + "@babel/types" "^7.4.0" + lodash "^4.17.11" + +babel-plugin-htmlbars-inline-precompile@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-htmlbars-inline-precompile/-/babel-plugin-htmlbars-inline-precompile-1.0.0.tgz#a9d2f6eaad8a3f3d361602de593a8cbef8179c22" + integrity sha512-4jvKEHR1bAX03hBDZ94IXsYCj3bwk9vYsn6ux6JZNL2U5pvzCWjqyrGahfsGNrhERyxw8IqcirOi9Q6WCo3dkQ== + +babel-plugin-htmlbars-inline-precompile@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-htmlbars-inline-precompile/-/babel-plugin-htmlbars-inline-precompile-3.0.1.tgz#e1e38a4087f446578e419a21c112530c8df02345" + integrity sha512-ZiFY0nQjtdMPGIDwp/5LYOs6rCr54QfcSV5nPbrA7C++Fv4Vb2Q/qrKYx78t+dwmARJztnOBlObFk4z8veHxNA== + +babel-plugin-module-resolver@^3.1.1, babel-plugin-module-resolver@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.2.0.tgz#ddfa5e301e3b9aa12d852a9979f18b37881ff5a7" + integrity sha512-tjR0GvSndzPew/Iayf4uICWZqjBwnlMWjSx6brryfQ81F9rxBVqwDJtFCV8oOs0+vJeefK9TmdZtkIFdFe1UnA== + dependencies: + find-babel-config "^1.1.0" + glob "^7.1.2" + pkg-up "^2.0.0" + reselect "^3.0.1" + resolve "^1.4.0" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= + +babel-plugin-syntax-dynamic-import@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + integrity sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo= + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= + +babel-plugin-transform-async-to-generator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ= + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + integrity sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM= + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + integrity sha1-rJl+YoXNGO1hdq22B9YCNErThGg= + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw= + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek= + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + integrity sha1-KrDJx/MJj6SJB3cruBP+QejeOg4= + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8= + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-polyfill@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" + integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM= + dependencies: + babel-runtime "^6.26.0" + core-js "^2.5.0" + regenerator-runtime "^0.10.5" + +babel-preset-env@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" + integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^3.2.6" + invariant "^2.2.2" + semver "^5.3.0" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + +backbone@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/backbone/-/backbone-1.4.0.tgz#54db4de9df7c3811c3f032f34749a4cd27f3bd12" + integrity sha512-RLmDrRXkVdouTg38jcgHhyQ/2zjg7a8E6sz2zxfz21Hh17xDJYUHBZimVIt5fUyS8vbfpeSmTL3gUjTEvUV3qQ== + dependencies: + underscore ">=1.8.3" + +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-arraybuffer@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= + +base64-js@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.2.tgz#024f0f72afa25b75f9c0ee73cd4f55ec1bed9784" + integrity sha1-Ak8Pcq+iW3X5wO5zzU9V7Bvtl4Q= + +base64-js@^1.0.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +base64id@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +basic-auth@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" + integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== + dependencies: + safe-buffer "5.1.2" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +better-assert@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI= + dependencies: + callsite "1.0.0" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +"binaryextensions@1 || 2": + version "2.2.0" + resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.2.0.tgz#e7c6ba82d4f5f5758c26078fe8eea28881233311" + integrity sha512-bHhs98rj/7i/RZpCSJ3uk55pLXOItjIrh2sRQZSM6OoktScX+LxJzvlU+FELp9j3TdcddTmmYArLSGptCTwjuw== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +blank-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/blank-object/-/blank-object-1.0.2.tgz#f990793fbe9a8c8dd013fb3219420bec81d5f4b9" + integrity sha1-+ZB5P76ajI3QE/syGUIL7IHV9Lk= + +blob@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" + integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== + +bluebird@^3.1.1, bluebird@^3.4.6, bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +body@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/body/-/body-5.1.0.tgz#e4ba0ce410a46936323367609ecb4e6553125069" + integrity sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk= + dependencies: + continuable-cache "^0.3.1" + error "^7.0.0" + raw-body "~1.1.0" + safe-json-parse "~1.0.1" + +bops@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/bops/-/bops-0.0.3.tgz#c5cbf6fea8be7401ca5ea6d1679e6c4e8b407c79" + integrity sha1-xcv2/qi+dAHKXqbRZ55sTotAfHk= + dependencies: + base64-js "0.0.2" + to-utf8 "0.0.1" + +bower-config@^1.4.1: + version "1.4.3" + resolved "https://registry.yarnpkg.com/bower-config/-/bower-config-1.4.3.tgz#3454fecdc5f08e7aa9cc6d556e492be0669689ae" + integrity sha512-MVyyUk3d1S7d2cl6YISViwJBc2VXCkxF5AUFykvN0PQj5FsUiMNSgAYTso18oRFfyZ6XEtjrgg9MAaufHbOwNw== + dependencies: + graceful-fs "^4.1.3" + minimist "^0.2.1" + mout "^1.0.0" + osenv "^0.1.3" + untildify "^2.1.0" + wordwrap "^0.0.3" + +bower-endpoint-parser@0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz#00b565adbfab6f2d35addde977e97962acbcb3f6" + integrity sha1-ALVlrb+rby01rd3pd+l5Yqy8s/Y= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +broccoli-amd-funnel@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/broccoli-amd-funnel/-/broccoli-amd-funnel-2.0.1.tgz#dbdbfd28841731342d538126567c25bea3f15310" + integrity sha512-VRE+0PYAN4jQfkIq3GKRj4U/4UV9rVpLan5ll6fVYV4ziVg4OEfR5GUnILEg++QtR4xSaugRxCPU5XJLDy3bNQ== + dependencies: + broccoli-plugin "^1.3.0" + symlink-or-copy "^1.2.0" + +broccoli-asset-rev@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/broccoli-asset-rev/-/broccoli-asset-rev-3.0.0.tgz#65a28c8a062d6ee2cffd91ed2a8309e0f8253ac6" + integrity sha512-gAHQZnwvtl74tGevUqGuWoyOdJUdMMv0TjGSMzbdyGImr9fZcnM6xmggDA8bUawrMto9NFi00ZtNUgA4dQiUBw== + dependencies: + broccoli-asset-rewrite "^2.0.0" + broccoli-filter "^1.2.2" + broccoli-persistent-filter "^1.4.3" + json-stable-stringify "^1.0.0" + minimatch "^3.0.4" + rsvp "^3.0.6" + +broccoli-asset-rewrite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/broccoli-asset-rewrite/-/broccoli-asset-rewrite-2.0.0.tgz#603c4a52d4c8987a2f681254436923ac0a9c94ab" + integrity sha512-dqhxdQpooNi7LHe8J9Jdxp6o3YPFWl4vQmint6zrsn2sVbOo+wpyiX3erUSt0IBtjNkAxqJjuvS375o2cLBHTA== + dependencies: + broccoli-filter "^1.2.3" + +broccoli-babel-transpiler@^6.5.0: + version "6.5.1" + resolved "https://registry.yarnpkg.com/broccoli-babel-transpiler/-/broccoli-babel-transpiler-6.5.1.tgz#a4afc8d3b59b441518eb9a07bd44149476e30738" + integrity sha512-w6GcnkxvHcNCte5FcLGEG1hUdQvlfvSN/6PtGWU/otg69Ugk8rUk51h41R0Ugoc+TNxyeFG1opRt2RlA87XzNw== + dependencies: + babel-core "^6.26.0" + broccoli-funnel "^2.0.1" + broccoli-merge-trees "^2.0.0" + broccoli-persistent-filter "^1.4.3" + clone "^2.0.0" + hash-for-dep "^1.2.3" + heimdalljs-logger "^0.1.7" + json-stable-stringify "^1.0.0" + rsvp "^4.8.2" + workerpool "^2.3.0" + +broccoli-babel-transpiler@^7.3.0, broccoli-babel-transpiler@^7.4.0: + version "7.4.0" + resolved "https://registry.yarnpkg.com/broccoli-babel-transpiler/-/broccoli-babel-transpiler-7.4.0.tgz#f3069f0f77e8017aa17e1e757dfb4a30de044182" + integrity sha512-DzPXQr1C+zOgzXG40wqPjtjSSa6wRKb+Ls45Qtq7Pn+GxL3/jIvQOBZi0/irZ5dlYVbRMEZiUnaIBIOha2ygIw== + dependencies: + "@babel/core" "^7.8.3" + "@babel/polyfill" "^7.8.3" + broccoli-funnel "^2.0.2" + broccoli-merge-trees "^3.0.2" + broccoli-persistent-filter "^2.2.1" + clone "^2.1.2" + hash-for-dep "^1.4.7" + heimdalljs-logger "^0.1.9" + json-stable-stringify "^1.0.1" + rsvp "^4.8.4" + workerpool "^3.1.1" + +broccoli-builder@^0.18.14: + version "0.18.14" + resolved "https://registry.yarnpkg.com/broccoli-builder/-/broccoli-builder-0.18.14.tgz#4b79e2f844de11a4e1b816c3f49c6df4776c312d" + integrity sha1-S3ni+ETeEaThuBbD9Jxt9HdsMS0= + dependencies: + broccoli-node-info "^1.1.0" + heimdalljs "^0.2.0" + promise-map-series "^0.2.1" + quick-temp "^0.1.2" + rimraf "^2.2.8" + rsvp "^3.0.17" + silent-error "^1.0.1" + +broccoli-caching-writer@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/broccoli-caching-writer/-/broccoli-caching-writer-2.3.1.tgz#b93cf58f9264f003075868db05774f4e7f25bd07" + integrity sha1-uTz1j5Jk8AMHWGjbBXdPTn8lvQc= + dependencies: + broccoli-kitchen-sink-helpers "^0.2.5" + broccoli-plugin "1.1.0" + debug "^2.1.1" + rimraf "^2.2.8" + rsvp "^3.0.17" + walk-sync "^0.2.5" + +broccoli-caching-writer@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/broccoli-caching-writer/-/broccoli-caching-writer-3.0.3.tgz#0bd2c96a9738d6a6ab590f07ba35c5157d7db476" + integrity sha1-C9LJapc41qarWQ8HujXFFX19tHY= + dependencies: + broccoli-kitchen-sink-helpers "^0.3.1" + broccoli-plugin "^1.2.1" + debug "^2.1.1" + rimraf "^2.2.8" + rsvp "^3.0.17" + walk-sync "^0.3.0" + +broccoli-clean-css@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/broccoli-clean-css/-/broccoli-clean-css-1.1.0.tgz#9db143d9af7e0ae79c26e3ac5a9bb2d720ea19fa" + integrity sha1-nbFD2a9+CuecJuOsWpuy1yDqGfo= + dependencies: + broccoli-persistent-filter "^1.1.6" + clean-css-promise "^0.1.0" + inline-source-map-comment "^1.0.5" + json-stable-stringify "^1.0.0" + +broccoli-concat@^3.2.2, broccoli-concat@^3.7.1, broccoli-concat@^3.7.4: + version "3.7.5" + resolved "https://registry.yarnpkg.com/broccoli-concat/-/broccoli-concat-3.7.5.tgz#223beda8c1184252cf08ae020a3d45ffa6a48218" + integrity sha512-rDs1Mej3Ej0Cy5yIO9oIQq5+BCv0opAwS2NW7M0BeCsAMeFM42Z/zacDUC6jKc5OV5wiHvGTyCPLnZkMe0h6kQ== + dependencies: + broccoli-debug "^0.6.5" + broccoli-kitchen-sink-helpers "^0.3.1" + broccoli-plugin "^1.3.0" + ensure-posix-path "^1.0.2" + fast-sourcemap-concat "^1.4.0" + find-index "^1.1.0" + fs-extra "^4.0.3" + fs-tree-diff "^0.5.7" + lodash.merge "^4.6.2" + lodash.omit "^4.1.0" + lodash.uniq "^4.2.0" + walk-sync "^0.3.2" + +broccoli-config-loader@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/broccoli-config-loader/-/broccoli-config-loader-1.0.1.tgz#d10aaf8ebc0cb45c1da5baa82720e1d88d28c80a" + integrity sha512-MDKYQ50rxhn+g17DYdfzfEM9DjTuSGu42Db37A8TQHQe8geYEcUZ4SQqZRgzdAI3aRQNlA1yBHJfOeGmOjhLIg== + dependencies: + broccoli-caching-writer "^3.0.3" + +broccoli-config-replace@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/broccoli-config-replace/-/broccoli-config-replace-1.1.2.tgz#6ea879d92a5bad634d11329b51fc5f4aafda9c00" + integrity sha1-bqh52SpbrWNNETKbUfxfSq/anAA= + dependencies: + broccoli-kitchen-sink-helpers "^0.3.1" + broccoli-plugin "^1.2.0" + debug "^2.2.0" + fs-extra "^0.24.0" + +broccoli-debug@^0.6.4, broccoli-debug@^0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/broccoli-debug/-/broccoli-debug-0.6.5.tgz#164a5cdafd8936e525e702bf8f91f39d758e2e78" + integrity sha512-RIVjHvNar9EMCLDW/FggxFRXqpjhncM/3qq87bn/y+/zR9tqEkHvTqbyOc4QnB97NO2m6342w4wGkemkaeOuWg== + dependencies: + broccoli-plugin "^1.2.1" + fs-tree-diff "^0.5.2" + heimdalljs "^0.2.1" + heimdalljs-logger "^0.1.7" + symlink-or-copy "^1.1.8" + tree-sync "^1.2.2" + +broccoli-file-creator@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/broccoli-file-creator/-/broccoli-file-creator-2.1.1.tgz#7351dd2496c762cfce7736ce9b49e3fce0c7b7db" + integrity sha512-YpjOExWr92C5vhnK0kmD81kM7U09kdIRZk9w4ZDCDHuHXW+VE/x6AGEOQQW3loBQQ6Jk+k+TSm8dESy4uZsnjw== + dependencies: + broccoli-plugin "^1.1.0" + mkdirp "^0.5.1" + +broccoli-filter@^1.2.2, broccoli-filter@^1.2.3: + version "1.3.0" + resolved "https://registry.yarnpkg.com/broccoli-filter/-/broccoli-filter-1.3.0.tgz#71e3a8e32a17f309e12261919c5b1006d6766de6" + integrity sha512-VXJXw7eBfG82CFxaBDjYmyN7V72D4In2zwLVQJd/h3mBfF3CMdRTsv2L20lmRTtCv1sAHcB+LgMso90e/KYiLw== + dependencies: + broccoli-kitchen-sink-helpers "^0.3.1" + broccoli-plugin "^1.0.0" + copy-dereference "^1.0.0" + debug "^2.2.0" + mkdirp "^0.5.1" + promise-map-series "^0.2.1" + rsvp "^3.0.18" + symlink-or-copy "^1.0.1" + walk-sync "^0.3.1" + +broccoli-funnel-reducer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/broccoli-funnel-reducer/-/broccoli-funnel-reducer-1.0.0.tgz#11365b2a785aec9b17972a36df87eef24c5cc0ea" + integrity sha1-ETZbKnha7JsXlyo234fu8kxcwOo= + +broccoli-funnel@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/broccoli-funnel/-/broccoli-funnel-1.2.0.tgz#cddc3afc5ff1685a8023488fff74ce6fb5a51296" + integrity sha1-zdw6/F/xaFqAI0iP/3TOb7WlEpY= + dependencies: + array-equal "^1.0.0" + blank-object "^1.0.1" + broccoli-plugin "^1.3.0" + debug "^2.2.0" + exists-sync "0.0.4" + fast-ordered-set "^1.0.0" + fs-tree-diff "^0.5.3" + heimdalljs "^0.2.0" + minimatch "^3.0.0" + mkdirp "^0.5.0" + path-posix "^1.0.0" + rimraf "^2.4.3" + symlink-or-copy "^1.0.0" + walk-sync "^0.3.1" + +broccoli-funnel@^2.0.0, broccoli-funnel@^2.0.1, broccoli-funnel@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/broccoli-funnel/-/broccoli-funnel-2.0.2.tgz#0edf629569bc10bd02cc525f74b9a38e71366a75" + integrity sha512-/vDTqtv7ipjEZQOVqO4vGDVAOZyuYzQ/EgGoyewfOgh1M7IQAToBKZI0oAQPgMBeFPPlIbfMuAngk+ohPBuaHQ== + dependencies: + array-equal "^1.0.0" + blank-object "^1.0.1" + broccoli-plugin "^1.3.0" + debug "^2.2.0" + fast-ordered-set "^1.0.0" + fs-tree-diff "^0.5.3" + heimdalljs "^0.2.0" + minimatch "^3.0.0" + mkdirp "^0.5.0" + path-posix "^1.0.0" + rimraf "^2.4.3" + symlink-or-copy "^1.0.0" + walk-sync "^0.3.1" + +broccoli-kitchen-sink-helpers@^0.2.5: + version "0.2.9" + resolved "https://registry.yarnpkg.com/broccoli-kitchen-sink-helpers/-/broccoli-kitchen-sink-helpers-0.2.9.tgz#a5e0986ed8d76fb5984b68c3f0450d3a96e36ecc" + integrity sha1-peCYbtjXb7WYS2jD8EUNOpbjbsw= + dependencies: + glob "^5.0.10" + mkdirp "^0.5.1" + +broccoli-kitchen-sink-helpers@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/broccoli-kitchen-sink-helpers/-/broccoli-kitchen-sink-helpers-0.3.1.tgz#77c7c18194b9664163ec4fcee2793444926e0c06" + integrity sha1-d8fBgZS5ZkFj7E/O4nk0RJJuDAY= + dependencies: + glob "^5.0.10" + mkdirp "^0.5.1" + +broccoli-lint-eslint@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/broccoli-lint-eslint/-/broccoli-lint-eslint-5.0.0.tgz#05365879d597dd78496a1c718db0e5ea5d4a2bde" + integrity sha512-V7M6U4th21bf1X4u3KoZa0xkcPq9JCSyKxB/nCWCBFMI3rkrB8nlyDLd8DKIUTqL+ojlFOGV5lohPZwndw0sZw== + dependencies: + aot-test-generators "^0.1.0" + broccoli-concat "^3.2.2" + broccoli-persistent-filter "^2.1.0" + eslint "^5.6.0" + json-stable-stringify "^1.0.1" + lodash.defaultsdeep "^4.6.0" + md5-hex "^2.0.0" + +broccoli-merge-trees@^1.0.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/broccoli-merge-trees/-/broccoli-merge-trees-1.2.4.tgz#a001519bb5067f06589d91afa2942445a2d0fdb5" + integrity sha1-oAFRm7UGfwZYnZGvopQkRaLQ/bU= + dependencies: + broccoli-plugin "^1.3.0" + can-symlink "^1.0.0" + fast-ordered-set "^1.0.2" + fs-tree-diff "^0.5.4" + heimdalljs "^0.2.1" + heimdalljs-logger "^0.1.7" + rimraf "^2.4.3" + symlink-or-copy "^1.0.0" + +broccoli-merge-trees@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/broccoli-merge-trees/-/broccoli-merge-trees-2.0.1.tgz#14d4b7fc1a90318c12b16f843e6ba2693808100c" + integrity sha512-WjaexJ+I8BxP5V5RNn6um/qDRSmKoiBC/QkRi79FT9ClHfldxRyCDs9mcV7mmoaPlsshmmPaUz5jdtcKA6DClQ== + dependencies: + broccoli-plugin "^1.3.0" + merge-trees "^1.0.1" + +broccoli-merge-trees@^3.0.0, broccoli-merge-trees@^3.0.1, broccoli-merge-trees@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/broccoli-merge-trees/-/broccoli-merge-trees-3.0.2.tgz#f33b451994225522b5c9bcf27d59decfd8ba537d" + integrity sha512-ZyPAwrOdlCddduFbsMyyFzJUrvW6b04pMvDiAQZrCwghlvgowJDY+EfoXn+eR1RRA5nmGHJ+B68T63VnpRiT1A== + dependencies: + broccoli-plugin "^1.3.0" + merge-trees "^2.0.0" + +broccoli-middleware@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/broccoli-middleware/-/broccoli-middleware-2.1.1.tgz#183635bbef4dc1241533ee001a162f013d776cb9" + integrity sha512-BK8aPhQpOLsHWiftrqXQr84XsvzUqeaN4PlCQOYg5yM0M+WKAHtX2WFXmicSQZOVgKDyh5aeoNTFkHjBAEBzwQ== + dependencies: + ansi-html "^0.0.7" + handlebars "^4.0.4" + has-ansi "^3.0.0" + mime-types "^2.1.18" + +broccoli-module-normalizer@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/broccoli-module-normalizer/-/broccoli-module-normalizer-1.3.0.tgz#f9982d9cbb776b4ed754161cc6547784d3eb19de" + integrity sha512-0idZCOtdVG6xXoQ36Psc1ApMCr3lW5DB+WEAOEwHcUoESIBHzwcRPQTxheGIjZ5o0hxpsRYAUH5x0ErtNezbrQ== + dependencies: + broccoli-plugin "^1.3.0" + merge-trees "^1.0.1" + rimraf "^2.6.2" + symlink-or-copy "^1.1.8" + +broccoli-module-unification-reexporter@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/broccoli-module-unification-reexporter/-/broccoli-module-unification-reexporter-1.0.0.tgz#031909c5d3f159ec11d5f9e2346f2861db8acb3e" + integrity sha512-HTi9ua520M20aBZomaiBopsSt3yjL7J/paR3XPjieygK7+ShATBiZdn0B+ZPiniBi4I8JuMn1q0fNFUevtP//A== + dependencies: + broccoli-plugin "^1.3.0" + mkdirp "^0.5.1" + walk-sync "^0.3.2" + +broccoli-node-api@^1.6.0, broccoli-node-api@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/broccoli-node-api/-/broccoli-node-api-1.7.0.tgz#391aa6edecd2a42c63c111b4162956b2fa288cb6" + integrity sha512-QIqLSVJWJUVOhclmkmypJJH9u9s/aWH4+FH6Q6Ju5l+Io4dtwqdPUNmDfw40o6sxhbZHhqGujDJuHTML1wG8Yw== + +broccoli-node-info@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/broccoli-node-info/-/broccoli-node-info-1.1.0.tgz#3aa2e31e07e5bdb516dd25214f7c45ba1c459412" + integrity sha1-OqLjHgflvbUW3SUhT3xFuhxFlBI= + +broccoli-node-info@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/broccoli-node-info/-/broccoli-node-info-2.1.0.tgz#ca84560e8570ff78565bea1699866ddbf58ad644" + integrity sha512-l6qDuboJThHfRVVWQVaTs++bFdrFTP0gJXgsWenczc1PavRVUmL1Eyb2swTAXXMpDOnr2zhNOBLx4w9AxkqbPQ== + +broccoli-output-wrapper@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/broccoli-output-wrapper/-/broccoli-output-wrapper-2.0.0.tgz#f1e0b9b2f259a67fd41a380141c3c20b096828e6" + integrity sha512-V/ozejo+snzNf75i/a6iTmp71k+rlvqjE3+jYfimuMwR1tjNNRdtfno+NGNQB2An9bIAeqZnKhMDurAznHAdtA== + dependencies: + heimdalljs-logger "^0.1.10" + +broccoli-persistent-filter@^1.1.6, broccoli-persistent-filter@^1.4.3: + version "1.4.6" + resolved "https://registry.yarnpkg.com/broccoli-persistent-filter/-/broccoli-persistent-filter-1.4.6.tgz#80762d19000880a77da33c34373299c0f6a3e615" + integrity sha512-0RejLwoC95kv4kta8KAa+FmECJCK78Qgm8SRDEK7YyU0N9Cx6KpY3UCDy9WELl3mCXLN8TokNxc7/hp3lL4lfw== + dependencies: + async-disk-cache "^1.2.1" + async-promise-queue "^1.0.3" + broccoli-plugin "^1.0.0" + fs-tree-diff "^0.5.2" + hash-for-dep "^1.0.2" + heimdalljs "^0.2.1" + heimdalljs-logger "^0.1.7" + mkdirp "^0.5.1" + promise-map-series "^0.2.1" + rimraf "^2.6.1" + rsvp "^3.0.18" + symlink-or-copy "^1.0.1" + walk-sync "^0.3.1" + +broccoli-persistent-filter@^2.1.0, broccoli-persistent-filter@^2.2.1, broccoli-persistent-filter@^2.2.2, broccoli-persistent-filter@^2.3.0, broccoli-persistent-filter@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/broccoli-persistent-filter/-/broccoli-persistent-filter-2.3.1.tgz#4a052e0e0868b344c3a2977e35a3d497aa9eca72" + integrity sha512-hVsmIgCDrl2NFM+3Gs4Cr2TA6UPaIZip99hN8mtkaUPgM8UeVnCbxelCvBjUBHo0oaaqP5jzqqnRVvb568Yu5g== + dependencies: + async-disk-cache "^1.2.1" + async-promise-queue "^1.0.3" + broccoli-plugin "^1.0.0" + fs-tree-diff "^2.0.0" + hash-for-dep "^1.5.0" + heimdalljs "^0.2.1" + heimdalljs-logger "^0.1.7" + mkdirp "^0.5.1" + promise-map-series "^0.2.1" + rimraf "^2.6.1" + rsvp "^4.7.0" + symlink-or-copy "^1.0.1" + sync-disk-cache "^1.3.3" + walk-sync "^1.0.0" + +broccoli-plugin@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/broccoli-plugin/-/broccoli-plugin-1.1.0.tgz#73e2cfa05f8ea1e3fc1420c40c3d9e7dc724bf02" + integrity sha1-c+LPoF+OoeP8FCDEDD2efcckvwI= + dependencies: + promise-map-series "^0.2.1" + quick-temp "^0.1.3" + rimraf "^2.3.4" + symlink-or-copy "^1.0.1" + +broccoli-plugin@^1.0.0, broccoli-plugin@^1.1.0, broccoli-plugin@^1.2.0, broccoli-plugin@^1.2.1, broccoli-plugin@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/broccoli-plugin/-/broccoli-plugin-1.3.1.tgz#a26315732fb99ed2d9fb58f12a1e14e986b4fabd" + integrity sha512-DW8XASZkmorp+q7J4EeDEZz+LoyKLAd2XZULXyD9l4m9/hAKV3vjHmB1kiUshcWAYMgTP1m2i4NnqCE/23h6AQ== + dependencies: + promise-map-series "^0.2.1" + quick-temp "^0.1.3" + rimraf "^2.3.4" + symlink-or-copy "^1.1.8" + +broccoli-plugin@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/broccoli-plugin/-/broccoli-plugin-2.1.0.tgz#2fab6c578219cfcc64f773e9616073313fc8b334" + integrity sha512-ElE4caljW4slapyEhSD9jU9Uayc8SoSABWdmY9SqbV8DHNxU6xg1jJsPcMm+cXOvggR3+G+OXAYQeFjWVnznaw== + dependencies: + promise-map-series "^0.2.1" + quick-temp "^0.1.3" + rimraf "^2.3.4" + symlink-or-copy "^1.1.8" + +broccoli-plugin@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/broccoli-plugin/-/broccoli-plugin-3.1.0.tgz#54ba6dd90a42ec3db5624063292610e326b1e542" + integrity sha512-7w7FP8WJYjLvb0eaw27LO678TGGaom++49O1VYIuzjhXjK5kn2+AMlDm7CaUFw4F7CLGoVQeZ84d8gICMJa4lA== + dependencies: + broccoli-node-api "^1.6.0" + broccoli-output-wrapper "^2.0.0" + fs-merger "^3.0.1" + promise-map-series "^0.2.1" + quick-temp "^0.1.3" + rimraf "^2.3.4" + symlink-or-copy "^1.1.8" + +broccoli-slow-trees@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/broccoli-slow-trees/-/broccoli-slow-trees-3.1.0.tgz#8e48903f59e061bf1213963733b9e61dec2ee5d7" + integrity sha512-FRI7mRTk2wjIDrdNJd6znS7Kmmne4VkAkl8Ix1R/VoePFMD0g0tEl671xswzFqaRjpT9Qu+CC4hdXDLDJBuzMw== + dependencies: + heimdalljs "^0.2.1" + +broccoli-source@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/broccoli-source/-/broccoli-source-1.1.0.tgz#54f0e82c8b73f46580cbbc4f578f0b32fca8f809" + integrity sha1-VPDoLItz9GWAy7xPV48LMvyo+Ak= + +broccoli-source@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/broccoli-source/-/broccoli-source-3.0.0.tgz#c7c9ba24505941b72a0244568285bc859f69dfbd" + integrity sha512-G4Zc8HngZIdASyQOiz/9H/0Gjc2F02EFwhWF4wiueaI+/FBrM9Ixj6Prno/1aiLIYcN0JvRC3oytN9uOVonTww== + dependencies: + broccoli-node-api "^1.6.0" + +broccoli-sri-hash@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/broccoli-sri-hash/-/broccoli-sri-hash-2.1.2.tgz#bc69905ed7a381ad325cc0d02ded071328ebf3f3" + integrity sha1-vGmQXtejga0yXMDQLe0HEyjr8/M= + dependencies: + broccoli-caching-writer "^2.2.0" + mkdirp "^0.5.1" + rsvp "^3.1.0" + sri-toolbox "^0.2.0" + symlink-or-copy "^1.0.1" + +broccoli-stew@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/broccoli-stew/-/broccoli-stew-3.0.0.tgz#fd1d19d162ad9490b42e5c563b78c26eb1e80b95" + integrity sha512-NXfi+Vas24n3Ivo21GvENTI55qxKu7OwKRnCLWXld8MiLiQKQlWIq28eoARaFj0lTUFwUa4jKZeA7fW9PiWQeg== + dependencies: + broccoli-debug "^0.6.5" + broccoli-funnel "^2.0.0" + broccoli-merge-trees "^3.0.1" + broccoli-persistent-filter "^2.3.0" + broccoli-plugin "^2.1.0" + chalk "^2.4.1" + debug "^4.1.1" + ensure-posix-path "^1.0.1" + fs-extra "^8.0.1" + minimatch "^3.0.4" + resolve "^1.11.1" + rsvp "^4.8.5" + symlink-or-copy "^1.2.0" + walk-sync "^1.1.3" + +broccoli-uglify-sourcemap@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/broccoli-uglify-sourcemap/-/broccoli-uglify-sourcemap-3.2.0.tgz#d96f1d41f6c18e9a5d49af1a5ab9489cdcac1c6c" + integrity sha512-kkkn8v7kXdWwnZNekq+3ILuTAGkZoaoEMUYCKoER5/uokuoyTjtdYLHaE7UxHkuPEuLfjvJYv21sCCePZ74/2g== + dependencies: + async-promise-queue "^1.0.5" + broccoli-plugin "^1.2.1" + debug "^4.1.0" + lodash.defaultsdeep "^4.6.1" + matcher-collection "^2.0.0" + mkdirp "^0.5.0" + source-map-url "^0.4.0" + symlink-or-copy "^1.0.1" + terser "^4.3.9" + walk-sync "^1.1.3" + workerpool "^5.0.1" + +broccoli@^3.2.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/broccoli/-/broccoli-3.4.1.tgz#3acf2c8d998ed57fb7a89dee1b1b5e8e956e285b" + integrity sha512-DTIHD4olRsXr+Y+6k/E6PqnnSKAAROwgM77qmCloojmJS19QiIAJq7Pq2w6qZx9tQZt1zByhYgLm3r1m73yTPQ== + dependencies: + "@types/chai" "^4.2.9" + "@types/chai-as-promised" "^7.1.2" + "@types/express" "^4.17.2" + ansi-html "^0.0.7" + broccoli-node-info "^2.1.0" + broccoli-slow-trees "^3.0.1" + broccoli-source "^3.0.0" + commander "^4.1.1" + connect "^3.6.6" + console-ui "^3.0.4" + esm "^3.2.4" + findup-sync "^4.0.0" + handlebars "^4.7.3" + heimdalljs "^0.2.6" + heimdalljs-logger "^0.1.9" + https "^1.0.0" + mime-types "^2.1.26" + resolve-path "^1.4.0" + rimraf "^3.0.2" + sane "^4.0.0" + tmp "^0.0.33" + tree-sync "^2.0.0" + underscore.string "^3.2.2" + watch-detector "^1.0.0" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@^3.2.6: + version "3.2.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" + integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== + dependencies: + caniuse-lite "^1.0.30000844" + electron-to-chromium "^1.3.47" + +browserslist@^4.8.5, browserslist@^4.9.1: + version "4.12.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.12.0.tgz#06c6d5715a1ede6c51fc39ff67fd647f740b656d" + integrity sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg== + dependencies: + caniuse-lite "^1.0.30001043" + electron-to-chromium "^1.3.413" + node-releases "^1.1.53" + pkg-up "^2.0.0" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +builtins@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" + integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= + +bytes@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-1.0.0.tgz#3569ede8ba34315fab99c3e92cb04c7220de1fa8" + integrity sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g= + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cacache@^12.0.2: + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cacheable-request@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + integrity sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0= + dependencies: + clone-response "1.0.2" + get-stream "3.0.0" + http-cache-semantics "3.8.1" + keyv "3.0.0" + lowercase-keys "1.0.0" + normalize-url "2.0.1" + responselike "1.0.2" + +calculate-cache-key-for-tree@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/calculate-cache-key-for-tree/-/calculate-cache-key-for-tree-2.0.0.tgz#7ac57f149a4188eacb0a45b210689215d3fef8d6" + integrity sha512-Quw8a6y8CPmRd6eU+mwypktYCwUcf8yVFIRbNZ6tPQEckX9yd+EBVEPC/GSZZrMWH9e7Vz4pT7XhpmyApRByLQ== + dependencies: + json-stable-stringify "^1.0.1" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + +callsite@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA= + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +can-symlink@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/can-symlink/-/can-symlink-1.0.0.tgz#97b607d8a84bb6c6e228b902d864ecb594b9d219" + integrity sha1-l7YH2KhLtsbiKLkC2GTstZS50hk= + dependencies: + tmp "0.0.28" + +caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001043: + version "1.0.30001048" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001048.tgz#4bb4f1bc2eb304e5e1154da80b93dee3f1cf447e" + integrity sha512-g1iSHKVxornw0K8LG9LLdf+Fxnv7T1Z+mMsf0/YYLclQX4Cd522Ap0Lrw6NFqHgezit78dtyWxzlV2Xfc7vgRg== + +capture-exit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" + integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== + dependencies: + rsvp "^4.8.4" + +capture-stack-trace@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== + +cardinal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-1.0.0.tgz#50e21c1b0aa37729f9377def196b5a9cec932ee9" + integrity sha1-UOIcGwqjdyn5N33vGWtanOyTLuk= + dependencies: + ansicolors "~0.2.1" + redeyed "~1.0.0" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +chalk@^1.0.0, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + 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" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +charm@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/charm/-/charm-1.0.2.tgz#8add367153a6d9a581331052c4090991da995e35" + integrity sha1-it02cVOm2aWBMxBSxAkJkdqZXjU= + dependencies: + inherits "^2.0.1" + +chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chrome-trace-event@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" + integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== + dependencies: + tslib "^1.9.0" + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-base-url@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clean-base-url/-/clean-base-url-1.0.0.tgz#c901cf0a20b972435b0eccd52d056824a4351b7b" + integrity sha1-yQHPCiC5ckNbDszVLQVoJKQ1G3s= + +clean-css-promise@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/clean-css-promise/-/clean-css-promise-0.1.1.tgz#43f3d2c8dfcb2bf071481252cd9b76433c08eecb" + integrity sha1-Q/PSyN/LK/BxSBJSzZt2QzwI7ss= + dependencies: + array-to-error "^1.0.0" + clean-css "^3.4.5" + pinkie-promise "^2.0.0" + +clean-css@^3.4.5: + version "3.4.28" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-3.4.28.tgz#bf1945e82fc808f55695e6ddeaec01400efd03ff" + integrity sha1-vxlF6C/ICPVWlebd6uwBQA79A/8= + dependencies: + commander "2.8.x" + source-map "0.4.x" + +clean-up-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clean-up-path/-/clean-up-path-1.0.0.tgz#de9e8196519912e749c9eaf67c13d64fac72a3e5" + integrity sha512-PHGlEF0Z6976qQyN6gM7kKH6EH0RdfZcc8V+QhFe36eRxV0SMH5OUBZG7Bxa9YcreNzyNbK63cGiZxdSZgosRw== + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-spinners@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.3.0.tgz#0632239a4b5aa4c958610142c34bb7a651fc8df5" + integrity sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w== + +cli-table3@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" + integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== + dependencies: + object-assign "^4.1.0" + string-width "^2.1.1" + optionalDependencies: + colors "^1.1.2" + +cli-table@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" + integrity sha1-9TsFJmqLGguTSz0IIebi3FkUriM= + dependencies: + colors "1.0.3" + +cli-width@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" + integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== + +clone-response@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +clone@^2.0.0, clone@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= + +colors@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@2.12.2: + version "2.12.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555" + integrity sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA== + +commander@2.8.x: + version "2.8.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ= + dependencies: + graceful-readlink ">= 1.0.0" + +commander@^2.20.0, commander@^2.6.0, commander@~2.20.3: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +common-tags@^1.4.0, common-tags@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" + integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= + +component-emitter@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +configstore@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" + integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== + dependencies: + dot-prop "^5.2.0" + graceful-fs "^4.1.2" + make-dir "^3.0.0" + unique-string "^2.0.0" + write-file-atomic "^3.0.0" + xdg-basedir "^4.0.0" + +connect@^3.6.6: + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +console-ui@^3.0.4, console-ui@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/console-ui/-/console-ui-3.1.1.tgz#681a0414e8b0a23ed679d0a2802e39d920801171" + integrity sha512-22y+uk4AGq9quz6kofKQjkeCIAm86+MTxT/RZMFm8fMArP2lAkzxjUjNyrw7S6wXnnB+qRnC+/2ANMTke68RTQ== + dependencies: + chalk "^2.1.0" + inquirer "^6" + json-stable-stringify "^1.0.1" + ora "^3.4.0" + through2 "^3.0.1" + +consolidate@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.15.1.tgz#21ab043235c71a07d45d9aad98593b0dba56bab7" + integrity sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw== + dependencies: + bluebird "^3.1.1" + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +content-disposition@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +continuable-cache@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/continuable-cache/-/continuable-cache-0.3.1.tgz#bd727a7faed77e71ff3985ac93351a912733ad0f" + integrity sha1-vXJ6f67XfnH/OYWskzUakSczrQ8= + +convert-source-map@^1.5.1, convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-dereference@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/copy-dereference/-/copy-dereference-1.0.0.tgz#6b131865420fd81b413ba994b44d3655311152b6" + integrity sha1-axMYZUIP2BtBO6mUtE02VTERUrY= + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-js-compat@^3.6.2: + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" + integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== + dependencies: + browserslist "^4.8.5" + semver "7.0.0" + +core-js@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" + integrity sha1-TekR5mew6ukSTjQlS1OupvxhjT4= + +core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.5: + version "2.6.11" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" + integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== + +core-object@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/core-object/-/core-object-3.1.5.tgz#fa627b87502adc98045e44678e9a8ec3b9c0d2a9" + integrity sha512-sA2/4+/PZ/KV6CKgjrVrrUVBKCkdDO02CUlQ0YKTQoYUwPYNOtOAcWlbYhd5v/1JqYaA6oZ4sDlOU4ppVw6Wbg== + dependencies: + chalk "^2.0.0" + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= + dependencies: + capture-stack-trace "^1.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.2.tgz#d0d7dcfa74e89115c7619f4f721a94e1fdb716d6" + integrity sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== + +cssom@0.3.x, cssom@^0.3.4: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^1.1.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" + integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== + dependencies: + cssom "0.3.x" + +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= + +dag-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dag-map/-/dag-map-2.0.2.tgz#9714b472de82a1843de2fba9b6876938cab44c68" + integrity sha1-lxS0ct6CoYQ94vuptodpOMq0TGg= + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +data-urls@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" + integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== + dependencies: + abab "^2.0.0" + whatwg-mimetype "^2.2.0" + whatwg-url "^7.0.0" + +debug@2.6.9, debug@^2.1.0, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.0.0, debug@^3.0.1, debug@^3.1.0, debug@^3.1.1, debug@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +depd@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= + dependencies: + repeating "^2.0.0" + +detect-indent@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.0.0.tgz#0abd0f549f69fc6659a254fe96786186b6f528fd" + integrity sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA== + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +detect-newline@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== + dependencies: + webidl-conversions "^4.0.2" + +dot-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.3.tgz#21d3b52efaaba2ea5fda875bb1aa8124521cf4aa" + integrity sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA== + dependencies: + no-case "^3.0.3" + tslib "^1.10.0" + +dot-prop@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" + integrity sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A== + dependencies: + is-obj "^2.0.0" + +duplex@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/duplex/-/duplex-1.0.0.tgz#6abc5c16ec17e4c578578727126700590d3a2dda" + integrity sha1-arxcFuwX5MV4V4cnEmcAWQ06Ldo= + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +editions@^1.1.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b" + integrity sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg== + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +electron-to-chromium@^1.3.413, electron-to-chromium@^1.3.47: + version "1.3.421" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.421.tgz#4abfe7e49070b5b437ec2ce442543add8eb66800" + integrity sha512-ogxgmvHGfDuLA+GtgfK0jkFWlBb4MCZK2U1MM+l98sf4U3Ixtrfw1iC9w4mQqNvo+lHgM4pR62TqoT4QrvKJCw== + +elliptic@^6.0.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" + integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +ember-assign-polyfill@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/ember-assign-polyfill/-/ember-assign-polyfill-2.6.0.tgz#07847e3357ee35b33f886a0b5fbec6873f6860eb" + integrity sha512-Y8NzOmHI/g4PuJ+xC14eTYiQbigNYddyHB8FY2kuQMxThTEIDE7SJtgttJrYYcPciOu0Tnb5ff36iO46LeiXkw== + dependencies: + ember-cli-babel "^6.16.0" + ember-cli-version-checker "^2.0.0" + +ember-auto-import@^1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/ember-auto-import/-/ember-auto-import-1.5.3.tgz#b32936f874d1ed7057ad2ed3f6116357820be44b" + integrity sha512-7JfdunM1BmLy/lyUXu7uEoi0Gi4+dxkGM23FgIEyW5g7z4MidhP53Fc61t49oPSnq7+J4lLpbH1f6C+mDMgb4A== + dependencies: + "@babel/core" "^7.1.6" + "@babel/preset-env" "^7.0.0" + "@babel/traverse" "^7.1.6" + "@babel/types" "^7.1.6" + "@embroider/core" "^0.4.3" + babel-core "^6.26.3" + babel-loader "^8.0.6" + babel-plugin-syntax-dynamic-import "^6.18.0" + babel-template "^6.26.0" + babylon "^6.18.0" + broccoli-debug "^0.6.4" + broccoli-plugin "^1.3.0" + debug "^3.1.0" + ember-cli-babel "^6.6.0" + enhanced-resolve "^4.0.0" + fs-extra "^6.0.1" + fs-tree-diff "^1.0.0" + handlebars "^4.3.1" + js-string-escape "^1.0.1" + lodash "^4.17.10" + mkdirp "^0.5.1" + pkg-up "^2.0.0" + resolve "^1.7.1" + rimraf "^2.6.2" + symlink-or-copy "^1.2.0" + typescript-memoize "^1.0.0-alpha.3" + walk-sync "^0.3.3" + webpack "~4.28" + +ember-cli-babel-plugin-helpers@^1.0.0, ember-cli-babel-plugin-helpers@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ember-cli-babel-plugin-helpers/-/ember-cli-babel-plugin-helpers-1.1.0.tgz#de3baedd093163b6c2461f95964888c1676325ac" + integrity sha512-Zr4my8Xn+CzO0gIuFNXji0eTRml5AxZUTDQz/wsNJ5AJAtyFWCY4QtKdoELNNbiCVGt1lq5yLiwTm4scGKu6xA== + +ember-cli-babel@^6.0.0-beta.4, ember-cli-babel@^6.16.0, ember-cli-babel@^6.6.0, ember-cli-babel@^6.8.1: + version "6.18.0" + resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-6.18.0.tgz#3f6435fd275172edeff2b634ee7b29ce74318957" + integrity sha512-7ceC8joNYxY2wES16iIBlbPSxwKDBhYwC8drU3ZEvuPDMwVv1KzxCNu1fvxyFEBWhwaRNTUxSCsEVoTd9nosGA== + dependencies: + amd-name-resolver "1.2.0" + babel-plugin-debug-macros "^0.2.0-beta.6" + babel-plugin-ember-modules-api-polyfill "^2.6.0" + babel-plugin-transform-es2015-modules-amd "^6.24.0" + babel-polyfill "^6.26.0" + babel-preset-env "^1.7.0" + broccoli-babel-transpiler "^6.5.0" + broccoli-debug "^0.6.4" + broccoli-funnel "^2.0.0" + broccoli-source "^1.1.0" + clone "^2.0.0" + ember-cli-version-checker "^2.1.2" + semver "^5.5.0" + +ember-cli-babel@^7.11.0, ember-cli-babel@^7.12.0, ember-cli-babel@^7.13.0, ember-cli-babel@^7.13.2, ember-cli-babel@^7.7.3: + version "7.19.0" + resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-7.19.0.tgz#e6eddea18a867231fcf90a80689e92b98be9a63b" + integrity sha512-HiWKuoyy35vGEr+iCw6gUnQ3pS5qslyTlKEDW8cVoMbvZNGYBgRxHed5nklVUh+BS74AwR9lsp25BTAagYAP9Q== + dependencies: + "@babel/core" "^7.9.0" + "@babel/helper-compilation-targets" "^7.8.7" + "@babel/plugin-proposal-class-properties" "^7.8.3" + "@babel/plugin-proposal-decorators" "^7.8.3" + "@babel/plugin-transform-modules-amd" "^7.9.0" + "@babel/plugin-transform-runtime" "^7.9.0" + "@babel/plugin-transform-typescript" "^7.9.0" + "@babel/polyfill" "^7.8.7" + "@babel/preset-env" "^7.9.0" + "@babel/runtime" "^7.9.0" + amd-name-resolver "^1.2.1" + babel-plugin-debug-macros "^0.3.0" + babel-plugin-ember-data-packages-polyfill "^0.1.2" + babel-plugin-ember-modules-api-polyfill "^2.12.0" + babel-plugin-module-resolver "^3.1.1" + broccoli-babel-transpiler "^7.4.0" + broccoli-debug "^0.6.4" + broccoli-funnel "^2.0.1" + broccoli-source "^1.1.0" + clone "^2.1.2" + ember-cli-babel-plugin-helpers "^1.1.0" + ember-cli-version-checker "^4.1.0" + ensure-posix-path "^1.0.2" + fixturify-project "^1.10.0" + rimraf "^3.0.1" + semver "^5.5.0" + +ember-cli-dependency-checker@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ember-cli-dependency-checker/-/ember-cli-dependency-checker-3.2.0.tgz#9202ad9e14d6fda33cffc22a11c343c2a8885330" + integrity sha512-dkSmcJ/jY/2ms/S6ph2jXSfOW5VfOpLfg5DFEbra0SaMNgYkNDFF1o0U4OdTsG37L5h/AXWNuVtnOa4TMabz9Q== + dependencies: + chalk "^2.3.0" + find-yarn-workspace-root "^1.1.0" + is-git-url "^1.0.0" + resolve "^1.5.0" + semver "^5.3.0" + +ember-cli-eslint@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ember-cli-eslint/-/ember-cli-eslint-5.1.0.tgz#acdb9b072911e04b07c313b610f514db4086d21a" + integrity sha512-o6787b0tgkRNp+KJo5BiQxtkLuz/yyYqVWF31LPrh+ZCC8jETrfyjsuk8VPDxKLGq7qEiQNJUgOEW87HTad7Vg== + dependencies: + broccoli-lint-eslint "^5.0.0" + ember-cli-version-checker "^3.0.0" + rsvp "^4.6.1" + walk-sync "^1.0.0" + +ember-cli-get-component-path-option@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-get-component-path-option/-/ember-cli-get-component-path-option-1.0.0.tgz#0d7b595559e2f9050abed804f1d8eff1b08bc771" + integrity sha1-DXtZVVni+QUKvtgE8djv8bCLx3E= + +ember-cli-htmlbars-inline-precompile@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ember-cli-htmlbars-inline-precompile/-/ember-cli-htmlbars-inline-precompile-2.1.0.tgz#61b91ff1879d44ae504cadb46fb1f2604995ae08" + integrity sha512-BylIHduwQkncPhnj0ZyorBuljXbTzLgRo6kuHf1W+IHFxThFl2xG+r87BVwsqx4Mn9MTgW9SE0XWjwBJcSWd6Q== + dependencies: + babel-plugin-htmlbars-inline-precompile "^1.0.0" + ember-cli-version-checker "^2.1.2" + hash-for-dep "^1.2.3" + heimdalljs-logger "^0.1.9" + silent-error "^1.1.0" + +ember-cli-htmlbars@^4.2.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-4.3.1.tgz#4af8adc21ab3c4953f768956b7f7d207782cb175" + integrity sha512-CW6AY/yzjeVqoRtItOKj3hcYzc5dWPRETmeCzr2Iqjt5vxiVtpl0z5VTqHqIlT5fsFx6sGWBQXNHIe+ivYsxXQ== + dependencies: + "@ember/edition-utils" "^1.2.0" + babel-plugin-htmlbars-inline-precompile "^3.0.1" + broccoli-debug "^0.6.5" + broccoli-persistent-filter "^2.3.1" + broccoli-plugin "^3.1.0" + common-tags "^1.8.0" + ember-cli-babel-plugin-helpers "^1.1.0" + fs-tree-diff "^2.0.1" + hash-for-dep "^1.5.1" + heimdalljs-logger "^0.1.10" + json-stable-stringify "^1.0.1" + semver "^6.3.0" + strip-bom "^4.0.0" + walk-sync "^2.0.2" + +ember-cli-inject-live-reload@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ember-cli-inject-live-reload/-/ember-cli-inject-live-reload-2.0.2.tgz#95edb543b386239d35959e5ea9579f5382976ac7" + integrity sha512-HDD6o/kBHT/kUtazklU0OW23q2jigIN42QmcpFdXUSvJ2/2SYA6yIqSUxWfJgISmtn5gTNZ2KPq1p3dLkhJxSQ== + dependencies: + clean-base-url "^1.0.0" + ember-cli-version-checker "^3.1.3" + +ember-cli-is-package-missing@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-is-package-missing/-/ember-cli-is-package-missing-1.0.0.tgz#6e6184cafb92635dd93ca6c946b104292d4e3390" + integrity sha1-bmGEyvuSY13ZPKbJRrEEKS1OM5A= + +ember-cli-lodash-subset@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ember-cli-lodash-subset/-/ember-cli-lodash-subset-2.0.1.tgz#20cb68a790fe0fde2488ddfd8efbb7df6fe766f2" + integrity sha1-IMtop5D+D94kiN39jvu332/nZvI= + +ember-cli-normalize-entity-name@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-normalize-entity-name/-/ember-cli-normalize-entity-name-1.0.0.tgz#0b14f7bcbc599aa117b5fddc81e4fd03c4bad5b7" + integrity sha1-CxT3vLxZmqEXtf3cgeT9A8S61bc= + dependencies: + silent-error "^1.0.0" + +ember-cli-path-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-path-utils/-/ember-cli-path-utils-1.0.0.tgz#4e39af8b55301cddc5017739b77a804fba2071ed" + integrity sha1-Tjmvi1UwHN3FAXc5t3qAT7ogce0= + +ember-cli-preprocess-registry@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/ember-cli-preprocess-registry/-/ember-cli-preprocess-registry-3.3.0.tgz#685837a314fbe57224bd54b189f4b9c23907a2de" + integrity sha512-60GYpw7VPeB7TvzTLZTuLTlHdOXvayxjAQ+IxM2T04Xkfyu75O2ItbWlftQW7NZVGkaCsXSRAmn22PG03VpLMA== + dependencies: + broccoli-clean-css "^1.1.0" + broccoli-funnel "^2.0.1" + debug "^3.0.1" + process-relative-require "^1.0.0" + +ember-cli-sri@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ember-cli-sri/-/ember-cli-sri-2.1.1.tgz#971620934a4b9183cf7923cc03e178b83aa907fd" + integrity sha1-lxYgk0pLkYPPeSPMA+F4uDqpB/0= + dependencies: + broccoli-sri-hash "^2.1.0" + +ember-cli-string-utils@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ember-cli-string-utils/-/ember-cli-string-utils-1.1.0.tgz#39b677fc2805f55173735376fcef278eaa4452a1" + integrity sha1-ObZ3/CgF9VFzc1N2/O8njqpEUqE= + +ember-cli-template-lint@^1.0.0-beta.3: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-template-lint/-/ember-cli-template-lint-1.0.0.tgz#8ca8f5f05fdcad35c13f26b65fb93c016196bdc9" + integrity sha512-acWyJUvRFo2aA/0kqeUxfCPwLtPk3ckZ/1I0BzBX9qW/Gi8qWqYnwnI/vEotIqmsQl+npbl0/SXeQHFrUdyB0g== + dependencies: + aot-test-generators "^0.1.0" + broccoli-concat "^3.7.1" + broccoli-persistent-filter "^2.1.0" + chalk "^2.4.1" + debug "^4.0.1" + ember-cli-version-checker "^3.0.1" + ember-template-lint "^1.2.0" + json-stable-stringify "^1.0.1" + md5-hex "^2.0.0" + strip-ansi "^4.0.0" + walk-sync "^1.1.3" + +ember-cli-test-loader@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ember-cli-test-loader/-/ember-cli-test-loader-2.2.0.tgz#3fb8d5d1357e4460d3f0a092f5375e71b6f7c243" + integrity sha512-mlSXX9SciIRwGkFTX6XGyJYp4ry6oCFZRxh5jJ7VH8UXLTNx2ZACtDTwaWtNhYrWXgKyiDUvmD8enD56aePWRA== + dependencies: + ember-cli-babel "^6.8.1" + +ember-cli-typescript@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-typescript/-/ember-cli-typescript-3.0.0.tgz#3b838d1ce9e4d22a98e68da22ceac6dc0cfd9bfc" + integrity sha512-lo5YArbJzJi5ssvaGqTt6+FnhTALnSvYVuxM7lfyL1UCMudyNJ94ovH5C7n5il7ATd6WsNiAPRUO/v+s5Jq/aA== + dependencies: + "@babel/plugin-transform-typescript" "~7.5.0" + ansi-to-html "^0.6.6" + debug "^4.0.0" + ember-cli-babel-plugin-helpers "^1.0.0" + execa "^2.0.0" + fs-extra "^8.0.0" + resolve "^1.5.0" + rsvp "^4.8.1" + semver "^6.0.0" + stagehand "^1.0.0" + walk-sync "^2.0.0" + +ember-cli-typescript@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ember-cli-typescript/-/ember-cli-typescript-2.0.2.tgz#464984131fbdc05655eb61d1c3cdd911d3137f0d" + integrity sha512-7I5azCTxOgRDN8aSSnJZIKSqr+MGnT+jLTUbBYqF8wu6ojs2DUnTePxUcQMcvNh3Q3B1ySv7Q/uZFSjdU9gSjA== + dependencies: + "@babel/plugin-proposal-class-properties" "^7.1.0" + "@babel/plugin-transform-typescript" "~7.4.0" + ansi-to-html "^0.6.6" + debug "^4.0.0" + ember-cli-babel-plugin-helpers "^1.0.0" + execa "^1.0.0" + fs-extra "^7.0.0" + resolve "^1.5.0" + rsvp "^4.8.1" + semver "^6.0.0" + stagehand "^1.0.0" + walk-sync "^1.0.0" + +ember-cli-uglify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ember-cli-uglify/-/ember-cli-uglify-3.0.0.tgz#8819665b2cc5fe70e3ba9fe7a94645209bc42fd6" + integrity sha512-n3QxdBfAgBdb2Cnso82Kt/nxm3ppIjnYWM8uhOEhF1aYxNXfM7AJrc+yiqTCDUR61Db8aCpHfAMvChz3kyme7g== + dependencies: + broccoli-uglify-sourcemap "^3.1.0" + lodash.defaultsdeep "^4.6.0" + +ember-cli-version-checker@^2.0.0, ember-cli-version-checker@^2.1.1, ember-cli-version-checker@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ember-cli-version-checker/-/ember-cli-version-checker-2.2.0.tgz#47771b731fe0962705e27c8199a9e3825709f3b3" + integrity sha512-G+KtYIVlSOWGcNaTFHk76xR4GdzDLzAS4uxZUKdASuFX0KJE43C6DaqL+y3VTpUFLI2FIkAS6HZ4I1YBi+S3hg== + dependencies: + resolve "^1.3.3" + semver "^5.3.0" + +ember-cli-version-checker@^3.0.0, ember-cli-version-checker@^3.0.1, ember-cli-version-checker@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/ember-cli-version-checker/-/ember-cli-version-checker-3.1.3.tgz#7c9b4f5ff30fdebcd480b1c06c4de43bb51c522c" + integrity sha512-PZNSvpzwWgv68hcXxyjREpj3WWb81A7rtYNQq1lLEgrWIchF8ApKJjWP3NBpHjaatwILkZAV8klair5WFlXAKg== + dependencies: + resolve-package-path "^1.2.6" + semver "^5.6.0" + +ember-cli-version-checker@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ember-cli-version-checker/-/ember-cli-version-checker-4.1.0.tgz#7fc9836bdbc87451d286ba6a9a89b23591d8bbb7" + integrity sha512-yLf2YqotTSsjiXwx9Dt6H7AU0QcldFn5SLk/pG3Zqb0aHNeanBOPlx4/Ysa46ILGWYIh0fDH34AEVRueXTrQBQ== + dependencies: + resolve-package-path "^2.0.0" + semver "^6.3.0" + silent-error "^1.1.1" + +ember-cli@~3.15.2: + version "3.15.2" + resolved "https://registry.yarnpkg.com/ember-cli/-/ember-cli-3.15.2.tgz#c2a5871850da7537e0cb3cd0e7d59fd76cd3184e" + integrity sha512-ciuFaLokZDJfEzltH3QUxZYnQcigCzNrjyyVbeNtr3qUMICHZEzrreQjqIdmuOzmog+BOFddgAB2i/b7ewmV0Q== + dependencies: + "@babel/core" "^7.7.2" + "@babel/plugin-transform-modules-amd" "^7.5.0" + amd-name-resolver "^1.3.1" + babel-plugin-module-resolver "^3.2.0" + bower-config "^1.4.1" + bower-endpoint-parser "0.2.2" + broccoli "^3.2.0" + broccoli-amd-funnel "^2.0.1" + broccoli-babel-transpiler "^7.3.0" + broccoli-builder "^0.18.14" + broccoli-concat "^3.7.4" + broccoli-config-loader "^1.0.1" + broccoli-config-replace "^1.1.2" + broccoli-debug "^0.6.5" + broccoli-funnel "^2.0.2" + broccoli-funnel-reducer "^1.0.0" + broccoli-merge-trees "^3.0.2" + broccoli-middleware "^2.1.0" + broccoli-module-normalizer "^1.3.0" + broccoli-module-unification-reexporter "^1.0.0" + broccoli-slow-trees "^3.0.1" + broccoli-source "^3.0.0" + broccoli-stew "^3.0.0" + calculate-cache-key-for-tree "^2.0.0" + capture-exit "^2.0.0" + chalk "^2.4.2" + ci-info "^2.0.0" + clean-base-url "^1.0.0" + compression "^1.7.4" + configstore "^5.0.0" + console-ui "^3.1.1" + core-object "^3.1.5" + dag-map "^2.0.2" + diff "^4.0.1" + ember-cli-is-package-missing "^1.0.0" + ember-cli-lodash-subset "^2.0.1" + ember-cli-normalize-entity-name "^1.0.0" + ember-cli-preprocess-registry "^3.3.0" + ember-cli-string-utils "^1.1.0" + ember-source-channel-url "^2.0.1" + ensure-posix-path "^1.0.2" + execa "^1.0.0" + exit "^0.1.2" + express "^4.16.4" + filesize "^4.2.0" + find-up "^4.1.0" + find-yarn-workspace-root "^1.2.1" + fs-extra "^8.1.0" + fs-tree-diff "^2.0.1" + get-caller-file "^2.0.5" + git-repo-info "^2.1.0" + glob "^7.1.4" + heimdalljs "^0.2.6" + heimdalljs-fs-monitor "^0.2.3" + heimdalljs-graph "^1.0.0" + heimdalljs-logger "^0.1.10" + http-proxy "^1.18.0" + inflection "^1.12.0" + is-git-url "^1.0.0" + isbinaryfile "^3.0.3" + js-yaml "^3.13.1" + json-stable-stringify "^1.0.1" + leek "0.0.24" + lodash.template "^4.5.0" + markdown-it "^9.1.0" + markdown-it-terminal "0.1.0" + minimatch "^3.0.4" + morgan "^1.9.1" + nopt "^3.0.6" + npm-package-arg "^6.1.1" + p-defer "^3.0.0" + portfinder "^1.0.25" + promise-map-series "^0.2.3" + promise.prototype.finally "^3.1.1" + quick-temp "^0.1.8" + resolve "^1.12.0" + resolve-package-path "^1.2.7" + rsvp "^4.8.5" + sane "^4.1.0" + semver "^6.3.0" + silent-error "^1.1.1" + sort-package-json "^1.23.1" + symlink-or-copy "^1.2.0" + temp "0.9.0" + testem "^2.17.0" + tiny-lr "^1.1.1" + tree-sync "^2.0.0" + uuid "^3.3.3" + walk-sync "^2.0.2" + watch-detector "^1.0.0" + yam "^1.0.0" + +ember-compatibility-helpers@^1.1.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ember-compatibility-helpers/-/ember-compatibility-helpers-1.2.1.tgz#87c92c4303f990ff455c28ca39fb3ee11441aa16" + integrity sha512-6wzYvnhg1ihQUT5yGqnLtleq3Nv5KNv79WhrEuNU9SwR4uIxCO+KpyC7r3d5VI0EM7/Nmv9Nd0yTkzmTMdVG1A== + dependencies: + babel-plugin-debug-macros "^0.2.0" + ember-cli-version-checker "^2.1.1" + semver "^5.4.1" + +ember-disable-prototype-extensions@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/ember-disable-prototype-extensions/-/ember-disable-prototype-extensions-1.1.3.tgz#1969135217654b5e278f9fe2d9d4e49b5720329e" + integrity sha1-GWkTUhdlS14nj5/i2dTkm1cgMp4= + +ember-export-application-global@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ember-export-application-global/-/ember-export-application-global-2.0.1.tgz#b120a70e322ab208defc9e2daebe8d0dfc2dcd46" + integrity sha512-B7wiurPgsxsSGzJuPFkpBWnaeuCu2PGpG2BjyrfA1VcL7//o+5RSnZqiCEY326y7qmxb2GoCgo0ft03KBU0rRw== + +ember-load-initializers@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ember-load-initializers/-/ember-load-initializers-2.1.1.tgz#d1a8bead00bc44222b0ab181840869992beb30f5" + integrity sha512-Ho5sBeaZPN3HmZkYkcLrjSBF3DTNmzC5h0DizzDj8cjpnCvaqeofphJDnH41k6kLv/QHMk4pMRISPcwc+bOceQ== + dependencies: + ember-cli-babel "^7.11.0" + ember-cli-typescript "^2.0.2" + +ember-maybe-import-regenerator@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ember-maybe-import-regenerator/-/ember-maybe-import-regenerator-0.1.6.tgz#35d41828afa6d6a59bc0da3ce47f34c573d776ca" + integrity sha1-NdQYKK+m1qWbwNo85H80xXPXdso= + dependencies: + broccoli-funnel "^1.0.1" + broccoli-merge-trees "^1.0.0" + ember-cli-babel "^6.0.0-beta.4" + regenerator-runtime "^0.9.5" + +ember-qunit@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/ember-qunit/-/ember-qunit-4.6.0.tgz#ad79fd3ff00073a8779400cc5a4b44829517590f" + integrity sha512-i5VOGn0RP8XH+5qkYDOZshbqAvO6lHgF65D0gz8vRx4DszCIvJMJO+bbftBTfYMxp6rqG85etAA6pfNxE0DqsQ== + dependencies: + "@ember/test-helpers" "^1.7.1" + broccoli-funnel "^2.0.2" + broccoli-merge-trees "^3.0.2" + common-tags "^1.4.0" + ember-cli-babel "^7.12.0" + ember-cli-test-loader "^2.2.0" + qunit "^2.9.3" + +ember-resolver@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/ember-resolver/-/ember-resolver-7.0.0.tgz#07ca86b3bae373395b44bba784b8c133f75d61c2" + integrity sha512-tqyWk9E1P5LL42x7AnVoE25a/YWe0WcwAr8LXasm5V7Az3vFR/zbFtwN0oI3tpoSP/nCoGWDct6dRYlXrQjqBQ== + dependencies: + babel-plugin-debug-macros "^0.3.3" + broccoli-funnel "^2.0.2" + broccoli-merge-trees "^3.0.0" + ember-cli-babel "^7.13.2" + ember-cli-version-checker "^3.1.3" + resolve "^1.14.0" + +ember-rfc176-data@^0.3.12: + version "0.3.12" + resolved "https://registry.yarnpkg.com/ember-rfc176-data/-/ember-rfc176-data-0.3.12.tgz#90d82878e69e2ac9a5438e8ce14d12c6031c5bd2" + integrity sha512-g9HeZj/gU5bfIIrGXkP7MhS2b3Vu5DfNUrYr14hy99TgIvtZETO+96QF4WOEUXGjIJdfTRjerVnQlqngPQSv1g== + +ember-router-generator@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ember-router-generator/-/ember-router-generator-2.0.0.tgz#d04abfed4ba8b42d166477bbce47fccc672dbde0" + integrity sha512-89oVHVJwmLDvGvAUWgS87KpBoRhy3aZ6U0Ql6HOmU4TrPkyaa8pM0W81wj9cIwjYprcQtN9EwzZMHnq46+oUyw== + dependencies: + "@babel/parser" "^7.4.5" + "@babel/traverse" "^7.4.5" + recast "^0.18.1" + +ember-source-channel-url@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ember-source-channel-url/-/ember-source-channel-url-1.2.0.tgz#77eb9d0889e5f5370e6c70fcb2696c63ff4a34a1" + integrity sha512-CLClcHzVf+8GoFk4176R16nwXoel70bd7DKVAY6D8M0m5fJJhbTrAPYpDA0lY8A60HZo9j/s8A8LWiGh1YmdZg== + dependencies: + got "^8.0.1" + +ember-source-channel-url@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ember-source-channel-url/-/ember-source-channel-url-2.0.1.tgz#18b88f8a00b7746e7a456b3551abb3aea18729cc" + integrity sha512-YlLUHW9gNvxEaohIj5exykoTZb4xj9ZRTcR4J3svv9S8rjAHJUnHmqC5Fd9onCs+NGxHo7KwR/fDwsfadbDu5Q== + dependencies: + got "^8.0.1" + +ember-source@~3.15.0: + version "3.15.0" + resolved "https://registry.yarnpkg.com/ember-source/-/ember-source-3.15.0.tgz#f6500c6d289ce58231bf1e6695c4974df2be7390" + integrity sha512-daTELJBDMGqAmQb/Puxdk1YR204/zs1DEiEMQWlqbtmhphAoDUbGi9ifJu20ajP/IcOCWw9Vp7aPzguTohWF7w== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/plugin-transform-block-scoping" "^7.6.2" + "@babel/plugin-transform-object-assign" "^7.2.0" + "@ember/edition-utils" "^1.1.1" + babel-plugin-debug-macros "^0.3.3" + babel-plugin-filter-imports "^3.0.0" + broccoli-concat "^3.7.4" + broccoli-funnel "^2.0.2" + broccoli-merge-trees "^3.0.2" + chalk "^2.4.2" + ember-cli-babel "^7.11.0" + ember-cli-get-component-path-option "^1.0.0" + ember-cli-is-package-missing "^1.0.0" + ember-cli-normalize-entity-name "^1.0.0" + ember-cli-path-utils "^1.0.0" + ember-cli-string-utils "^1.1.0" + ember-cli-version-checker "^3.1.3" + ember-router-generator "^2.0.0" + inflection "^1.12.0" + jquery "^3.4.1" + resolve "^1.11.1" + semver "^6.1.1" + silent-error "^1.1.1" + +ember-template-lint@^1.2.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/ember-template-lint/-/ember-template-lint-1.14.0.tgz#fd3e8ec600b0b3de16b5701bf02acc99d192008e" + integrity sha512-M4CebpUZ6G8NEX05FsvlB6nFRO9Xi3eJWbGbnHI1Sakyp5Hl739fTPR5yPn/Gscc/sgNU25Rq1RSm0hoevrYGA== + dependencies: + "@glimmer/syntax" "^0.47.9" + chalk "^2.4.2" + globby "^9.2.0" + minimatch "^3.0.4" + resolve "^1.15.1" + strip-bom "^3.0.0" + +ember-test-waiters@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ember-test-waiters/-/ember-test-waiters-1.2.0.tgz#c12ead4313934c24cff41857020cacdbf8e6effe" + integrity sha512-aEw7YuutLuJT4NUuPTNiGFwgTYl23ThqmBxSkfFimQAn+keWjAftykk3dlFELuhsJhYW/S8YoVjN0bSAQRLNtw== + dependencies: + ember-cli-babel "^7.11.0" + semver "^6.3.0" + +ember-try-config@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ember-try-config/-/ember-try-config-3.0.0.tgz#012d8c90cae9eb624e2b62040bf7e76a1aa58edc" + integrity sha512-pNwHS29O1ACczkrxBKRtDY0TzTb7uPnA5eHEe+4NF6qpLK5FVnL3EtgZ8+yVYtnm1If5mZ07rIubw45vaSek7w== + dependencies: + ember-source-channel-url "^1.0.1" + lodash "^4.6.1" + package-json "^4.0.1" + remote-git-tags "^2.0.0" + rsvp "^4.8.1" + semver "^5.5.0" + +ember-try@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ember-try/-/ember-try-1.4.0.tgz#be15965bd1727c27a65a78c4c8392f03763cc565" + integrity sha512-o0SoCH4K8umCf8etphla8FDygKfQGkwY+w47wEuYFVKaESrOZaK63ObnAK7DTKkjJU74Fss2abf+r+pAWpX43g== + dependencies: + chalk "^2.4.2" + cli-table3 "^0.5.1" + core-object "^3.1.5" + debug "^4.1.1" + ember-try-config "^3.0.0" + execa "^1.0.0" + extend "^3.0.0" + fs-extra "^5.0.0" + promise-map-series "^0.2.1" + resolve "^1.10.1" + rimraf "^2.6.3" + rsvp "^4.7.0" + walk-sync "^1.1.3" + +emit-function@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/emit-function/-/emit-function-0.0.2.tgz#e3a50b3d61be1bf8ca88b924bf713157a5bec124" + integrity sha1-46ULPWG+G/jKiLkkv3ExV6W+wSQ= + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +engine.io-client@~3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.4.1.tgz#922ddb47eecdcb541136a93aeead24718fd05461" + integrity sha512-RJNmA+A9Js+8Aoq815xpGAsgWH1VoSYM//2VgIiu9lNOaHFfLpTjH4tOzktBpjIs5lvOfiNY1dwf+NuU6D38Mw== + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "~4.1.0" + engine.io-parser "~2.2.0" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.5" + parseuri "0.0.5" + ws "~6.1.0" + xmlhttprequest-ssl "~1.5.4" + yeast "0.1.2" + +engine.io-parser@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.0.tgz#312c4894f57d52a02b420868da7b5c1c84af80ed" + integrity sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w== + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.5" + blob "0.0.5" + has-binary2 "~1.0.2" + +engine.io@~3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.4.1.tgz#a61cbc13fa0cb27d9453fd079a29ee980564b069" + integrity sha512-8MfIfF1/IIfxuc2gv5K+XlFZczw/BpTvqBdl0E2fBLkYQp4miv4LuDTVtYt4yMyaIFLEr4vtaSgV4mjvll8Crw== + dependencies: + accepts "~1.3.4" + base64id "2.0.0" + cookie "0.3.1" + debug "~4.1.0" + engine.io-parser "~2.2.0" + ws "^7.1.2" + +enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" + integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +ensure-posix-path@^1.0.0, ensure-posix-path@^1.0.1, ensure-posix-path@^1.0.2, ensure-posix-path@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ensure-posix-path/-/ensure-posix-path-1.1.1.tgz#3c62bdb19fa4681544289edb2b382adc029179ce" + integrity sha512-VWU0/zXzVbeJNXvME/5EmLuEj2TauvoaTz6aFYK1Z92JCBlDlZ3Gu0tuGR42kpW1754ywTs+QB0g5TP0oj9Zaw== + +entities@^1.1.2, entities@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error@^7.0.0: + version "7.2.1" + resolved "https://registry.yarnpkg.com/error/-/error-7.2.1.tgz#eab21a4689b5f684fc83da84a0e390de82d94894" + integrity sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA== + dependencies: + string-template "~0.2.1" + +es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5: + version "1.17.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" + integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.1.5" + is-regex "^1.0.5" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimleft "^2.1.1" + string.prototype.trimright "^2.1.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escodegen@^1.11.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.1.tgz#ba01d0c8278b5e95a9a45350142026659027a457" + integrity sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +eslint-plugin-ember@^7.7.1: + version "7.13.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-ember/-/eslint-plugin-ember-7.13.0.tgz#a1df7794f06cdc6e1b8acfe6c59db5cf861f53dc" + integrity sha512-qIbw4uP0qUJoiWF4+7MTJWqwEN86RGmBNId0cwSoHoVNWtcw50R1ajYgxM1Q5FVUdoisVeSl9lKVRh5zkDFl+g== + dependencies: + "@ember-data/rfc395-data" "^0.0.4" + ember-rfc176-data "^0.3.12" + snake-case "^3.0.3" + +eslint-plugin-es@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz#0f5f5da5f18aa21989feebe8a73eadefb3432976" + integrity sha512-f6fceVtg27BR02EYnBhgWLFQfK6bN4Ll0nQFrBHOlCsAyxeZkn0NHns5O0YZOPrV1B3ramd6cgFwaoFLcSkwEQ== + dependencies: + eslint-utils "^1.4.2" + regexpp "^3.0.0" + +eslint-plugin-node@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz#fd1adbc7a300cf7eb6ac55cf4b0b6fc6e577f5a6" + integrity sha512-1CSyM/QCjs6PXaT18+zuAXsjXGIGo5Rw630rSKwokSs2jrYURQc4R5JZpoanNCqwNmepg+0eZ9L7YiRUJb8jiQ== + dependencies: + eslint-plugin-es "^2.0.0" + eslint-utils "^1.4.2" + ignore "^5.1.1" + minimatch "^3.0.4" + resolve "^1.10.1" + semver "^6.1.0" + +eslint-scope@^4.0.0, eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.3.1, eslint-utils@^1.4.2: + version "1.4.3" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" + integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== + +eslint@^5.6.0: + version "5.16.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" + integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.9.1" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^4.0.3" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^5.0.1" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.7.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^6.2.2" + js-yaml "^3.13.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.11" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^5.5.1" + strip-ansi "^4.0.0" + strip-json-comments "^2.0.1" + table "^5.2.3" + text-table "^0.2.0" + +esm@^3.2.4: + version "3.2.25" + resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" + integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== + +espree@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" + integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== + dependencies: + acorn "^6.0.7" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + +esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esprima@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.0.0.tgz#53cf247acda77313e551c3aa2e73342d3fb4f7d9" + integrity sha1-U88kes2ncxPlUcOqLnM0LT+099k= + +esquery@^1.0.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" + integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.1.0.tgz#374309d39fd935ae500e7b92e8a6b4c720e59642" + integrity sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +eventemitter3@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb" + integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg== + +events-to-array@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/events-to-array/-/events-to-array-1.1.2.tgz#2d41f563e1fe400ed4962fe1a4d5c6a7539df7f6" + integrity sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y= + +events@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" + integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +exec-sh@^0.3.2: + version "0.3.4" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" + integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-2.1.0.tgz#e5d3ecd837d2a60ec50f3da78fd39767747bbe99" + integrity sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^3.0.0" + onetime "^5.1.0" + p-finally "^2.0.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +exists-sync@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/exists-sync/-/exists-sync-0.0.4.tgz#9744c2c428cc03b01060db454d4b12f0ef3c8879" + integrity sha1-l0TCxCjMA7AQYNtFTUsS8O88iHk= + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + +express@^4.10.7, express@^4.16.4: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + +fast-glob@^2.2.6: + version "2.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" + integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + +fast-glob@^3.1.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.2.tgz#ade1a9d91148965d4bf7c51f72e1ca662d32e63d" + integrity sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fast-ordered-set@^1.0.0, fast-ordered-set@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fast-ordered-set/-/fast-ordered-set-1.0.3.tgz#3fbb36634f7be79e4f7edbdb4a357dee25d184eb" + integrity sha1-P7s2Y097555PftvbSjV97iXRhOs= + dependencies: + blank-object "^1.0.1" + +fast-sourcemap-concat@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/fast-sourcemap-concat/-/fast-sourcemap-concat-1.4.0.tgz#122c330d4a2afaff16ad143bc9674b87cd76c8ad" + integrity sha512-x90Wlx/2C83lfyg7h4oguTZN4MyaVfaiUSJQNpU+YEA0Odf9u659Opo44b0LfoVg9G/bOE++GdID/dkyja+XcA== + dependencies: + chalk "^2.0.0" + fs-extra "^5.0.0" + heimdalljs-logger "^0.1.9" + memory-streams "^0.1.3" + mkdirp "^0.5.0" + source-map "^0.4.2" + source-map-url "^0.3.0" + sourcemap-validator "^1.1.0" + +fastq@^1.6.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.7.0.tgz#fcd79a08c5bd7ec5b55cd3f5c4720db551929801" + integrity sha512-YOadQRnHd5q6PogvAR/x62BGituF2ufiEA6s8aavQANw5YKHERI4AREboX6KotzP8oX2klxYF2wcV/7bn1clfQ== + dependencies: + reusify "^1.0.4" + +faye-websocket@~0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= + dependencies: + websocket-driver ">=0.5.1" + +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.1" + +figgy-pudding@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +filesize@^4.1.2, filesize@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-4.2.1.tgz#ab1cb2069db5d415911c1a13e144c0e743bc89bc" + integrity sha512-bP82Hi8VRZX/TUBKfE24iiUGsB/sfm2WUrwTQyAzQrhO3V9IhcBBNBXMyzLY5orACxRyYJ3d2HeRVX+eFv4lmA== + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.1.2, finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-babel-config@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.2.0.tgz#a9b7b317eb5b9860cda9d54740a8c8337a2283a2" + integrity sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA== + dependencies: + json5 "^0.5.1" + path-exists "^3.0.0" + +find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-index@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/find-index/-/find-index-1.1.1.tgz#4b221f8d46b7f8bea33d8faed953f3ca7a081cbc" + integrity sha512-XYKutXMrIK99YMUPf91KX5QVJoG31/OsgftD6YoTPAObfQIxM4ziA9f0J1AsqKhJmo+IeaIPP0CFopTD4bdUBw== + +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-yarn-workspace-root@^1.1.0, find-yarn-workspace-root@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz#40eb8e6e7c2502ddfaa2577c176f221422f860db" + integrity sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q== + dependencies: + fs-extra "^4.0.3" + micromatch "^3.1.4" + +findup-sync@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-4.0.0.tgz#956c9cdde804052b881b428512905c4a5f2cdef0" + integrity sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ== + dependencies: + detect-file "^1.0.0" + is-glob "^4.0.0" + micromatch "^4.0.2" + resolve-dir "^1.0.1" + +fireworm@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/fireworm/-/fireworm-0.7.1.tgz#ccf20f7941f108883fcddb99383dbe6e1861c758" + integrity sha1-zPIPeUHxCIg/zduZOD2+bhhhx1g= + dependencies: + async "~0.2.9" + is-type "0.0.1" + lodash.debounce "^3.1.1" + lodash.flatten "^3.0.2" + minimatch "^3.0.2" + +fixturify-project@^1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/fixturify-project/-/fixturify-project-1.10.0.tgz#091c452a9bb15f09b6b9cc7cf5c0ad559f1d9aad" + integrity sha512-L1k9uiBQuN0Yr8tA9Noy2VSQ0dfg0B8qMdvT7Wb5WQKc7f3dn3bzCbSrqlb+etLW+KDV4cBC7R1OvcMg3kcxmA== + dependencies: + fixturify "^1.2.0" + tmp "^0.0.33" + +fixturify@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fixturify/-/fixturify-1.3.0.tgz#163c468093c7c4d90b70cde39fd6325f6528b25d" + integrity sha512-tL0svlOy56pIMMUQ4bU1xRe6NZbFSa/ABTWMxW2mH38lFGc9TrNAKWcMBQ7eIjo3wqSS8f2ICabFaatFyFmrVQ== + dependencies: + "@types/fs-extra" "^5.0.5" + "@types/minimatch" "^3.0.3" + "@types/rimraf" "^2.0.2" + fs-extra "^7.0.1" + matcher-collection "^2.0.0" + +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" + integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +follow-redirects@^1.0.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.11.0.tgz#afa14f08ba12a52963140fe43212658897bc0ecb" + integrity sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA== + dependencies: + debug "^3.0.0" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2@^2.1.0, from2@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-extra@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.24.0.tgz#d4e4342a96675cb7846633a6099249332b539952" + integrity sha1-1OQ0KpZnXLeEZjOmCZJJMytTmVI= + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + path-is-absolute "^1.0.0" + rimraf "^2.2.8" + +fs-extra@^4.0.2, fs-extra@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" + integrity sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b" + integrity sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^7.0.0, fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^8.0.0, fs-extra@^8.0.1, fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-merger@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/fs-merger/-/fs-merger-3.0.3.tgz#d43c978e3cd5dbc29fb34144182eba749ab8c4b5" + integrity sha512-d9Qx+XlPRU4mkp+JYhUvp5NyS31uhqffIgs6EBnZcjrlO9RwSv0lkWi6PIDxgdNF+vjn9QCZevunGDpfoy4BGg== + dependencies: + broccoli-node-api "^1.7.0" + broccoli-node-info "^2.1.0" + fs-extra "^8.0.1" + fs-tree-diff "^2.0.1" + rimraf "^2.6.3" + walk-sync "^2.0.2" + +fs-minipass@^1.2.5: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + +fs-tree-diff@^0.5.2, fs-tree-diff@^0.5.3, fs-tree-diff@^0.5.4, fs-tree-diff@^0.5.6, fs-tree-diff@^0.5.7: + version "0.5.9" + resolved "https://registry.yarnpkg.com/fs-tree-diff/-/fs-tree-diff-0.5.9.tgz#a4ec6182c2f5bd80b9b83c8e23e4522e6f5fd946" + integrity sha512-872G8ax0kHh01m9n/2KDzgYwouKza0Ad9iFltBpNykvROvf2AGtoOzPJgGx125aolGPER3JuC7uZFrQ7bG1AZw== + dependencies: + heimdalljs-logger "^0.1.7" + object-assign "^4.1.0" + path-posix "^1.0.0" + symlink-or-copy "^1.1.8" + +fs-tree-diff@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/fs-tree-diff/-/fs-tree-diff-1.0.2.tgz#0e2931733a85b55feb3472c0b89a20b0c03ac0de" + integrity sha512-Zro2ACaPVDgVOx9+s5s5AfPlAD0kMJdbwGvTGF6KC1SjxjiGWxJvV4mUTDkFVSy3OUw2C/f1qpdjF81hGqSBAw== + dependencies: + heimdalljs-logger "^0.1.7" + object-assign "^4.1.0" + path-posix "^1.0.0" + symlink-or-copy "^1.1.8" + +fs-tree-diff@^2.0.0, fs-tree-diff@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fs-tree-diff/-/fs-tree-diff-2.0.1.tgz#343e4745ab435ec39ebac5f9059ad919cd034afa" + integrity sha512-x+CfAZ/lJHQqwlD64pYM5QxWjzWhSjroaVsr8PW831zOApL55qPibed0c+xebaLWVr2BnHFoHdrwOv8pzt8R5A== + dependencies: + "@types/symlink-or-copy" "^1.2.0" + heimdalljs-logger "^0.1.7" + object-assign "^4.1.0" + path-posix "^1.0.0" + symlink-or-copy "^1.1.8" + +fs-updater@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/fs-updater/-/fs-updater-1.0.4.tgz#2329980f99ae9176e9a0e84f7637538a182ce63b" + integrity sha512-0pJX4mJF/qLsNEwTct8CdnnRdagfb+LmjRPJ8sO+nCnAZLW0cTmz4rTgU25n+RvTuWSITiLKrGVJceJPBIPlKg== + dependencies: + can-symlink "^1.0.0" + clean-up-path "^1.0.0" + heimdalljs "^0.2.5" + heimdalljs-logger "^0.1.9" + rimraf "^2.6.2" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.7: + version "1.2.12" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.12.tgz#db7e0d8ec3b0b45724fd4d83d43554a8f1f0de5c" + integrity sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + 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" + +gensync@^1.0.0-beta.1: + version "1.0.0-beta.1" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" + integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + +get-stream@3.0.0, get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" + integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +git-fetch-pack@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/git-fetch-pack/-/git-fetch-pack-0.1.1.tgz#7703a32cf0db80f060d2766a34ac00d02cebcdf5" + integrity sha1-dwOjLPDbgPBg0nZqNKwA0CzrzfU= + dependencies: + bops "0.0.3" + emit-function "0.0.2" + git-packed-ref-parse "0.0.0" + through "~2.2.7" + +git-hooks-list@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/git-hooks-list/-/git-hooks-list-1.0.3.tgz#be5baaf78203ce342f2f844a9d2b03dba1b45156" + integrity sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ== + +git-packed-ref-parse@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/git-packed-ref-parse/-/git-packed-ref-parse-0.0.0.tgz#b85046931f3e4a65679b5de54af3a5d3df372646" + integrity sha1-uFBGkx8+SmVnm13lSvOl0983JkY= + dependencies: + line-stream "0.0.0" + through "~2.2.7" + +git-read-pkt-line@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/git-read-pkt-line/-/git-read-pkt-line-0.0.8.tgz#494037854ed57bd90cd55676540d86ab0cb36caa" + integrity sha1-SUA3hU7Ve9kM1VZ2VA2GqwyzbKo= + dependencies: + bops "0.0.3" + through "~2.2.7" + +git-repo-info@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/git-repo-info/-/git-repo-info-2.1.1.tgz#220ffed8cbae74ef8a80e3052f2ccb5179aed058" + integrity sha512-8aCohiDo4jwjOwma4FmYFd3i97urZulL8XL24nIPxuE+GZnfsAyy/g2Shqx6OjUiFKUXZM+Yy+KHnOmmA3FVcg== + +git-transport-protocol@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/git-transport-protocol/-/git-transport-protocol-0.1.0.tgz#99f4dd6389b9161eded74a9e617d6ba5ed0a6c2c" + integrity sha1-mfTdY4m5Fh7e10qeYX1rpe0KbCw= + dependencies: + duplex "~1.0.0" + emit-function "0.0.2" + git-read-pkt-line "0.0.8" + git-write-pkt-line "0.1.0" + through "~2.2.7" + +git-write-pkt-line@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/git-write-pkt-line/-/git-write-pkt-line-0.1.0.tgz#a84c1856c09011908389b2f06f911d91f6394694" + integrity sha1-qEwYVsCQEZCDibLwb5EdkfY5RpQ= + dependencies: + bops "0.0.3" + through "~2.2.7" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + +glob@^5.0.10: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.4, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + 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" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +globals@^11.1.0, globals@^11.7.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + +globby@11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.0.tgz#56fd0e9f0d4f8fb0c456f1ab0dee96e1380bc154" + integrity sha512-iuehFnR3xu5wBBtm4xi0dMe92Ob87ufyu/dHwpDYfbcpYpIbrO5OnS8M1vWvrBhSGEJ3/Ecj7gnX76P8YxpPEg== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +globby@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" + integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^1.0.2" + dir-glob "^2.2.2" + fast-glob "^2.2.6" + glob "^7.1.3" + ignore "^4.0.3" + pify "^4.0.1" + slash "^2.0.0" + +got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + +got@^8.0.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" + integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== + dependencies: + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + into-stream "^3.1.0" + is-retry-allowed "^1.1.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.4.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" + url-to-options "^1.0.1" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= + +handlebars@^4.0.11, handlebars@^4.0.4, handlebars@^4.3.1, handlebars@^4.5.1, handlebars@^4.7.3: + version "4.7.6" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.6.tgz#d4c05c1baf90e9945f77aa68a7a219aa4a7df74e" + integrity sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.0" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-3.0.0.tgz#36077ef1d15f333484aa7fa77a28606f1c655b37" + integrity sha1-Ngd+8dFfMzSEqn+neihgbxxlWzc= + dependencies: + ansi-regex "^3.0.0" + +has-binary2@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" + integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== + dependencies: + isarray "2.0.1" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + +has-symbols@^1.0.0, has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== + dependencies: + has-symbol-support-x "^1.4.1" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash-for-dep@^1.0.2, hash-for-dep@^1.2.3, hash-for-dep@^1.4.7, hash-for-dep@^1.5.0, hash-for-dep@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/hash-for-dep/-/hash-for-dep-1.5.1.tgz#497754b39bee2f1c4ade4521bfd2af0a7c1196e3" + integrity sha512-/dQ/A2cl7FBPI2pO0CANkvuuVi/IFS5oTyJ0PsOb6jW6WbVW1js5qJXMJTNbWHXBIPdFTWFbabjB+mE0d+gelw== + dependencies: + broccoli-kitchen-sink-helpers "^0.3.1" + heimdalljs "^0.2.3" + heimdalljs-logger "^0.1.7" + path-root "^0.1.1" + resolve "^1.10.0" + resolve-package-path "^1.0.11" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +heimdalljs-fs-monitor@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/heimdalljs-fs-monitor/-/heimdalljs-fs-monitor-0.2.3.tgz#1aedd4b1c61d86c51f6141fb75c5a3350dc41b15" + integrity sha512-fYAvqSP0CxeOjLrt61B4wux/jqZzdZnS2xfb2oc14NP6BTZ8gtgtR2op6gKFakOR8lm8GN9Xhz1K4A1ZvJ4RQw== + dependencies: + heimdalljs "^0.2.3" + heimdalljs-logger "^0.1.7" + +heimdalljs-graph@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/heimdalljs-graph/-/heimdalljs-graph-1.0.0.tgz#0059857952988e54f3a74bb23edaf669f8eaf6af" + integrity sha512-v2AsTERBss0ukm/Qv4BmXrkwsT5x6M1V5Om6E8NcDQ/ruGkERsfsuLi5T8jx8qWzKMGYlwzAd7c/idymxRaPzA== + +heimdalljs-logger@^0.1.10, heimdalljs-logger@^0.1.7, heimdalljs-logger@^0.1.9: + version "0.1.10" + resolved "https://registry.yarnpkg.com/heimdalljs-logger/-/heimdalljs-logger-0.1.10.tgz#90cad58aabb1590a3c7e640ddc6a4cd3a43faaf7" + integrity sha512-pO++cJbhIufVI/fmB/u2Yty3KJD0TqNPecehFae0/eps0hkZ3b4Zc/PezUMOpYuHFQbA7FxHZxa305EhmjLj4g== + dependencies: + debug "^2.2.0" + heimdalljs "^0.2.6" + +heimdalljs@^0.2.0, heimdalljs@^0.2.1, heimdalljs@^0.2.3, heimdalljs@^0.2.5, heimdalljs@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/heimdalljs/-/heimdalljs-0.2.6.tgz#b0eebabc412813aeb9542f9cc622cb58dbdcd9fe" + integrity sha512-o9bd30+5vLBvBtzCPwwGqpry2+n0Hi6H1+qwt6y+0kwRHGGF8TFIhJPmnuM0xO97zaKrDZMwO/V56fAnn8m/tA== + dependencies: + rsvp "~3.2.1" + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hosted-git-info@^2.7.1: + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== + dependencies: + whatwg-encoding "^1.0.1" + +http-cache-semantics@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +"http-parser-js@>=0.4.0 <0.4.11": + version "0.4.10" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" + integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= + +http-proxy@^1.13.1, http-proxy@^1.18.0: + version "1.18.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a" + integrity sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +https@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https/-/https-1.0.0.tgz#3c37c7ae1a8eeb966904a2ad1e975a194b7ed3a4" + integrity sha1-PDfHrhqO65ZpBKKtHpdaGUt+06Q= + +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore-walk@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" + integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== + dependencies: + minimatch "^3.0.4" + +ignore@^4.0.3, ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.1, ignore@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" + integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== + +import-fresh@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + +infer-owner@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflection@^1.12.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.12.0.tgz#a200935656d6f5f6bc4dc7502e1aecb703228416" + integrity sha1-ogCTVlbW9fa8TcdQLhrstwMihBY= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +inline-source-map-comment@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/inline-source-map-comment/-/inline-source-map-comment-1.0.5.tgz#50a8a44c2a790dfac441b5c94eccd5462635faf6" + integrity sha1-UKikTCp5DfrEQbXJTszVRiY1+vY= + dependencies: + chalk "^1.0.0" + get-stdin "^4.0.1" + minimist "^1.1.1" + sum-up "^1.0.1" + xtend "^4.0.0" + +inquirer@^6, inquirer@^6.2.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" + integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== + dependencies: + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.12" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + +inquirer@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.1.0.tgz#1298a01859883e17c7264b82870ae1034f92dd29" + integrity sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg== + dependencies: + ansi-escapes "^4.2.1" + chalk "^3.0.0" + cli-cursor "^3.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.15" + mute-stream "0.0.8" + run-async "^2.4.0" + rxjs "^6.5.3" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + +into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + integrity sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY= + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" + +invariant@^2.2.2, invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-callable@^1.1.4, is-callable@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" + integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-git-url@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-git-url/-/is-git-url-1.0.0.tgz#53f684cd143285b52c3244b4e6f28253527af66b" + integrity sha1-U/aEzRQyhbUsMkS05vKCU1J69ms= + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= + +is-plain-obj@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= + +is-regex@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" + integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== + dependencies: + has "^1.0.3" + +is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + +is-stream@^1.0.0, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + +is-symbol@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + +is-type@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/is-type/-/is-type-0.0.1.tgz#f651d85c365d44955d14a51d8d7061f3f6b4779c" + integrity sha1-9lHYXDZdRJVdFKUdjXBh8/a0d5w= + dependencies: + core-util-is "~1.0.0" + +is-typedarray@^1.0.0, is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" + integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= + +isbinaryfile@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80" + integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw== + dependencies: + buffer-alloc "^1.2.0" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +istextorbinary@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.1.0.tgz#dbed2a6f51be2f7475b68f89465811141b758874" + integrity sha1-2+0qb1G+L3R1to+JRlgRFBt1iHQ= + dependencies: + binaryextensions "1 || 2" + editions "^1.1.1" + textextensions "1 || 2" + +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + +jquery@^3.4.1: + version "3.5.0" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.0.tgz#9980b97d9e4194611c36530e7dc46a58d7340fc9" + integrity sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ== + +js-reporters@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/js-reporters/-/js-reporters-1.2.1.tgz#f88c608e324a3373a95bcc45ad305e5c979c459b" + integrity sha1-+IxgjjJKM3OpW8xFrTBeXJecRZs= + +js-string-escape@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" + integrity sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8= + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +js-yaml@^3.13.0, js-yaml@^3.13.1, js-yaml@^3.2.5, js-yaml@^3.2.7: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsdom@^12.0.0: + version "12.2.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-12.2.0.tgz#7cf3f5b5eafd47f8f09ca52315d367ff6e95de23" + integrity sha512-QPOggIJ8fquWPLaYYMoh+zqUmdphDtu1ju0QGTitZT1Yd8I5qenPpXM1etzUegu3MjVp8XPzgZxdn8Yj7e40ig== + dependencies: + abab "^2.0.0" + acorn "^6.0.2" + acorn-globals "^4.3.0" + array-equal "^1.0.0" + cssom "^0.3.4" + cssstyle "^1.1.1" + data-urls "^1.0.1" + domexception "^1.0.1" + escodegen "^1.11.0" + html-encoding-sniffer "^1.0.2" + nwsapi "^2.0.9" + parse5 "5.1.0" + pn "^1.1.0" + request "^2.88.0" + request-promise-native "^1.0.5" + saxes "^3.1.3" + symbol-tree "^3.2.2" + tough-cookie "^2.4.3" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.2.0" + whatwg-url "^7.0.0" + ws "^6.1.0" + xml-name-validator "^3.0.0" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= + +jsesc@^2.5.0, jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.3.x: + version "0.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.3.0.tgz#1bf5ee63b4539fe2e26d0c1e99c240b97a457972" + integrity sha1-G/XuY7RTn+LibQwemcJAuXpFeXI= + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + dependencies: + minimist "^1.2.5" + +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +keyv@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" + integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== + dependencies: + json-buffer "3.0.0" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +leek@0.0.24: + version "0.0.24" + resolved "https://registry.yarnpkg.com/leek/-/leek-0.0.24.tgz#e400e57f0e60d8ef2bd4d068dc428a54345dbcda" + integrity sha1-5ADlfw5g2O8r1NBo3EKKVDRdvNo= + dependencies: + debug "^2.1.0" + lodash.assign "^3.2.0" + rsvp "^3.0.21" + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levenary@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" + integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== + dependencies: + leven "^3.1.0" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +line-stream@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/line-stream/-/line-stream-0.0.0.tgz#888b7cc7951c6a05ce4d696dd1e6b8262371bb45" + integrity sha1-iIt8x5UcagXOTWlt0ea4JiNxu0U= + dependencies: + through "~2.2.0" + +linkify-it@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" + integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw== + dependencies: + uc.micro "^1.0.1" + +livereload-js@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.4.0.tgz#447c31cf1ea9ab52fc20db615c5ddf678f78009c" + integrity sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw== + +loader-runner@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@^1.1.0, loader-utils@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +loader.js@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/loader.js/-/loader.js-4.7.0.tgz#a1a52902001c83631efde9688b8ab3799325ef1f" + integrity sha512-9M2KvGT6duzGMgkOcTkWb+PR/Q2Oe54df/tLgHGVmFpAmtqJ553xJh6N63iFYI2yjo2PeJXbS5skHi/QpJq4vA== + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + integrity sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4= + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= + +lodash._baseflatten@^3.0.0: + version "3.1.4" + resolved "https://registry.yarnpkg.com/lodash._baseflatten/-/lodash._baseflatten-3.1.4.tgz#0770ff80131af6e34f3b511796a7ba5214e65ff7" + integrity sha1-B3D/gBMa9uNPO1EXlqe6UhTmX/c= + dependencies: + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash._bindcallback@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" + integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4= + +lodash._createassigner@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" + integrity sha1-g4pbri/aymOsIt7o4Z+k5taXCxE= + dependencies: + lodash._bindcallback "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash.restparam "^3.0.0" + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw= + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash.assign@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-3.2.0.tgz#3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa" + integrity sha1-POnwI0tLIiPilrj6CsH+6OvKZPo= + dependencies: + lodash._baseassign "^3.0.0" + lodash._createassigner "^3.0.0" + lodash.keys "^3.0.0" + +lodash.assignin@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" + integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI= + +lodash.castarray@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115" + integrity sha1-wCUTUV4wna3dTCTGDP3c9ZdtkRU= + +lodash.clonedeep@^4.4.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.debounce@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-3.1.1.tgz#812211c378a94cc29d5aa4e3346cf0bfce3a7df5" + integrity sha1-gSIRw3ipTMKdWqTjNGzwv846ffU= + dependencies: + lodash._getnative "^3.0.0" + +lodash.defaultsdeep@^4.6.0, lodash.defaultsdeep@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" + integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== + +lodash.find@^4.5.1: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1" + integrity sha1-ywcE1Hq3F4n/oN6Ll92Sb7iLE7E= + +lodash.flatten@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-3.0.2.tgz#de1cf57758f8f4479319d35c3e9cc60c4501938c" + integrity sha1-3hz1d1j49EeTGdNcPpzGDEUBk4w= + dependencies: + lodash._baseflatten "^3.0.0" + lodash._isiterateecall "^3.0.0" + +lodash.foreach@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" + integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM= + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.merge@^4.6.0, lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.omit@^4.1.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60" + integrity sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA= + +lodash.restparam@^3.0.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" + integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash.template@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" + integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" + integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== + dependencies: + lodash._reinterpolate "^3.0.0" + +lodash.uniq@^4.2.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +lodash.uniqby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" + integrity sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI= + +lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.6.1: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lower-case@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.1.tgz#39eeb36e396115cc05e29422eaea9e692c9408c7" + integrity sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ== + dependencies: + tslib "^1.10.0" + +lowercase-keys@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY= + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= + dependencies: + tmpl "1.0.x" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +markdown-it-terminal@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/markdown-it-terminal/-/markdown-it-terminal-0.1.0.tgz#545abd8dd01c3d62353bfcea71db580b51d22bd9" + integrity sha1-VFq9jdAcPWI1O/zqcdtYC1HSK9k= + dependencies: + ansi-styles "^3.0.0" + cardinal "^1.0.0" + cli-table "^0.3.1" + lodash.merge "^4.6.0" + markdown-it "^8.3.1" + +markdown-it@^8.3.1: + version "8.4.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54" + integrity sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ== + dependencies: + argparse "^1.0.7" + entities "~1.1.1" + linkify-it "^2.0.0" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +markdown-it@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-9.1.0.tgz#df9601c168568704d554b1fff9af0c5b561168d9" + integrity sha512-xHKG4C8iPriyfu/jc2hsCC045fKrMQ0VexX2F1FGYiRxDxqMB2aAhF8WauJ3fltn2kb90moGBkiiEdooGIg55w== + dependencies: + argparse "^1.0.7" + entities "~1.1.1" + linkify-it "^2.0.0" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +matcher-collection@^1.0.0, matcher-collection@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/matcher-collection/-/matcher-collection-1.1.2.tgz#1076f506f10ca85897b53d14ef54f90a5c426838" + integrity sha512-YQ/teqaOIIfUHedRam08PB3NK7Mjct6BvzRnJmpGDm8uFXpNr1sbY4yuflI5JcEs6COpYA0FpRQhSDBf1tT95g== + dependencies: + minimatch "^3.0.2" + +matcher-collection@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/matcher-collection/-/matcher-collection-2.0.1.tgz#90be1a4cf58d6f2949864f65bb3b0f3e41303b29" + integrity sha512-daE62nS2ZQsDg9raM0IlZzLmI2u+7ZapXBwdoeBUKAYERPDDIc0qNqA8E0Rp2D+gspKR7BgIFP52GeujaGXWeQ== + dependencies: + "@types/minimatch" "^3.0.3" + minimatch "^3.0.2" + +md5-hex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" + integrity sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM= + dependencies: + md5-o-matic "^0.1.1" + +md5-o-matic@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + integrity sha1-givM1l4RfFFPqxdrJZRdVBAKA8M= + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +memory-streams@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/memory-streams/-/memory-streams-0.1.3.tgz#d9b0017b4b87f1d92f55f2745c9caacb1dc93ceb" + integrity sha512-qVQ/CjkMyMInPaaRMrwWNDvf6boRZXaT/DbQeMYcCWuXPEBf1v8qChOc9OlEVQp2uOvRXa1Qu30fLmKhY6NipA== + dependencies: + readable-stream "~1.0.2" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge-trees@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-trees/-/merge-trees-1.0.1.tgz#ccbe674569787f9def17fd46e6525f5700bbd23e" + integrity sha1-zL5nRWl4f53vF/1G5lJfVwC70j4= + dependencies: + can-symlink "^1.0.0" + fs-tree-diff "^0.5.4" + heimdalljs "^0.2.1" + heimdalljs-logger "^0.1.7" + rimraf "^2.4.3" + symlink-or-copy "^1.0.0" + +merge-trees@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-trees/-/merge-trees-2.0.0.tgz#a560d796e566c5d9b2c40472a2967cca48d85161" + integrity sha512-5xBbmqYBalWqmhYm51XlohhkmVOua3VAUrrWh8t9iOkaLpS6ifqm/UVuUjQCeDVJ9Vx3g2l6ihfkbLSTeKsHbw== + dependencies: + fs-updater "^1.0.4" + heimdalljs "^0.2.5" + +merge2@^1.2.3, merge2@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" + integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.44.0, "mime-db@>= 1.43.0 < 2": + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== + +mime-types@^2.1.12, mime-types@^2.1.18, mime-types@^2.1.26, mime-types@~2.1.19, mime-types@~2.1.24: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + dependencies: + mime-db "1.44.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.2.1.tgz#827ba4e7593464e7c221e8c5bed930904ee2c455" + integrity sha512-GY8fANSrTMfBVfInqJAY41QkOM+upUTytK1jZ0c8+3HdHrJxBJ3rF5i9moClXTE8uUSnUo8cAsCoxDXvSY4DHg== + +minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minipass@^2.2.0, minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.0: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mktemp@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/mktemp/-/mktemp-0.4.0.tgz#6d0515611c8a8c84e484aa2000129b98e981ff0b" + integrity sha1-bQUVYRyKjITkhKogABKbmOmB/ws= + +morgan@^1.9.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7" + integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ== + dependencies: + basic-auth "~2.0.1" + debug "2.6.9" + depd "~2.0.0" + on-finished "~2.3.0" + on-headers "~1.0.2" + +mout@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/mout/-/mout-1.2.2.tgz#c9b718a499806a0632cede178e80f436259e777d" + integrity sha512-w0OUxFEla6z3d7sVpMZGBCpQvYh8PHS1wZ6Wu9GNKHMpAHWJ0if0LsQZh3DlOqw55HlhJEOMLpFnwtxp99Y5GA== + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +mustache@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/mustache/-/mustache-3.2.1.tgz#89e78a9d207d78f2799b1e95764a25bf71a28322" + integrity sha512-RERvMFdLpaFfSRIEe632yDm5nsd0SDKn8hGmcUwswnyiE5mtdZLDybtHAz6hjJhawokF0hXvGLtx9mrQfm6FkA== + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +nan@^2.12.1: + version "2.14.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" + integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +needle@^2.2.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.1.tgz#14af48732463d7475696f937626b1b993247a56a" + integrity sha512-x/gi6ijr4B7fwl6WYL9FwlCvRQKGlUNvnceho8wxkwXqN8jvVmmmATTmZPRRG7b/yC1eode26C2HO9jl78Du9g== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.5.0, neo-async@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +no-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.3.tgz#c21b434c1ffe48b39087e86cfb4d2582e9df18f8" + integrity sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw== + dependencies: + lower-case "^2.0.1" + tslib "^1.10.0" + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + +node-libs-browser@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + +node-modules-path@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/node-modules-path/-/node-modules-path-1.0.2.tgz#e3acede9b7baf4bc336e3496b58e5b40d517056e" + integrity sha512-6Gbjq+d7uhkO7epaKi5DNgUJn7H0gEyA4Jg0Mo1uQOi3Rk50G83LtmhhFyw0LxnAFhtlspkiiw52ISP13qzcBg== + +node-notifier@^5.0.1: + version "5.4.3" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" + integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== + dependencies: + growly "^1.3.0" + is-wsl "^1.1.0" + semver "^5.5.0" + shellwords "^0.1.1" + which "^1.3.0" + +node-pre-gyp@*: + version "0.14.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz#9a0596533b877289bcad4e143982ca3d904ddc83" + integrity sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4.4.2" + +node-releases@^1.1.53: + version "1.1.53" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.53.tgz#2d821bfa499ed7c5dffc5e2f28c88e78a08ee3f4" + integrity sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ== + +node-watch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/node-watch/-/node-watch-0.6.1.tgz#b9874111ce9f5841b1c7596120206c7b825be0e9" + integrity sha512-gwQiR7weFRV8mAtT0x0kXkZ18dfRLB45xH7q0hCOVQMLfLb2f1ZaSvR57q4/b/Vj6B0RwMNJYbvb69e1yM7qEA== + +nopt@^3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + +nopt@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" + integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + +npm-bundled@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" + integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== + dependencies: + npm-normalize-package-bin "^1.0.1" + +npm-normalize-package-bin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== + +npm-package-arg@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.1.tgz#02168cb0a49a2b75bf988a28698de7b529df5cb7" + integrity sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg== + dependencies: + hosted-git-info "^2.7.1" + osenv "^0.1.5" + semver "^5.6.0" + validate-npm-package-name "^3.0.0" + +npm-packlist@^1.1.6: + version "1.4.8" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" + integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + npm-normalize-package-bin "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +npm-run-path@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-3.1.0.tgz#7f91be317f6a466efed3c9f2980ad8a4ee8b0fa5" + integrity sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg== + dependencies: + path-key "^3.0.0" + +npmlog@^4.0.0, npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +nwsapi@^2.0.9: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@4.1.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-component@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-hash@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" + integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== + +object-inspect@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.getownpropertydescriptors@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" + integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +onetime@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" + integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== + dependencies: + mimic-fn "^2.1.0" + +optionator@^0.8.1, optionator@^0.8.2: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +ora@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" + integrity sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg== + dependencies: + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-spinners "^2.0.0" + log-symbols "^2.2.0" + strip-ansi "^5.2.0" + wcwidth "^1.0.1" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@^0.1.3, osenv@^0.1.4, osenv@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-cancelable@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== + +p-defer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-3.0.0.tgz#d1dceb4ee9b2b604b1d94ffec83760175d4e6f83" + integrity sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw== + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-finally@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" + integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== + +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-timeout@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" + integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== + dependencies: + p-finally "^1.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +package-json@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-asn1@^5.0.0: + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +parse5@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" + integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== + +parseqs@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" + integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0= + dependencies: + better-assert "~1.0.0" + +parseuri@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" + integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo= + dependencies: + better-assert "~1.0.0" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@1.0.1, path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-posix@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/path-posix/-/path-posix-1.0.0.tgz#06b26113f56beab042545a23bfa88003ccac260f" + integrity sha1-BrJhE/Vr6rBCVFojv6iAA8ysJg8= + +path-root-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0= + +path-root@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc= + dependencies: + path-root-regex "^0.1.0" + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +picomatch@^2.0.5, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= + dependencies: + find-up "^2.1.0" + +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== + +portfinder@^1.0.25: + version "1.0.25" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.25.tgz#254fd337ffba869f4b9d37edc298059cb4d35eca" + integrity sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.1" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + +printf@^0.5.1: + version "0.5.3" + resolved "https://registry.yarnpkg.com/printf/-/printf-0.5.3.tgz#8b7eec278d886833312238b2bf42b2b6f250880a" + integrity sha512-t3lYN6vPU5PZXDiEZZqoyXvN8wCsBfi8gPoxTKo2e5hhV673t/KUh+mfO8P8lCOCDC/BWcOGIxKyebxc5FuqLA== + +private@^0.1.6, private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process-relative-require@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/process-relative-require/-/process-relative-require-1.0.0.tgz#1590dfcf5b8f2983ba53e398446b68240b4cc68a" + integrity sha1-FZDfz1uPKYO6U+OYRGtoJAtMxoo= + dependencies: + node-modules-path "^1.0.0" + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +promise-map-series@^0.2.1, promise-map-series@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/promise-map-series/-/promise-map-series-0.2.3.tgz#c2d377afc93253f6bd03dbb77755eb88ab20a847" + integrity sha1-wtN3r8kyU/a9A9u3d1XriKsgqEc= + dependencies: + rsvp "^3.0.14" + +promise.prototype.finally@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.2.tgz#b8af89160c9c673cefe3b4c4435b53cfd0287067" + integrity sha512-A2HuJWl2opDH0EafgdjwEw7HysI8ff/n4lW4QEVBCUXFk9QeGecBWv0Deph0UmLe3tTNYegz8MOjsVuE6SMoJA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.0" + function-bind "^1.1.1" + +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +qs@^6.4.0: + version "6.9.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e" + integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw== + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +quick-temp@^0.1.2, quick-temp@^0.1.3, quick-temp@^0.1.5, quick-temp@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/quick-temp/-/quick-temp-0.1.8.tgz#bab02a242ab8fb0dd758a3c9776b32f9a5d94408" + integrity sha1-urAqJCq4+w3XWKPJd2sy+aXZRAg= + dependencies: + mktemp "~0.4.0" + rimraf "^2.5.4" + underscore.string "~3.3.4" + +qunit-dom@^0.9.2: + version "0.9.2" + resolved "https://registry.yarnpkg.com/qunit-dom/-/qunit-dom-0.9.2.tgz#cc7bb777e4f5faa749eca843f54e199755df8473" + integrity sha512-BPf7OZjhXo9ekgsViNjQVS9BWkm2yQsPvBoy0juvt5nOFlcBVVwHSYsgpsJOunWkI1IgA3eStAC9mQx3Zw734g== + dependencies: + broccoli-funnel "^2.0.2" + broccoli-merge-trees "^3.0.1" + +qunit@^2.9.3: + version "2.9.3" + resolved "https://registry.yarnpkg.com/qunit/-/qunit-2.9.3.tgz#9522a088e76f0782f70a45db92f2fd14db311bcc" + integrity sha512-RH4VYSaVsNRDthMFFboTJAJ8q4kJM5LvOqWponKUYPEAeOcmc/YFV1QsZ7ikknA3TjqliWFJYEV63vvVXaALmQ== + dependencies: + commander "2.12.2" + js-reporters "1.2.1" + minimatch "3.0.4" + node-watch "0.6.1" + resolve "1.9.0" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +raw-body@~1.1.0: + version "1.1.7" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-1.1.7.tgz#1d027c2bfa116acc6623bca8f00016572a87d425" + integrity sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU= + dependencies: + bytes "1" + string_decoder "0.10" + +rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + 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" + +"readable-stream@2 || 3": + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@~1.0.2: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +recast@^0.18.1: + version "0.18.10" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.18.10.tgz#605ebbe621511eb89b6356a7e224bff66ed91478" + integrity sha512-XNvYvkfdAN9QewbrxeTOjgINkdY/odTgTS56ZNEWL9Ml0weT4T3sFtvnTuF+Gxyu46ANcRm1ntrF6F5LAJPAaQ== + dependencies: + ast-types "0.13.3" + esprima "~4.0.0" + private "^0.1.8" + source-map "~0.6.1" + +redeyed@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/redeyed/-/redeyed-1.0.1.tgz#e96c193b40c0816b00aec842698e61185e55498a" + integrity sha1-6WwZO0DAgWsArshCaY5hGF5VSYo= + dependencies: + esprima "~3.0.0" + +regenerate-unicode-properties@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.2.1, regenerate@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + +regenerator-runtime@^0.10.5: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-runtime@^0.13.4: + version "0.13.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" + integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== + +regenerator-runtime@^0.9.5: + version "0.9.6" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.9.6.tgz#d33eb95d0d2001a4be39659707c51b0cb71ce029" + integrity sha1-0z65XQ0gAaS+OWWXB8UbDLcc4Ck= + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regenerator-transform@^0.14.2: + version "0.14.4" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.4.tgz#5266857896518d1616a78a0479337a30ea974cc7" + integrity sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw== + dependencies: + "@babel/runtime" "^7.8.4" + private "^0.1.8" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +regexpp@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" + integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regexpu-core@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" + integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.2.0" + regjsgen "^0.5.1" + regjsparser "^0.6.4" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.2.0" + +registry-auth-token@^3.0.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" + integrity sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A== + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= + dependencies: + rc "^1.0.1" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= + +regjsgen@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c" + integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg== + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= + dependencies: + jsesc "~0.5.0" + +regjsparser@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" + integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== + dependencies: + jsesc "~0.5.0" + +remote-git-tags@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/remote-git-tags/-/remote-git-tags-2.0.0.tgz#1152f39cf8b5268ae0e4307636ef741ec341664c" + integrity sha1-EVLznPi1Jorg5DB2Nu90HsNBZkw= + dependencies: + git-fetch-pack "^0.1.1" + git-transport-protocol "^0.1.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +request-promise-core@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" + integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ== + dependencies: + lodash "^4.17.15" + +request-promise-native@^1.0.5: + version "1.0.8" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" + integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ== + dependencies: + request-promise-core "1.1.3" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + +request@^2.88.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + 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.3" + 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.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +reselect@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147" + integrity sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc= + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-package-path@^1.0.11, resolve-package-path@^1.2.2, resolve-package-path@^1.2.6, resolve-package-path@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/resolve-package-path/-/resolve-package-path-1.2.7.tgz#2a7bc37ad96865e239330e3102c31322847e652e" + integrity sha512-fVEKHGeK85bGbVFuwO9o1aU0n3vqQGrezPc51JGu9UTXpFQfWq5qCeKxyaRUSvephs+06c5j5rPq/dzHGEo8+Q== + dependencies: + path-root "^0.1.1" + resolve "^1.10.0" + +resolve-package-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-package-path/-/resolve-package-path-2.0.0.tgz#7f258ab86ff074fff4ff8027a28f94d17d6fb1df" + integrity sha512-/CLuzodHO2wyyHTzls5Qr+EFeG6RcW4u6//gjYvUfcfyuplIX1SSccU+A5A9A78Gmezkl3NBkFAMxLbzTY9TJA== + dependencies: + path-root "^0.1.1" + resolve "^1.13.1" + +resolve-path@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/resolve-path/-/resolve-path-1.4.0.tgz#c4bda9f5efb2fce65247873ab36bb4d834fe16f7" + integrity sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc= + dependencies: + http-errors "~1.6.2" + path-is-absolute "1.0.1" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06" + integrity sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ== + dependencies: + path-parse "^1.0.6" + +resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.0, resolve@^1.15.1, resolve@^1.3.2, resolve@^1.3.3, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.7.1, resolve@^1.8.1: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + +responselike@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@2.6.3, rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +rimraf@^2.2.8, rimraf@^2.3.4, rimraf@^2.4.3, rimraf@^2.4.4, rimraf@^2.5.3, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@^3.0.1, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +rsvp@^3.0.14, rsvp@^3.0.17, rsvp@^3.0.18, rsvp@^3.0.21, rsvp@^3.0.6, rsvp@^3.1.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" + integrity sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw== + +rsvp@^4.6.1, rsvp@^4.7.0, rsvp@^4.8.1, rsvp@^4.8.2, rsvp@^4.8.4, rsvp@^4.8.5: + version "4.8.5" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" + integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== + +rsvp@~3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.2.1.tgz#07cb4a5df25add9e826ebc67dcc9fd89db27d84a" + integrity sha1-B8tKXfJa3Z6Cbrxn3Mn9idsn2Eo= + +run-async@^2.2.0, run-async@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + +run-parallel@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" + integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +rxjs@^6.4.0, rxjs@^6.5.3: + version "6.5.5" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec" + integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + +safe-json-parse@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/safe-json-parse/-/safe-json-parse-1.0.1.tgz#3e76723e38dfdda13c9b1d29a1e07ffee4b30b57" + integrity sha1-PnZyPjjf3aE8mx0poeB//uSzC1c= + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sane@^4.0.0, sane@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" + integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== + dependencies: + "@cnakazawa/watch" "^1.0.3" + anymatch "^2.0.0" + capture-exit "^2.0.0" + exec-sh "^0.3.2" + execa "^1.0.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +saxes@^3.1.3: + version "3.1.11" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b" + integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g== + dependencies: + xmlchars "^2.1.1" + +schema-utils@^0.4.4: + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" + integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +schema-utils@^2.6.5: + version "2.6.6" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.6.tgz#299fe6bd4a3365dc23d99fd446caff8f1d6c330c" + integrity sha512-wHutF/WPSbIi9x6ctjGGk2Hvl0VOz5l3EKEuKbjPlB30mKZUzb9A5k9yEXRX3pwyqVLPvpfZZEllaFq/M718hA== + dependencies: + ajv "^6.12.0" + ajv-keywords "^3.4.1" + +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-javascript@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" + integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +silent-error@^1.0.0, silent-error@^1.0.1, silent-error@^1.1.0, silent-error@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/silent-error/-/silent-error-1.1.1.tgz#f72af5b0d73682a2ba1778b7e32cd8aa7c2d8662" + integrity sha512-n4iEKyNcg4v6/jpb3c0/iyH2G1nzUNl7Gpqtn/mHIJK9S/q/7MCfoO4rwVOoO59qPFIc0hVHvMbiOJ0NdtxKKw== + dependencies: + debug "^2.2.0" + +simple-html-tokenizer@^0.5.9: + version "0.5.9" + resolved "https://registry.yarnpkg.com/simple-html-tokenizer/-/simple-html-tokenizer-0.5.9.tgz#1a83fe97f5a3e39b335fddf71cfe9b0263b581c2" + integrity sha512-w/3FEDN94r4JQ9WoYrIr8RqDIPZdyNkdpbK9glFady1CAEyD97XWCv8HFetQO21w81e7h7Nh59iYTyG1mUJftg== + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +snake-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.3.tgz#c598b822ab443fcbb145ae8a82c5e43526d5bbee" + integrity sha512-WM1sIXEO+rsAHBKjGf/6R1HBBcgbncKS08d2Aqec/mrDSpU80SiOU41hO7ny6DToHSyrlwTYzQBIK1FPSx4Y3Q== + dependencies: + dot-case "^3.0.3" + tslib "^1.10.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +socket.io-adapter@~1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz#ab3f0d6f66b8fc7fca3959ab5991f82221789be9" + integrity sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g== + +socket.io-client@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.3.0.tgz#14d5ba2e00b9bcd145ae443ab96b3f86cbcc1bb4" + integrity sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA== + dependencies: + backo2 "1.0.2" + base64-arraybuffer "0.1.5" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "~4.1.0" + engine.io-client "~3.4.0" + has-binary2 "~1.0.2" + has-cors "1.1.0" + indexof "0.0.1" + object-component "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + socket.io-parser "~3.3.0" + to-array "0.1.4" + +socket.io-parser@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.0.tgz#2b52a96a509fdf31440ba40fed6094c7d4f1262f" + integrity sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng== + dependencies: + component-emitter "1.2.1" + debug "~3.1.0" + isarray "2.0.1" + +socket.io-parser@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.4.0.tgz#370bb4a151df2f77ce3345ff55a7072cc6e9565a" + integrity sha512-/G/VOI+3DBp0+DJKW4KesGnQkQPFmUCbA/oO2QGT6CWxU7hLGWqU3tyuzeSK/dqcyeHsQg1vTe9jiZI8GU9SCQ== + dependencies: + component-emitter "1.2.1" + debug "~4.1.0" + isarray "2.0.1" + +socket.io@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.3.0.tgz#cd762ed6a4faeca59bc1f3e243c0969311eb73fb" + integrity sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg== + dependencies: + debug "~4.1.0" + engine.io "~3.4.0" + has-binary2 "~1.0.2" + socket.io-adapter "~1.1.0" + socket.io-client "2.3.0" + socket.io-parser "~3.4.0" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= + dependencies: + is-plain-obj "^1.0.0" + +sort-object-keys@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sort-object-keys/-/sort-object-keys-1.1.3.tgz#bff833fe85cab147b34742e45863453c1e190b45" + integrity sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg== + +sort-package-json@^1.23.1: + version "1.42.1" + resolved "https://registry.yarnpkg.com/sort-package-json/-/sort-package-json-1.42.1.tgz#4085582dfe83c60951673de2d5e4ce09dd47bd4e" + integrity sha512-+JgZVjEQhJuJ57RCUcF3rzESYCW/n3vCLWdhqBdPkerEgRTj5teGdJrCcj772zT1VzewqWk616/4xuRyIffyqQ== + dependencies: + detect-indent "^6.0.0" + detect-newline "3.1.0" + git-hooks-list "1.0.3" + globby "11.0.0" + is-plain-obj "2.1.0" + sort-object-keys "^1.1.3" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map-support@~0.5.12: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9" + integrity sha1-fsrxO1e80J2opAxdJp2zN5nUqvk= + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@0.4.x, source-map@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + integrity sha1-66T12pwNyZneaAMti092FzZSA2s= + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.1.x: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + integrity sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y= + dependencies: + amdefine ">=0.0.4" + +sourcemap-validator@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/sourcemap-validator/-/sourcemap-validator-1.1.1.tgz#3d7d8a399ccab09c1fedc510d65436e25b1c386b" + integrity sha512-pq6y03Vs6HUaKo9bE0aLoksAcpeOo9HZd7I8pI6O480W/zxNZ9U32GfzgtPP0Pgc/K1JHna569nAbOk3X8/Qtw== + dependencies: + jsesc "~0.3.x" + lodash.foreach "^4.5.0" + lodash.template "^4.5.0" + source-map "~0.1.x" + +spawn-args@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/spawn-args/-/spawn-args-0.2.0.tgz#fb7d0bd1d70fd4316bd9e3dec389e65f9d6361bb" + integrity sha1-+30L0dcP1DFr2ePew4nmX51jYbs= + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@^1.0.3: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" + integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sri-toolbox@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/sri-toolbox/-/sri-toolbox-0.2.0.tgz#a7fea5c3fde55e675cf1c8c06f3ebb5c2935835e" + integrity sha1-p/6lw/3lXmdc8cjAbz67XCk1g14= + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + 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" + +ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +stagehand@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stagehand/-/stagehand-1.0.0.tgz#79515e2ad3a02c63f8720c7df9b6077ae14276d9" + integrity sha512-zrXl0QixAtSHFyN1iv04xOBgplbT4HgC8T7g+q8ESZbDNi5uZbMtxLukFVXPJ5Nl7zCYvYcrT3Mj24WYCH93hw== + dependencies: + debug "^4.1.0" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +stealthy-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + +string-template@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" + integrity sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0= + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.trimend@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" + integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.trimleft@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz#4408aa2e5d6ddd0c9a80739b087fbc067c03b3cc" + integrity sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trimstart "^1.0.0" + +string.prototype.trimright@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz#c76f1cef30f21bbad8afeb8db1511496cfb0f2a3" + integrity sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trimend "^1.0.0" + +string.prototype.trimstart@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" + integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string_decoder@0.10, string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +styled_string@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/styled_string/-/styled_string-0.0.1.tgz#d22782bd81295459bc4f1df18c4bad8e94dd124a" + integrity sha1-0ieCvYEpVFm8Tx3xjEutjpTdEko= + +sum-up@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sum-up/-/sum-up-1.0.3.tgz#1c661f667057f63bcb7875aa1438bc162525156e" + integrity sha1-HGYfZnBX9jvLeHWqFDi8FiUlFW4= + dependencies: + chalk "^1.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + +symbol-tree@^3.2.2: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +symlink-or-copy@^1.0.0, symlink-or-copy@^1.0.1, symlink-or-copy@^1.1.8, symlink-or-copy@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/symlink-or-copy/-/symlink-or-copy-1.3.1.tgz#9506dd64d8e98fa21dcbf4018d1eab23e77f71fe" + integrity sha512-0K91MEXFpBUaywiwSSkmKjnGcasG/rVBXFLJz5DrgGabpYD6N+3yZrfD6uUIfpuTu65DZLHi7N8CizHc07BPZA== + +sync-disk-cache@^1.3.3: + version "1.3.4" + resolved "https://registry.yarnpkg.com/sync-disk-cache/-/sync-disk-cache-1.3.4.tgz#53a2c5a09d8f4bb53160bce182a456ad71574024" + integrity sha512-GlkGeM81GPPEKz/lH7QUTbvqLq7K/IUTuaKDSMulP9XQ42glqNJIN/RKgSOw4y8vxL1gOVvj+W7ruEO4s36eCw== + dependencies: + debug "^2.1.3" + heimdalljs "^0.2.3" + mkdirp "^0.5.0" + rimraf "^2.2.8" + username-sync "^1.0.2" + +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +tap-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/tap-parser/-/tap-parser-7.0.0.tgz#54db35302fda2c2ccc21954ad3be22b2cba42721" + integrity sha512-05G8/LrzqOOFvZhhAk32wsGiPZ1lfUrl+iV7+OkKgfofZxiceZWMHkKmow71YsyVQ8IvGBP2EjcIjE5gL4l5lA== + dependencies: + events-to-array "^1.0.1" + js-yaml "^3.2.7" + minipass "^2.2.0" + +tapable@^1.0.0, tapable@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +tar@^4.4.2: + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.8.6" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" + +temp@0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/temp/-/temp-0.9.0.tgz#61391795a11bd9738d4c4d7f55f012cb8f55edaa" + integrity sha512-YfUhPQCJoNQE5N+FJQcdPz63O3x3sdT4Xju69Gj4iZe0lBKOtnAMi0SLj9xKhGkcGhsxThvTJ/usxtFPo438zQ== + dependencies: + rimraf "~2.6.2" + +terser-webpack-plugin@^1.1.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" + integrity sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^2.1.2" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser@^4.1.2, terser@^4.3.9: + version "4.6.12" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.12.tgz#44b98aef8703fdb09a3491bf79b43faffc5b4fee" + integrity sha512-fnIwuaKjFPANG6MAixC/k1TDtnl1YlPLUlLVIxxGZUn1gfUx2+l3/zGNB72wya+lgsb50QBi2tUV75RiODwnww== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +testem@^2.17.0: + version "2.17.0" + resolved "https://registry.yarnpkg.com/testem/-/testem-2.17.0.tgz#1cb4a2a90524a088803dfe52fbf197a6fd73c883" + integrity sha512-PLkIlT523w5rTJPWwR4TL1EiAEa941ECV7d4pMqsB0YdnH+sCTz0loWMKCUSdhR+VijveAZ6anE/JHehE7KqMQ== + dependencies: + backbone "^1.1.2" + bluebird "^3.4.6" + charm "^1.0.0" + commander "^2.6.0" + compression "^1.7.4" + consolidate "^0.15.1" + execa "^1.0.0" + express "^4.10.7" + fireworm "^0.7.0" + glob "^7.0.4" + http-proxy "^1.13.1" + js-yaml "^3.2.5" + lodash.assignin "^4.1.0" + lodash.castarray "^4.4.0" + lodash.clonedeep "^4.4.1" + lodash.find "^4.5.1" + lodash.uniqby "^4.7.0" + mkdirp "^0.5.1" + mustache "^3.0.0" + node-notifier "^5.0.1" + npmlog "^4.0.0" + printf "^0.5.1" + rimraf "^2.4.4" + socket.io "^2.1.0" + spawn-args "^0.2.0" + styled_string "0.0.1" + tap-parser "^7.0.0" + tmp "0.0.33" + xmldom "^0.1.19" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +"textextensions@1 || 2": + version "2.6.0" + resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.6.0.tgz#d7e4ab13fe54e32e08873be40d51b74229b00fc4" + integrity sha512-49WtAWS+tcsy93dRt6P0P3AMD2m5PvXRhuEA0kaXos5ZLlujtYmpmFsB+QvWUSxE1ZsstmYXfQ7L40+EcQgpAQ== + +through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through2@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a" + integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== + dependencies: + readable-stream "2 || 3" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +through@~2.2.0, through@~2.2.7: + version "2.2.7" + resolved "https://registry.yarnpkg.com/through/-/through-2.2.7.tgz#6e8e21200191d4eb6a99f6f010df46aa1c6eb2bd" + integrity sha1-bo4hIAGR1OtqmfbwEN9Gqhxusr0= + +timed-out@^4.0.0, timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + +timers-browserify@^2.0.4: + version "2.0.11" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" + integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== + dependencies: + setimmediate "^1.0.4" + +tiny-lr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-1.1.1.tgz#9fa547412f238fedb068ee295af8b682c98b2aab" + integrity sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA== + dependencies: + body "^5.1.0" + debug "^3.1.0" + faye-websocket "~0.10.0" + livereload-js "^2.3.0" + object-assign "^4.1.0" + qs "^6.4.0" + +tmp@0.0.28: + version "0.0.28" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.28.tgz#172735b7f614ea7af39664fa84cf0de4e515d120" + integrity sha1-Fyc1t/YU6nrzlmT6hM8N5OUV0SA= + dependencies: + os-tmpdir "~1.0.1" + +tmp@0.0.33, tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tmp@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" + integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== + dependencies: + rimraf "^2.6.3" + +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +to-utf8@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/to-utf8/-/to-utf8-0.0.1.tgz#d17aea72ff2fba39b9e43601be7b3ff72e089852" + integrity sha1-0Xrqcv8vujm55DYBvns/9y4ImFI= + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +tough-cookie@^2.3.3, tough-cookie@^2.4.3, tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + +tree-sync@^1.2.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/tree-sync/-/tree-sync-1.4.0.tgz#314598d13abaf752547d9335b8f95d9a137100d6" + integrity sha512-YvYllqh3qrR5TAYZZTXdspnIhlKAYezPYw11ntmweoceu4VK+keN356phHRIIo1d+RDmLpHZrUlmxga2gc9kSQ== + dependencies: + debug "^2.2.0" + fs-tree-diff "^0.5.6" + mkdirp "^0.5.1" + quick-temp "^0.1.5" + walk-sync "^0.3.3" + +tree-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tree-sync/-/tree-sync-2.0.0.tgz#e51456731d5ac93b92f9a1d58dd383f76f0f2f39" + integrity sha512-AzeJnbmJjGVfWMTJ0T152fv8NDTbQc9ERY4nEs7Lmxd94Xah2bUS56+CcoTh6FB8qn2KjBMjC0mLNc731aVBqw== + dependencies: + debug "^2.2.0" + fs-tree-diff "^0.5.6" + mkdirp "^0.5.1" + quick-temp "^0.1.5" + walk-sync "^0.3.3" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= + +tslib@^1.10.0, tslib@^1.9.0: + version "1.11.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" + integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-fest@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" + integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== + +type-is@~1.6.17, type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +typescript-memoize@^1.0.0-alpha.3: + version "1.0.0-alpha.3" + resolved "https://registry.yarnpkg.com/typescript-memoize/-/typescript-memoize-1.0.0-alpha.3.tgz#699a5415f886694a8d6e2e5451bc28a39a6bc2f9" + integrity sha1-aZpUFfiGaUqNbi5UUbwoo5prwvk= + dependencies: + core-js "2.4.1" + +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + +uglify-js@^3.1.4: + version "3.9.1" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.9.1.tgz#a56a71c8caa2d36b5556cc1fd57df01ae3491539" + integrity sha512-JUPoL1jHsc9fOjVFHdQIhqEEJsQvfKDjlubcCilu8U26uZ73qOg8VsN8O1jbuei44ZPlwL7kmbAdM4tzaUvqnA== + dependencies: + commander "~2.20.3" + +underscore.string@^3.2.2, underscore.string@~3.3.4: + version "3.3.5" + resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.3.5.tgz#fc2ad255b8bd309e239cbc5816fd23a9b7ea4023" + integrity sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg== + dependencies: + sprintf-js "^1.0.3" + util-deprecate "^1.0.2" + +underscore@>=1.8.3: + version "1.10.2" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.10.2.tgz#73d6aa3668f3188e4adb0f1943bd12cfd7efaaaf" + integrity sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg== + +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" + integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== + dependencies: + crypto-random-string "^2.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +untildify@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" + integrity sha1-F+soB5h/dpUunASF/DEdBqgmouA= + dependencies: + os-homedir "^1.0.0" + +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +username-sync@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/username-sync/-/username-sync-1.0.2.tgz#0a3697909fb7b5768d29e2921f573acfdd427592" + integrity sha512-ayNkOJdoNSGNDBE46Nkc+l6IXmeugbzahZLSMkwvgRWv5y5ZqNY2IrzcgmkR4z32sj1W3tM3TuTUMqkqBzO+RA== + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util.promisify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.3.2, uuid@^3.3.3: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +validate-npm-package-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" + integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= + dependencies: + builtins "^1.0.3" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +w3c-hr-time@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + +walk-sync@^0.2.5: + version "0.2.7" + resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-0.2.7.tgz#b49be4ee6867657aeb736978b56a29d10fa39969" + integrity sha1-tJvk7mhnZXrrc2l4tWop0Q+jmWk= + dependencies: + ensure-posix-path "^1.0.0" + matcher-collection "^1.0.0" + +walk-sync@^0.3.0, walk-sync@^0.3.1, walk-sync@^0.3.2, walk-sync@^0.3.3: + version "0.3.4" + resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-0.3.4.tgz#cf78486cc567d3a96b5b2237c6108017a5ffb9a4" + integrity sha512-ttGcuHA/OBnN2pcM6johpYlEms7XpO5/fyKIr48541xXedan4roO8cS1Q2S/zbbjGH/BarYDAMeS2Mi9HE5Tig== + dependencies: + ensure-posix-path "^1.0.0" + matcher-collection "^1.0.0" + +walk-sync@^1.0.0, walk-sync@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-1.1.4.tgz#81049f3d8095479b49574cfa5f558d7a252b127d" + integrity sha512-nowc9thB/Jg0KW4TgxoRjLLYRPvl3DB/98S89r4ZcJqq2B0alNcKDh6pzLkBSkPMzRSMsJghJHQi79qw0YWEkA== + dependencies: + "@types/minimatch" "^3.0.3" + ensure-posix-path "^1.1.0" + matcher-collection "^1.1.1" + +walk-sync@^2.0.0, walk-sync@^2.0.2: + version "2.1.0" + resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-2.1.0.tgz#e214248e5f5cf497ddd87db5a2a02e47e29c6501" + integrity sha512-KpH9Xw64LNSx7/UI+3guRZvJWlDxVA4+KKb/4puRoVrG8GkvZRxnF3vhxdjgpoKJGL2TVg1OrtkXIE/VuGPLHQ== + dependencies: + "@types/minimatch" "^3.0.3" + ensure-posix-path "^1.1.0" + matcher-collection "^2.0.0" + +walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + dependencies: + makeerror "1.0.x" + +watch-detector@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/watch-detector/-/watch-detector-1.0.0.tgz#c7b722d8695fee9ab6071e0f38f258e6adb22609" + integrity sha512-siywMl3fXK30Tlpu/dUBHhlpxhQmHdguZ8OIb813eU9lrVmmsJa9k0+n1HtJ+7p3SzFCPq2XbmR3GUYpPC3TBA== + dependencies: + heimdalljs-logger "^0.1.10" + semver "^6.3.0" + silent-error "^1.1.1" + tmp "^0.1.0" + +watchpack@^1.5.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.1.tgz#280da0a8718592174010c078c7585a74cd8cd0e2" + integrity sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA== + dependencies: + chokidar "^2.1.8" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + dependencies: + defaults "^1.0.3" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +webpack-sources@^1.3.0, webpack-sources@^1.4.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@~4.28: + version "4.28.4" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.28.4.tgz#1ddae6c89887d7efb752adf0c3cd32b9b07eacd0" + integrity sha512-NxjD61WsK/a3JIdwWjtIpimmvE6UrRi3yG54/74Hk9rwNj5FPkA4DJCf1z4ByDWLkvZhTZE+P3C/eh6UD5lDcw== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-module-context" "1.7.11" + "@webassemblyjs/wasm-edit" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + acorn "^5.6.2" + acorn-dynamic-import "^3.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chrome-trace-event "^1.0.0" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.0" + json-parse-better-errors "^1.0.2" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + micromatch "^3.1.8" + mkdirp "~0.5.0" + neo-async "^2.5.0" + node-libs-browser "^2.0.0" + schema-utils "^0.4.4" + tapable "^1.1.0" + terser-webpack-plugin "^1.1.0" + watchpack "^1.5.0" + webpack-sources "^1.3.0" + +websocket-driver@>=0.5.1: + version "0.7.3" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9" + integrity sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg== + dependencies: + http-parser-js ">=0.4.0 <0.4.11" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" + integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-mimetype@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which@^1.2.14, which@^1.2.9, which@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wordwrap@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +workerpool@^2.3.0: + version "2.3.3" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-2.3.3.tgz#49a70089bd55e890d68cc836a19419451d7c81d7" + integrity sha512-L1ovlYHp6UObYqElXXpbd214GgbEKDED0d3sj7pRdFXjNkb2+un/AUcCkceHizO0IVI6SOGGncrcjozruCkRgA== + dependencies: + object-assign "4.1.1" + +workerpool@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-3.1.2.tgz#b34e79243647decb174b7481ab5b351dc565c426" + integrity sha512-WJFA0dGqIK7qj7xPTqciWBH5DlJQzoPjsANvc3Y4hNB0SScT+Emjvt0jPPkDBUjBNngX1q9hHgt1Gfwytu6pug== + dependencies: + "@babel/core" "^7.3.4" + object-assign "4.1.1" + rsvp "^4.8.4" + +workerpool@^5.0.1: + version "5.0.4" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-5.0.4.tgz#4f67cb70ff7550a27ab94de25b0b843cd92059a2" + integrity sha512-Sywova24Ow2NQ24JPB68bI89EdqMDjUXo4OpofK/QMD7C2ZVMloYBgQ5J3PChcBJHj2vspsmGx1/3nBKXtUkXQ== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + +ws@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + +ws@^7.1.2: + version "7.2.5" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.5.tgz#abb1370d4626a5a9cd79d8de404aa18b3465d10d" + integrity sha512-C34cIU4+DB2vMyAbmEKossWq2ZQDr6QEyuuCzWrM9zfw1sGc0mYiJ0UnG9zzNykt49C2Fi34hvr2vssFQRS6EA== + +ws@~6.1.0: + version "6.1.4" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9" + integrity sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA== + dependencies: + async-limiter "~1.0.0" + +xdg-basedir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" + integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + +xmlchars@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +xmldom@^0.1.19: + version "0.1.31" + resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.31.tgz#b76c9a1bd9f0a9737e5a72dc37231cf38375e2ff" + integrity sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ== + +xmlhttprequest-ssl@~1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" + integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yam@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/yam/-/yam-1.0.0.tgz#7f6c91dc0f5de75a031e6da6b3907c3d25ab0de5" + integrity sha512-Hv9xxHtsJ9228wNhk03xnlDReUuWVvHwM4rIbjdAXYvHLs17xjuyF50N6XXFMN6N0omBaqgOok/MCK3At9fTAg== + dependencies: + fs-extra "^4.0.2" + lodash.merge "^4.6.0" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" + integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= diff --git a/app/assets/javascripts/discourse-loader.js b/app/assets/javascripts/discourse-loader.js index 24f879f687..bafa10820a 100644 --- a/app/assets/javascripts/discourse-loader.js +++ b/app/assets/javascripts/discourse-loader.js @@ -19,9 +19,7 @@ var define, requirejs; default: Ember.ArrayProxy }, "@ember/component": { - default: Ember.Component, - TextArea: Ember.TextArea, - TextField: Ember.TextField + default: Ember.Component }, "@ember/controller": { default: Ember.Controller, @@ -129,6 +127,12 @@ var define, requirejs; "@ember/component/helper": { default: Ember.Helper }, + "@ember/component/text-field": { + default: Ember.TextField + }, + "@ember/component/text-area": { + default: Ember.TextArea + }, "@ember/error": { default: Ember.error }, @@ -259,6 +263,14 @@ var define, requirejs; function requireFrom(name, origin) { name = transformForAliases(name); + if (name === "discourse") { + // eslint-disable-next-line no-console + console.log( + "discourse has been moved to `discourse/app` - please update your code" + ); + name = "discourse/app"; + } + if (name === "discourse/models/input-validation") { // eslint-disable-next-line no-console console.log( diff --git a/app/assets/javascripts/discourse.js b/app/assets/javascripts/discourse.js deleted file mode 100644 index eea5c75640..0000000000 --- a/app/assets/javascripts/discourse.js +++ /dev/null @@ -1,223 +0,0 @@ -/*global Mousetrap:true*/ -import Application from "@ember/application"; -import EmberObject, { computed } from "@ember/object"; -import { buildResolver } from "discourse-common/resolver"; -import discourseComputed, { observes } from "discourse-common/utils/decorators"; -import FocusEvent from "discourse-common/mixins/focus-event"; -import deprecated from "discourse-common/lib/deprecated"; - -if (window.unsupportedBrowser) { - throw "Unsupported browser detected"; -} - -const _pluginCallbacks = []; - -const Discourse = Application.extend(FocusEvent, { - rootElement: "#main", - _docTitle: document.title, - RAW_TEMPLATES: {}, - __widget_helpers: {}, - customEvents: { - paste: "paste" - }, - - reset() { - this._super(...arguments); - - Mousetrap.reset(); - }, - - getURL(url) { - if (!url) return url; - - // if it's a non relative URL, return it. - if (url !== "/" && !/^\/[^\/]/.test(url)) return url; - - if (url[0] !== "/") url = "/" + url; - if (url.startsWith(Discourse.BaseUri)) return url; - - return Discourse.BaseUri + url; - }, - - getURLWithCDN(url) { - url = Discourse.getURL(url); - // only relative urls - if (Discourse.CDN && /^\/[^\/]/.test(url)) { - url = Discourse.CDN + url; - } else if (Discourse.S3CDN) { - url = url.replace(Discourse.S3BaseUrl, Discourse.S3CDN); - } - return url; - }, - - Resolver: buildResolver("discourse"), - - @observes("_docTitle", "hasFocus", "contextCount", "notificationCount") - _titleChanged() { - let title = this._docTitle || Discourse.SiteSettings.title; - - // if we change this we can trigger changes on document.title - // only set if changed. - if ($("title").text() !== title) { - $("title").text(title); - } - - let displayCount = this.displayCount; - let dynamicFavicon = this.currentUser && this.currentUser.dynamic_favicon; - if (displayCount > 0 && !dynamicFavicon) { - title = `(${displayCount}) ${title}`; - } - - document.title = title; - }, - - @discourseComputed("contextCount", "notificationCount") - displayCount() { - return this.currentUser && - this.currentUser.get("title_count_mode") === "notifications" - ? this.notificationCount - : this.contextCount; - }, - - @observes("contextCount", "notificationCount") - faviconChanged() { - if (this.currentUser && this.currentUser.get("dynamic_favicon")) { - let url = Discourse.SiteSettings.site_favicon_url; - - // Since the favicon is cached on the browser for a really long time, we - // append the favicon_url as query params to the path so that the cache - // is not used when the favicon changes. - if (/^http/.test(url)) { - url = Discourse.getURL("/favicon/proxied?" + encodeURIComponent(url)); - } - - var displayCount = this.displayCount; - - new window.Favcount(url).set(displayCount); - } - }, - - updateContextCount(count) { - this.set("contextCount", count); - }, - - updateNotificationCount(count) { - if (!this.hasFocus) { - this.set("notificationCount", count); - } - }, - - incrementBackgroundContextCount() { - if (!this.hasFocus) { - this.set("backgroundNotify", true); - this.set("contextCount", (this.contextCount || 0) + 1); - } - }, - - @observes("hasFocus") - resetCounts() { - if (this.hasFocus && this.backgroundNotify) { - this.set("contextCount", 0); - } - this.set("backgroundNotify", false); - - if (this.hasFocus) { - this.set("notificationCount", 0); - } - }, - - authenticationComplete(options) { - // TODO, how to dispatch this to the controller without the container? - const loginController = Discourse.__container__.lookup("controller:login"); - return loginController.authenticationComplete(options); - }, - - // Start up the Discourse application by running all the initializers we've defined. - start() { - $("noscript").remove(); - - Object.keys(requirejs._eak_seen).forEach(function(key) { - if (/\/pre\-initializers\//.test(key)) { - const module = requirejs(key, null, null, true); - if (!module) { - throw new Error(key + " must export an initializer."); - } - - const init = module.default; - const oldInitialize = init.initialize; - init.initialize = function() { - oldInitialize.call(this, Discourse.__container__, Discourse); - }; - - Discourse.initializer(init); - } - }); - - Object.keys(requirejs._eak_seen).forEach(function(key) { - if (/\/initializers\//.test(key)) { - const module = requirejs(key, null, null, true); - if (!module) { - throw new Error(key + " must export an initializer."); - } - - const init = module.default; - const oldInitialize = init.initialize; - init.initialize = function() { - oldInitialize.call(this, Discourse.__container__, Discourse); - }; - - Discourse.instanceInitializer(init); - } - }); - - // Plugins that are registered via ` - JAVASCRIPT - end - end -end diff --git a/plugins/discourse-internet-explorer/spec/requests/bootstrap_request_spec.rb b/plugins/discourse-internet-explorer/spec/requests/bootstrap_request_spec.rb deleted file mode 100644 index 34a6213afe..0000000000 --- a/plugins/discourse-internet-explorer/spec/requests/bootstrap_request_spec.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe 'Bootstrapping the Discourse App' do - let(:ie_agent) { "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko" } - - context "when disabled" do - before do - SiteSetting.discourse_internet_explorer_enabled = false - end - - it "does not include the IE stylesheet or Javascript" do - get "/categories", headers: { "HTTP_USER_AGENT" => ie_agent } - expect(response.body).not_to match(/discourse-internet-explorer-optional.js/) - expect(response.body).not_to match(/stylesheets\/discourse-internet-explorer/) - end - end - - context "when enabled" do - before do - SiteSetting.discourse_internet_explorer_enabled = true - end - - it "includes the IE js and css" do - get "/categories", headers: { "HTTP_USER_AGENT" => ie_agent } - expect(response.body).to match(/discourse-internet-explorer-optional.js/) - expect(response.body).to match(/stylesheets\/discourse-internet-explorer/) - end - - it "doesn't include IE stuff for non-IE browsers" do - get "/categories", headers: { "HTTP_USER_AGENT" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36" } - expect(response.body).not_to match(/discourse-internet-explorer-optional.js/) - expect(response.body).not_to match(/stylesheets\/discourse-internet-explorer/) - end - end -end diff --git a/plugins/discourse-local-dates/config/locales/client.bg.yml b/plugins/discourse-local-dates/config/locales/client.bg.yml index 5e1382b35c..fa9d1e7b1b 100644 --- a/plugins/discourse-local-dates/config/locales/client.bg.yml +++ b/plugins/discourse-local-dates/config/locales/client.bg.yml @@ -12,3 +12,4 @@ bg: form: date_title: Дата time_title: 'Време ' + timezone: Часова зона diff --git a/plugins/discourse-local-dates/config/locales/client.hy.yml b/plugins/discourse-local-dates/config/locales/client.hy.yml index b9fe770315..ead8396f92 100644 --- a/plugins/discourse-local-dates/config/locales/client.hy.yml +++ b/plugins/discourse-local-dates/config/locales/client.hy.yml @@ -27,3 +27,4 @@ hy: date_title: Ամսաթիվ time_title: Ժամ format_title: Ամսաթվի ֆորմատ + timezone: Ժամային գոտի diff --git a/plugins/discourse-local-dates/config/locales/client.ko.yml b/plugins/discourse-local-dates/config/locales/client.ko.yml index 6d98a6c311..4bd9d3ab6f 100644 --- a/plugins/discourse-local-dates/config/locales/client.ko.yml +++ b/plugins/discourse-local-dates/config/locales/client.ko.yml @@ -12,6 +12,9 @@ ko: today: 오늘 %{time} tomorrow: 내일 %{time} yesterday: 어제 %{time} + countdown: + passed: 날짜가 지났습니다 + title: 날짜 / 시간 삽입 create: form: insert: 삽입 @@ -28,6 +31,7 @@ ko: time_title: 시간 format_title: 날짜 형식 timezone: 시간대 + until: 까지... recurring: every_day: "매일" every_week: "매주" diff --git a/plugins/discourse-local-dates/config/locales/server.zh_CN.yml b/plugins/discourse-local-dates/config/locales/server.zh_CN.yml index 4436de82ba..448a8140cb 100644 --- a/plugins/discourse-local-dates/config/locales/server.zh_CN.yml +++ b/plugins/discourse-local-dates/config/locales/server.zh_CN.yml @@ -7,7 +7,7 @@ zh_CN: site_settings: - discourse_local_dates_enabled: "启用话语本地日期功能。这将使用[date]元素添加对帖子中本地日期的时区感知支持。" + discourse_local_dates_enabled: "启用discourse-local-dates功能。这将在使用[date]元素的帖子中添加对本地时区感知日期的支持。" discourse_local_dates_default_formats: "经常使用的日期时间格式,请参阅: momentjs字符串格式" discourse_local_dates_default_timezones: "默认的时区列表,必须是有效的TZ" discourse_local_dates_email_format: "用于在电子邮件中显示的日期格式。" diff --git a/plugins/discourse-narrative-bot/assets/javascripts/initializers/new-user-narrative.js.es6 b/plugins/discourse-narrative-bot/assets/javascripts/initializers/new-user-narrative.js.es6 index 6498f501b3..cc4c3d1bc1 100644 --- a/plugins/discourse-narrative-bot/assets/javascripts/initializers/new-user-narrative.js.es6 +++ b/plugins/discourse-narrative-bot/assets/javascripts/initializers/new-user-narrative.js.es6 @@ -14,25 +14,25 @@ function initialize(api) { }); api.modifyClass("model:post", { - toggleBookmarkWithReminder() { + toggleBookmark() { // if we are talking to discobot then any bookmarks should just // be created without reminder options, to streamline the new user // narrative. const discobotUserId = -2; - if (this.user_id === discobotUserId && !this.bookmarked_with_reminder) { + if (this.user_id === discobotUserId && !this.bookmarked) { return ajax("/bookmarks", { type: "POST", data: { post_id: this.id } }).then(response => { this.setProperties({ "topic.bookmarked": true, - bookmarked_with_reminder: true, + bookmarked: true, bookmark_id: response.id }); this.appEvents.trigger("post-stream:refresh", { id: this.id }); }); } - this._super(); + return this._super(); } }); diff --git a/plugins/discourse-narrative-bot/config/locales/server.bg.yml b/plugins/discourse-narrative-bot/config/locales/server.bg.yml index 1a726b66b8..51fed3681e 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.bg.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.bg.yml @@ -17,3 +17,6 @@ bg: new_user_narrative: hello: title: "Привет!" + bookmark: + instructions: |- + Ако искате да научите повече, изберете отдолу и **отметнете това лично съобщение**. Ако го направите, може да има :подарък: в бъдещето ви! diff --git a/plugins/discourse-narrative-bot/config/locales/server.bs_BA.yml b/plugins/discourse-narrative-bot/config/locales/server.bs_BA.yml index 61cce204f3..4a0f84b0d0 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.bs_BA.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.bs_BA.yml @@ -121,11 +121,6 @@ bs_BA: random_mention: reply: |- Pozdrav! Kako bi saznali šta sve mogu raditi, recite `@%{discobot_username} %{help_trigger}`. - tracks: |- - Trenutno znam kako uraditi sljedeće stvari: - - `@%{discobot_username} %{reset_trigger} {ime-tutorijala}` - > Starta interaktivni tutorijal. `{ime-tutorijala}` može biti jedan od `%{tracks}`. bot_actions: |- `@%{discobot_username} %{dice_trigger} 2d6` > :game_die: 3, 6 diff --git a/plugins/discourse-narrative-bot/config/locales/server.ca.yml b/plugins/discourse-narrative-bot/config/locales/server.ca.yml index 914e221e11..b930eeab10 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.ca.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.ca.yml @@ -117,11 +117,6 @@ ca: random_mention: reply: |- Hola! Per a trobar què puc fer, digueu `@%{discobot_username} %{help_trigger}`. - tracks: |- - Ara sé com fer les coses següents: - - `@ %{discobot_username} %{reset_trigger} {name-of-tutorial}` - > Inicia un tutorial interactiu. El `{name-of-tutorial}` pot ser un dels següents: `%{tracks}`. bot_actions: |- `@%{discobot_username} %{dice_trigger} 2d6` > :game_die: 3, 6 diff --git a/plugins/discourse-narrative-bot/config/locales/server.de.yml b/plugins/discourse-narrative-bot/config/locales/server.de.yml index 5f7ea53588..0f306d35be 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.de.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.de.yml @@ -121,11 +121,6 @@ de: random_mention: reply: |- Hallo! Um herauszufinden, was ich kann, schreibe `@%{discobot_username} %{help_trigger}`. - tracks: |- - Ich weiß jetzt, wie man die folgenden Dinge macht: - - `@%{discobot_username} %{reset_trigger} {Name-des-Tutorials}` - > Startet ein interaktives Tutorial. `{Name-des-Tutorials}` kann eins von: `%{tracks}` sein. bot_actions: |- `@%{discobot_username} %{dice_trigger} 2d6` > :game_die: 3, 6 diff --git a/plugins/discourse-narrative-bot/config/locales/server.en.yml b/plugins/discourse-narrative-bot/config/locales/server.en.yml index 86d081b5bb..38bad9ac85 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.en.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.en.yml @@ -127,7 +127,7 @@ en: I currently know how to do the following things: `@%{discobot_username} %{reset_trigger} {name-of-tutorial}` - > Starts an interactive tutorial. `{name-of-tutorial}` can be one of: `%{tracks}`. + > Starts an interactive tutorial just for you, in a personal message. `{name-of-tutorial}` can be one of: `%{tracks}`. bot_actions: |- `@%{discobot_username} %{dice_trigger} 2d6` > :game_die: 3, 6 diff --git a/plugins/discourse-narrative-bot/config/locales/server.es.yml b/plugins/discourse-narrative-bot/config/locales/server.es.yml index 75451434cc..c38c9ba1c3 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.es.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.es.yml @@ -121,11 +121,6 @@ es: random_mention: reply: |- ¡Hola! Para saber qué puedo hacer, escribe `@%{discobot_username} %{help_trigger}`. - tracks: |- - Actualmente sé como realizar las siguientes cosas: - - `@%{discobot_username} %{reset_trigger} {nombre-del-tutorial}` - > Comienza un tutorial interactivo. `{nombre-del-tutorial}` puede ser uno de: `%{tracks}`. bot_actions: |- `@%{discobot_username} %{dice_trigger} 2d6` > :game_die: 3, 6 @@ -230,6 +225,8 @@ es: bookmark: instructions: |- Si quieres aprender más, selecciona debajo el botón y **guarda en marcadores este mensaje personal**. Si lo haces, ¡puede haber un :gift: en tu futuro! + reply: |- + ¡Excelente! Ahora puedes encontrar fácilmente las conversaciones privadas en cualquier momento directamente desde la [sección de marcadores de tu perfil](%{bookmark_url}). Sólo debes seleccionar tu foto de perfil en la parte superior derecha de la pantalla ↗ not_found: |- Oh oh, no veo ningún marcador en este tema. ¿Encontraste el botón para guardar en marcadores que se encuentra debajo de cada mensaje? Usa el botón mostrar más para que aparezcan acciones adicionales si necesitas. emoji: diff --git a/plugins/discourse-narrative-bot/config/locales/server.fi.yml b/plugins/discourse-narrative-bot/config/locales/server.fi.yml index 20846f8be2..5ba202794b 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.fi.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.fi.yml @@ -121,11 +121,6 @@ fi: random_mention: reply: |- Moi! Jos haluat tietää mitä osaan, sano `@%{discobot_username} %{help_trigger}`. - tracks: |- - Osaan tehdä seuraavat asiat: - - `@%{discobot_username}%{reset_trigger}{name-of-tutorial}` - > Aloittaa interaktiivisen kurssin. `{name-of-tutorial} ` voi olla jokin seuraavista: `%{tracks}`. bot_actions: |- `@%{discobot_username} %{dice_trigger} 2d6` > :game_die: 3, 6 diff --git a/plugins/discourse-narrative-bot/config/locales/server.fr.yml b/plugins/discourse-narrative-bot/config/locales/server.fr.yml index 822cd2e85f..bc1ffdbaa5 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.fr.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.fr.yml @@ -121,11 +121,6 @@ fr: random_mention: reply: |- Bonjour ! Pour voir ce que je peux faire, dites `@%{discobot_username} `. - tracks: |- - Pour le moment, je sais faire les choses suivantes : - - `@%{discobot_username} %{reset_trigger} {nom-du-tutoriel}` - > Débute un tutoriel interactif. `{nom-du-tutoriel}` est l'une des options suivantes : `%{tracks}`. bot_actions: |- `@%{discobot_username} %{dice_trigger} 2d6` > :game_die: 3, 6` diff --git a/plugins/discourse-narrative-bot/config/locales/server.he.yml b/plugins/discourse-narrative-bot/config/locales/server.he.yml index 61c91465e4..29e96d79ba 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.he.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.he.yml @@ -124,8 +124,8 @@ he: tracks: |- אלו הפעולות שאני יודע לבצע נכון להיום: - ‏`@%{discobot_username} %{reset_trigger} {name-of-tutorial}‏` - > מתחיל מדריך אינטראקטיבי. `{name-of-tutorial}` יכול להיות כל אחד מבין: `%{tracks}`. + ‎`@%{discobot_username} %{reset_trigger} {name-of-tutorial}`‎ + > מתחיל מדריך אינטראקטיבי עבורך בלבד, בהודעה פרטית. `{name-of-tutorial}` יכול להיות כל אחד מבין: `%{tracks}`. bot_actions: |- `@%{discobot_username} %{dice_trigger} 2d6` > :game_die: 3, 6 diff --git a/plugins/discourse-narrative-bot/config/locales/server.hu.yml b/plugins/discourse-narrative-bot/config/locales/server.hu.yml index eac0a00872..c252a7096d 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.hu.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.hu.yml @@ -9,33 +9,68 @@ hu: site_settings: discourse_narrative_bot_enabled: "A Discourse alámondó bot (discobot) bekapcsolása" disable_discourse_narrative_bot_welcome_post: "A Discourse alámondó bot üdvözlő üzenetének kikapcsolása" - discourse_narrative_bot_ignored_usernames: "Felhasználónevek, amelyeket a Discourse alámondó bot figyelmen kívül hagyjon" + discourse_narrative_bot_ignored_usernames: "Felhasználónevek, amelyeket a Discourse alámondó bot hagyjon figyelmen kívül" discourse_narrative_bot_disable_public_replies: "A Discourse alámondó bot nyilvános válaszainak kikapcsolása" - discourse_narrative_bot_welcome_post_type: "A Discourse mesélő bot üdvözlő üzeneteinek kiküldendő típusai" - discourse_narrative_bot_welcome_post_delay: "Várj (n) másodpercet a Discourse mesélő bot üdvözlő üzenetének kiküldése előtt." + discourse_narrative_bot_welcome_post_type: "A Discourse alámondó bot üdvözlő üzeneteinek kiküldendő típusai" + discourse_narrative_bot_welcome_post_delay: "Várjon (n) másodpercet a Discourse alámondó bot üdvözlő üzenetének kiküldése előtt." badges: certified: name: Hitelesített description: "Teljesítette az új felhasználók eligazítását" long_description: | - Ezt a jelvényt az új felhasználók interaktív eligazításának sikeres teljesítéséért adjuk. Kezdeményező voltál és megtanultad a beszélgetés alapvető eszközeit, és ezzel hitelesített lettél! + Ez a jelvényt az interaktív új felhasználói eligazítás sikeres teljesítéséért jár. Kezdeményező volt és megtanulta a beszélgetés alapvető eszközeit, és ezzel hitelesített lett! licensed: - name: Licenszelt + name: Licencelt + description: "Teljesítette az haladó felhasználói eligazítást" + long_description: | + Ez a jelvényt az interaktív haladó felhasználói eligazítás sikeres teljesítéséért jár. Elsajátította a beszélgetés speciális eszközeit, és ezzel teljesen licencelt lett! discourse_narrative_bot: + bio: "Üdv, nem igazi személy vagyok. Egy bot vagyok, és megtanítom az oldal használatát. A velem történő interakcióhoz küldjön nekem egy üzenetet, vagy említsen meg így bárhol: **`@%{discobot_username}`**." + tl2_promotion_message: + subject_template: "Gratulálunk az első bizalmi szint előléptetéséért!" + text_body_template: | + Most hogy előléptették, ideje megtanulnia néhány speciális funkciót! + + Válaszoljon erre az üzenetre ezzel: `@%{discobot_username} %{reset_trigger}`, hogy többet tudjon meg arról, hogy mit tehet. + + Arra kérjük, hogy továbbra is vegyen részt – örülünk, hogy itt van. + timeout: + message: |- + Üdv @%{username}, csak beköszönök, mert nem hallottam Önről egy ideje. + + - A folytatáshoz válaszoljon bármikor. + + - Ha kihagyná ezt a lépést, mondja ezt: `%{skip_trigger}`. + + - Az újrakezdéshez mondja ezt: `%{reset_trigger}`. + + Ha inkább nem tenné, az is rendben van. Én egy robot vagyok. Nem fogja megbántani az érzéseimet. :sob: + dice: + trigger: "kockadobás" + invalid: |- + Sajnálom, matematikailag lehetetlen ezt a kockakombinációt dobni. :confounded: + not_enough_dice: |- + Csak %{num_of_dice} kockám van. [Szégyenletes](http://www.therobotsvoice.com/2009/04/the_10_most_shameful_rpg_dice.php), tudom! + out_of_range: |- + Tudta, hogy a [legtöbb oldallal rendelkező](https://www.wired.com/2016/05/mathematical-challenge-of-designing-the-worlds-most-complex-120-sided-dice) matematikailag fair kocka 120 oldalas? + results: |- + > :game_die: %{results} quote: trigger: "idézet" '1': - quote: "Minden nehézség közepében lehetőség rejtőzik" + quote: "A nehézségek közt mindig ott van a lehetőség" author: "Albert Einstein" '2': author: "Mahatma Gandhi" '3': - quote: "Ne azért sírj, mert vége van, mosolyogj azért, mert megtörtént." + quote: "Ne sírj, hogy vége, mosolyogj, hogy megtörtént." + author: "Dr. Seuss" '4': author: "Charles-Guillaume Étienne" '5': author: "Theodore Roosevelt" '6': + quote: " Az élet olyan, mint egy doboz bonbon. Soha nem tudhatod, hogy mi jut neked belőle." author: "Forrest Gump édesanyja" '7': quote: "Kis lépés egy embernek, de hatalmas ugrás az emberiségnek." @@ -46,16 +81,70 @@ hu: author: "Bruce Lee" '10': author: "Napoleon Hill" + results: |- + > :left_speech_bubble: _%{quote}_ — %{author} magic_8_ball: + trigger: "jövendőmondás" answers: + '1': "Biztos" + '2': "Határozottan így van" '3': "Kétségtelenül" - '7': "Leginkább" + '4': "Igen, határozottan" + '5': "Számíthatsz rá" + '6': "Ahogy látom, igen" + '7': "Egészen valószínű" + '8': "Jók a kilátások" '9': "Igen" - '12': "Kérdezd meg később" - '17': "A válaszom nem." + '10': "A jelek szerint igen" + '11': "A válasz ködös, próbálja újra" + '12': "Kérdezze meg később" + '13': "Jobb, ha most nem mondom el" + '14': "Most nem tudom megjósolni" + '15': "Koncentráljon és kérdezzen újra" + '16': "Ne számítson rá" + '17': "A válaszom nem" + '18': "A forrásaim szerint nem" + '19': "Nem túl jók a kilátások" + '20': "Nagyon kétséges" + result: |- + > :crystal_ball: %{result} track_selector: - reset_trigger: "start" + reset_trigger: "kezdés" skip_trigger: "átugrás" + help_trigger: "súgó megjelenítése" + random_mention: + reply: |- + Üdv! Hogy megtudja mit tudok, mondja ezt: `@%{discobot_username} %{help_trigger}`. + bot_actions: |- + `@%{discobot_username} %{dice_trigger} 2d6` + > :game_die: 3, 6 + + `@%{discobot_username} %{quote_trigger}` + %{quote_sample} + + `@%{discobot_username} %{magic_8_ball_trigger}` + > :crystal_ball: Számíthat rá + do_not_understand: + first_response: |- + Hé, köszönöm a választ! + + Sajnos mivel egy rosszul programozott bot vagyok, ezt nem egészen értettem. :frowning: + track_response: 'Megpróbálhatja újra, vagy kihagyhatja a lépést, csak mondja ezt: `%{skip_trigger}`. + + Egyébként az újrakezdéshez mondja ezt: `%{reset_trigger}`.' + second_response: |- + Sajnálom. Még mindig nem értem. :anguished: + + Csak egy bot vagyok, de ha egy valódi emberrel akar beszélni, keresse fel a [kapcsolat oldalunkat](%{base_path}/about). + + Addig is, elállok az útból. new_user_narrative: + reset_trigger: "oktatás" + title: "Új felhasználói eligazítás elvégzési tanúsítványa" + cert_title: "Az új felhasználói eligazítás teljesítése elismeréseképp" hello: title: "Üdvözlet!" + certificate: + alt: "Igazoló oklevél" + advanced_user_narrative: + reset_trigger: "haladó oktatás" diff --git a/plugins/discourse-narrative-bot/config/locales/server.it.yml b/plugins/discourse-narrative-bot/config/locales/server.it.yml index 265b4e8aee..3d9ef99743 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.it.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.it.yml @@ -122,10 +122,10 @@ it: reply: |- Ciao! Per sapere cosa posso fare, dimmi `@%{discobot_username} %{help_trigger}`. tracks: |- - Al momento so fare le seguenti cose: + Attualmente so come fare le seguenti cose: `@%{discobot_username} %{reset_trigger} {name-of-tutorial}` - > Inizia un tutorial interattivo. `{name-of-tutorial}` può essere uno di: `%{tracks}`. + > Avvia un tutorial interattivo solo per te, in un messaggio personale. `{name-of-tutorial}` può essere uno di: `%{tracks}`. bot_actions: |- `@%{discobot_username} %{dice_trigger} 2d6` > :game_die: 3, 6 @@ -231,7 +231,7 @@ it: Selezionare un qualsiasi testo del mio messaggio farà apparire il pulsante **Cita**. E anche premere **Rispondi** con qualsiasi testo selezionato funzionerà! Puoi provare di nuovo? bookmark: instructions: |- - Se vuoi saperne di più, seleziona qui sotto e **inserisci questo messaggio personale nei segnalibri**. Se lo farai, ci potrebbe essere un :gift: per te! + Se vuoi saperne di più, seleziona qui sotto e **inserisci questo messaggio personale nei segnalibri**. Se lo farai, ci potrebbe essere un :gift: per te in futuro! reply: | Eccellente! Ora puoi facilmente tornare alla nostra conversazione privata in qualsiasi momento, direttamente dalla [scheda dei segnalibri sul tuo profilo](%{bookmark_url}). Basta selezionare la tua foto del profilo in alto a destra ↗ not_found: |- diff --git a/plugins/discourse-narrative-bot/config/locales/server.ko.yml b/plugins/discourse-narrative-bot/config/locales/server.ko.yml index 5983e258db..3c92877fa9 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.ko.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.ko.yml @@ -26,6 +26,8 @@ ko: 이 배지는 고급 유저 튜토리얼을 성공적으로 완료한 사용자에게 부여됩니다. 당신은 고급 토론 도구를 숙지하여 면허를 취득하였습니다! discourse_narrative_bot: bio: "안녕, 사실 나는 사람이 아니야. 이 사이트에 대해서 알려주는 로봇이지. 나한테 물어보고 싶은 게 있다면 메세지를 보내거나 **`@%{discobot_username}`** 를 멘션하면 돼." + tl2_promotion_message: + subject_template: "신뢰 수준 프로모션을 축하합니다!" timeout: message: |- 안녕 @%{username}, 너한테서 소식이 없어서 한 번 말 걸어봤어. @@ -94,6 +96,7 @@ ko: '8': "좋을 전망." '9': "응." '10': "괜찮아 보이는군." + '11': "흐릿한 답글, 다시 시도" '12': "다음에 다시 물어봐." '13': "지금은 말하지 않는 편이 낫겠어." '14': "지금은 예측할 수 없어." @@ -125,8 +128,16 @@ ko: 그럼, 난 잠시 자리를 비워줄게. new_user_narrative: + reset_trigger: "지도 시간" + title: "새로운 사용자 튜토리얼 수료증" cert_title: "새로운 사용자 튜토리얼을 성공적으로 마친 것에 대한 보상으로" + hello: + title: "인사말!" + message: |- + %{title}에 참여해 주셔서 감사합니다. -나는 로봇 일 뿐이지 만 [친근한 직원] (%{base_uri} / about)도 사람과 연락해야 할 경우 도움을주기 위해 여기에 있습니다. -안전상의 이유로 신규 사용자가 할 수있는 일을 일시적으로 제한합니다. 우리가 당신을 알게되면 [새로운 능력] (https://blog.discourse.org/2018/06/understanding-discourse-trust-levels/) (그리고 [badges] (%{base_uri} / badges))을 얻게됩니다. -우리는 항상 [civilized community behavior] (%{base_uri} / guidelines)를 믿습니다. onebox: + instructions: |- + 다음으로이 링크 중 하나를 나와 공유 할 수 있습니까? ** 한 줄에 링크 **로 답장하면 자동으로 확장되어 멋진 요약을 포함합니다. 링크를 복사하려면 모바일을 길게 누르거나 포인팅 장치를 마우스 오른쪽 버튼으로 클릭하십시오. reply: |- 좋았어! 이건 대부분의 링크에 대해서 작동해. 딱 링크로만 된 한줄이어야만 한다는 걸 명심해. 앞이나 뒤에 다른게 있어서는 안돼. not_found: |- @@ -187,6 +198,10 @@ ko: 내 포스트에서 아무 글이나 선택해도 **인용하기** 버튼이 뜰거야. 글을 선택하고 **답글쓰기** 를 눌러도 돼! 다시 한 번 해 볼래? bookmark: + instructions: |- + 자세한 내용을 알아 보려면 아래와 **이 개인 메시지를 북마크하십시오 **. 당신이하는 경우 : 선물 : 미래에있을 수 있습니다! + reply: |- + 우수한! 이제 [프로필의 북마크 탭] (%{bookmark_url})에서 언제든지 개인 대화로 쉽게 돌아갈 수 있습니다. 오른쪽 상단에서 프로필 사진을 선택하십시오. ↗ not_found: |- 어라, 이 토픽에는 북마크가 없는데? 포스트 별로 있는 북마크 버튼을 찾았니? 더 보기 를 눌러서 필요한 추가 기능이 있는지 살펴 봐. emoji: @@ -226,6 +241,8 @@ ko: > :imp: 어쩌고 저쩌고 나쁜 글 뭘 할지 잘 알고 있지? **이 포스트 신고하기** 를 눌러서 부적절하다고 알려줘! + reply: |- + [우리의 직원] (%{base_uri} / groups / staff)는 귀하의 깃발에 대해 개인적으로 통지를받습니다. 커뮤니티 회원이 충분하면 게시물을 신고하면 예방 조치로 자동 숨겨집니다. (나는 실제로 불쾌한 게시물을 작성하지 않았기 때문에 : angel :, 나는 지금 나아가서 깃발을 제거했습니다.) not_found: |- 이런 내가 쓴 나쁜 포스트가 아직 신고가 안됐네. :worried: 부적절한 게시물로 **신고** 해주겠니 ? 더 보기 버튼을 누르면 포스트에 수행할 기능을 더 볼 수 있다는 걸 잊지마. search: @@ -233,6 +250,8 @@ ko: 이봐, 내가 이 토픽에 놀라운 걸 숨겼다구. 찾아보고 싶다면, 우측 상단에 있는 **검색 아이콘을** 선택해서 ↗ 찾아봐. 이 토픽에서 "capy​bara"를 찾으면 돼. + hidden_message: |- + 이 capybara를 어떻게 그리워 했습니까? :눈짓: 당신이 지금 처음에 돌아 왔음을 알았습니까? `%{search_answer}` 그림 이모티콘 **을 사용하여이 가난한 배고픈 카피 바라에게 먹이를 주면 자동으로 끝납니다. reply: |- 예이, 찾았네! :tada: @@ -243,11 +262,17 @@ ko: - 진짜 실물 :keyboard:가 있다면, ?를 눌러서 간편한 단축키가 뭐가 있는지 알아봐. not_found: |- 흠.... 아무래도 문제가 있어 보이네. 미안해. 검색을 눌러서 **capy​bara**를 찾아봤어? + end: + message: |- + @ %{username}와 함께 해 주셔서 감사합니다! 나는 당신을 위해 이것을 만들었다, 나는 당신이 그것을 얻은 것 같아 : %{certificate} 그게 다야! [** 최신 토론 주제 **] (%{base_uri} / latest) 또는 [** 토론 범주 **] (%{base_uri} / categories)를 확인하십시오. : 선글라스 : (더 많은 것을 배우기 위해 다시 나와 이야기하고 싶다면 언제든지 메시지를 보내거나`@ %{discobot_username} '를 언급하십시오!) certificate: alt: "목표달성 인증" advanced_user_narrative: + reset_trigger: "고급 튜토리얼" cert_title: "고급 사용자 튜토리얼을 훌륭하게 완료한 것에 대한 보상으로" title: ":arrow_up: 고급 사용자 기능" + start_message: |- + _advanced_ 사용자로서 [기본 설정 페이지] (%{base_uri} / my / preferences)를 방문했지만 아직 @ %{username}? 어둡거나 밝은 테마를 선택하는 등 다양한 방법으로 경험을 사용자 지정할 수 있습니다. 그러나 나는 출발한다, 시작하자! edit: bot_created_post_raw: "@%{discobot_username}는 내가 아는 한, 현존하는 가장 쿨한 봇이지:wink:" instructions: |- @@ -281,10 +306,40 @@ ko: **삭제 취소하기**를 부탁해도 될까? not_found: |- 잘 안되니? 더 보기를 누르면 삭제 취소하기가 보일거야. + reply: |- + 휴, 그것은 가까운 사람이었다! : wink : 게시물을 삭제 취소 할 수있는 시간은 %{deletion_after}입니다. category_hashtag: instructions: |- 포스트에 카테고리나 태그를 언급할 수 있다는 거 알고 있어? 예를 들어, %{category} 카테고리가 보이니? 문장 중간에 `#`을 넣고 어떤 카테고리나 태그든 선택해봐. + not_found: |- + 흠, 나는 어디에도 카테고리가 보이지 않습니다. `#`는 첫 번째 문자가 될 수 없습니다. 다음 답장에서이 내용을 복사 할 수 있습니까? ```텍스트 # #``을 통해 카테고리 링크를 만들 수 있습니다 + reply: |- + 우수한! 태그가 활성화 된 경우 두 카테고리 _and_ 태그 모두에서 작동합니다. + change_topic_notification_level: + instructions: |- + 모든 주제에는 알림 수준이 있습니다. '정상'으로 시작합니다. 즉, 누군가가 나와 직접 대화 할 때만 알림을받습니다. 기본적으로 비공개 메시지의 알림 수준은 '감시'의 최상위 수준으로 설정되므로 모든 새 회신에 대해 알림을받습니다. 그러나 _any_ 주제의 알림 수준을 '감시', '추적'또는 '음소거 됨'으로 무시할 수 있습니다. 이 주제에 대한 알림 수준을 변경해 봅시다. 주제 하단에이 주제를보고 있음을 나타내는 버튼이 있습니다. 알림 수준을 ** 추적 **으로 변경할 수 있습니까? + not_found: |- + 아직도보고있는 것 같습니다 : 눈 :이 주제! 찾는 데 문제가 있으면 알림 수준 버튼이 주제 하단에 있습니다. + reply: |- + 멋진 일! 나는 때때로 약간 대화가 가능하기 때문에이 주제를 무시하지 않기를 바랍니다. : grin :. 주제에 응답하거나 몇 분 이상 주제를 읽으면 자동으로 '추적'알림 레벨로 설정됩니다. [사용자 환경 설정] (%{base_uri} / my / preferences)에서이를 변경할 수 있습니다. + poll: + instructions: |- + 모든 게시물에 설문 조사를 추가 할 수 있다는 것을 알고 있습니까? 를 사용해보십시오 설문 조사를 작성하여 설문 조사를 작성합니다 **. + not_found: |- + 으악! 답장에 설문 조사가 없습니다. 사용 편집기에서 톱니 바퀴 아이콘을 클릭하거나 다음 응답에이 설문 조사를 복사하여 붙여 넣으십시오.```text [poll] * : cat : * : dog : [/ poll]``` + reply: |- + 여보세요, 여론 조사! 내가 당신을 가르치는 데 어떻게 했습니까? [폴] * : +1 : * : -1 : [/ 폴] + details: + instructions: |- + 때로는 답글에서 ** 세부 사항 숨기기 **를 원할 수도 있습니다.-스포일러로 간주되는 영화 또는 TV 프로그램의 플롯 포인트를 논의 할 때. -게시물에 한 번에 읽을 때 압도적 일 수있는 많은 옵션 세부 정보가 필요한 경우. [details = 작동 방식을 보려면 이것을 선택하십시오!] 1. 에디터에서 기어. 2. "세부 정보 숨기기"를 선택하십시오. 3. 세부 사항 요약을 편집하고 컨텐츠를 추가하십시오. [/ 세부 사항] 다음 답변에 세부 정보 섹션을 추가하려면 편집기를 사용하십시오. + not_found: |- + 세부 사항 위젯을 작성하는 데 문제가 있습니까? 다음 답장에 다음 내용을 포함시켜보십시오. + reply: |- + 훌륭합니다. _detail_에 대한 관심은 훌륭합니다! + end: + message: |- + 당신은 이것을 _advanced user_ 실제로 : bow : %{certificate}처럼 비난했습니다. 안녕! 나와 다시 대화하고 싶다면 언제든지 메시지를 보내주세요. certificate: alt: "고급 사용자 추적 인증" diff --git a/plugins/discourse-narrative-bot/config/locales/server.nl.yml b/plugins/discourse-narrative-bot/config/locales/server.nl.yml index da479e2934..de474e3cbd 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.nl.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.nl.yml @@ -95,11 +95,6 @@ nl: random_mention: reply: |- Hallo! Zeg `@%{discobot_username} %{help_trigger}` om te ontdekken wat ik kan. - tracks: |- - Momenteel kan ik de volgende dingen doen: - - `@%{discobot_username} %{reset_trigger} {name-of-tutorial}` - > Start een interactieve handleiding. `{name-of-tutorial}` kan één zijn van: `%{tracks}`. do_not_understand: first_response: |- Hallo, bedankt voor het antwoord! diff --git a/plugins/discourse-narrative-bot/config/locales/server.pl_PL.yml b/plugins/discourse-narrative-bot/config/locales/server.pl_PL.yml index 4a66730780..83ee3a2332 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.pl_PL.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.pl_PL.yml @@ -117,12 +117,6 @@ pl_PL: random_mention: reply: |- Hej! Aby dowiedzieć się, co mogę zrobić, powiedz `@%{discobot_username} %{help_trigger}`. - tracks: |- - Obecnie wiem, jak robić następujące rzeczy: - - `@%{discobot_username}%{reset_trigger}{name-of-tutorial}` - > Zaczyna interaktywny samouczek. `{name-of-tutorial}` może być jednym z: ` - %{tracks}`. bot_actions: |- `@ %{discobot_username} %{dice_trigger} 2d6` > :game_die: 3, 6 diff --git a/plugins/discourse-narrative-bot/config/locales/server.pt_BR.yml b/plugins/discourse-narrative-bot/config/locales/server.pt_BR.yml index d50817def5..473085ce61 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.pt_BR.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.pt_BR.yml @@ -121,11 +121,6 @@ pt_BR: random_mention: reply: |- Oi! Para descobrir o que eu posso fazer diga `@%{discobot_username} %{help_trigger}`. - tracks: |- - Atualmente, sei como fazer as seguintes coisas: - - `%{discobot_username} %{reset_trigger} {name-of-tutorial}` - > Inicia um tutorial interativo. `{name-of-tutorial}` pode ser um de: `%{tracks}`. bot_actions: |- `@%{discobot_username} %{dice_trigger} 2d6` > :game_die: 3, 6 diff --git a/plugins/discourse-narrative-bot/config/locales/server.ru.yml b/plugins/discourse-narrative-bot/config/locales/server.ru.yml index f5f68f7a2c..9e79fe8e5c 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.ru.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.ru.yml @@ -121,11 +121,6 @@ ru: random_mention: reply: |- Привет! Чтобы узнать, что я могу сделать, наберите: `@%{discobot_username} %{help_trigger}`. - tracks: |- - Я знаю следующие команды: - - `@%{discobot_username} %{reset_trigger} {название-руководства}` - > Запустить руководство. Доступные руководства: `%{tracks}`. bot_actions: |- `@%{discobot_username} %{dice_trigger} 2d6` > :game_die: 3, 6 diff --git a/plugins/discourse-narrative-bot/config/locales/server.sl.yml b/plugins/discourse-narrative-bot/config/locales/server.sl.yml index e4e61c705a..ce70e9b776 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.sl.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.sl.yml @@ -113,11 +113,6 @@ sl: random_mention: reply: |- Pozdravljeni! Da izveste, kaj znam, recite `@%{discobot_username} %{help_trigger}`. - tracks: |- - Trenutno znam narediti naslednje stvari: - - `@%{discobot_username} %{reset_trigger} {naziv-pripovedi}` - > Začni interaktivno pripoved. `{naziv-pripovedi}` je lahko ena od sledečih: %{tracks}. do_not_understand: first_response: |- Hvala za odgovor! diff --git a/plugins/discourse-narrative-bot/config/locales/server.sv.yml b/plugins/discourse-narrative-bot/config/locales/server.sv.yml index 06d136099c..862a4a4fd9 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.sv.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.sv.yml @@ -74,7 +74,7 @@ sv: author: "Theodore Roosevelt" '6': quote: "Livet är som en låda med choklad. Du vet aldrig vad du kommer att få." - author: "Forrest Gump’s Mom ( Författaren: Winston Groom )" + author: "Forrest Gumps mamma \n( Författaren: Winston Groom )" '7': quote: "Det är ett litet steg för en man, ett jättesprång för mänskligheten." author: "Neil Armstrong" @@ -90,7 +90,7 @@ sv: results: |- > :left_speech_bubble: _%{quote}_ — %{author} magic_8_ball: - trigger: "förmögenhet" + trigger: "framgång" answers: '1': "Det är säkert" '2': "Det är bestämt så" @@ -120,12 +120,12 @@ sv: help_trigger: "visa hjälp" random_mention: reply: |- - Hej! För att ta reda på vad jag kan göra, säg `%{discobot_username}%{help_trigger}`. + Hej! För att ta reda på vad jag kan göra, säg `@%{discobot_username} %{help_trigger}`. tracks: |- I nuläget klarar jag av följande saker: - `@%{discobot_username}%{reset_trigger} {namn-på-handledning}` - > Startar en interaktiv handledning. `{namn-på-handledning}` kan vara en av dessa: `%{tracks}` . + `@%{discobot_username} %{reset_trigger} {namn-på-handledning}` + > Startar en interaktiv handledning enbart för dig, i ett privat meddelande. `{namn-på-handledning}` kan vara en av dessa: `%{tracks}` . bot_actions: |- `@%{discobot_username} %{dice_trigger} 2d6` > :game_die: 3, 6 diff --git a/plugins/discourse-narrative-bot/config/locales/server.tr_TR.yml b/plugins/discourse-narrative-bot/config/locales/server.tr_TR.yml index f676323e7d..00baa82e87 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.tr_TR.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.tr_TR.yml @@ -121,11 +121,6 @@ tr_TR: random_mention: reply: |- Selam! Neler yapabileceğimi öğrenmek için `@ %{discobot_username} %{help_trigger}` komutunu girin. - tracks: |- - Şu anda aşağıdaki şeyleri nasıl yapacağımı biliyorum: - - `` @ %{discobot_username} %{reset_trigger} {öğretici adı} ` - > Etkileşimli bir öğretici başlatır. `{öğretici adı}` şunlardan biri olabilir: `%{tracks}`. bot_actions: |- @ @ %{discobot_username} %{dice_trigger} 2d6` >: game_die: 3, 6 diff --git a/plugins/discourse-narrative-bot/config/locales/server.uk.yml b/plugins/discourse-narrative-bot/config/locales/server.uk.yml index f126854198..9aea96cf12 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.uk.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.uk.yml @@ -97,9 +97,6 @@ uk: random_mention: reply: |- Привіт! Щоб дізнатися, що я можу зробити, скажіть `@ %{discobot_username} %{help_trigger}`. - tracks: |- - На даний момент я знаю, як робити наступні речі: `@ %{discobot_username} %{reset_trigger} {name-of-tutorial}` - > Запускає інтерактивний підручник. `{name-of-tutorial}` може бути одним із: `%{tracks}`. bot_actions: |- `@%{discobot_username} %{dice_trigger} 2d6` > :game_die: 3, 6 diff --git a/plugins/discourse-narrative-bot/config/locales/server.ur.yml b/plugins/discourse-narrative-bot/config/locales/server.ur.yml index 9621a1c406..a4dd9dec10 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.ur.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.ur.yml @@ -113,11 +113,6 @@ ur: random_mention: reply: |- ہیلو! جاننے کیلئے کہ میں کیا کر سکتا ہوں، `@%{discobot_username} %{help_trigger}` کہیں۔ - tracks: |- - میں فی الحال مندرجہ ذیل چیزوں کو کرنا جانتا ہوں: - - `@%{discobot_username} %{reset_trigger} {ٹیوٹوریل-کا-نام}` - > ایک انٹرایکٹو ٹیوٹوریل شروع کر دیتا ہے۔ {ٹیوٹوریل-کا-نام} اِن میں سے ایک ہوسکتا ہے: `%{tracks}`۔ do_not_understand: first_response: |- ارے، جواب کیلئے شکریہ! diff --git a/plugins/discourse-narrative-bot/config/locales/server.zh_CN.yml b/plugins/discourse-narrative-bot/config/locales/server.zh_CN.yml index ceb416e9c3..93d56b1d50 100644 --- a/plugins/discourse-narrative-bot/config/locales/server.zh_CN.yml +++ b/plugins/discourse-narrative-bot/config/locales/server.zh_CN.yml @@ -122,10 +122,10 @@ zh_CN: reply: |- 你好!想看看我能做什么吗?说 `@%{discobot_username} %{help_trigger}`。 tracks: |- - 我现在知道应该怎样应对下面的问题了: + 我现在知道怎么办了: - `@ %{discobot_username} %{reset_trigger} {name-of-tutorial}` - > 开始交互式教程。`{name-of-tutorial}`可以是一个:`%{tracks}`。 + `@%{discobot_username}%{reset_trigger}{name-of-tutorial}` + > 在私信中为你开设一个交互式的教程。`{name-of-tutorial}` 可以是以下之一: `%{tracks}`。 bot_actions: |- `@%{discobot_username} %{dice_trigger} 2d6` > :game_die: 3, 6 diff --git a/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/new_user_narrative.rb b/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/new_user_narrative.rb index 072c54beaf..5e9a1f38a5 100644 --- a/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/new_user_narrative.rb +++ b/plugins/discourse-narrative-bot/lib/discourse_narrative_bot/new_user_narrative.rb @@ -238,7 +238,7 @@ module DiscourseNarrativeBot return unless @post.user_id == self.discobot_user.id profile_page_url = url_helpers(:user_url, username: @user.username) - bookmark_url = "#{profile_page_url}/activity/bookmarks-with-reminders" + bookmark_url = "#{profile_page_url}/activity/bookmarks" raw = <<~RAW #{I18n.t("#{I18N_KEY}.bookmark.reply", i18n_post_args(bookmark_url: bookmark_url))} diff --git a/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/new_user_narrative_spec.rb b/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/new_user_narrative_spec.rb index d875de3b10..ce65b15463 100644 --- a/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/new_user_narrative_spec.rb +++ b/plugins/discourse-narrative-bot/spec/discourse_narrative_bot/new_user_narrative_spec.rb @@ -256,7 +256,7 @@ describe DiscourseNarrativeBot::NewUserNarrative do profile_page_url = "#{Discourse.base_url}/u/#{user.username}" expected_raw = <<~RAW - #{I18n.t('discourse_narrative_bot.new_user_narrative.bookmark.reply', bookmark_url: "#{profile_page_url}/activity/bookmarks-with-reminders", base_uri: '')} + #{I18n.t('discourse_narrative_bot.new_user_narrative.bookmark.reply', bookmark_url: "#{profile_page_url}/activity/bookmarks", base_uri: '')} #{I18n.t('discourse_narrative_bot.new_user_narrative.onebox.instructions', base_uri: '')} RAW diff --git a/plugins/discourse-presence/assets/javascripts/discourse/components/composer-presence-display.js.es6 b/plugins/discourse-presence/assets/javascripts/discourse/components/composer-presence-display.js.es6 index 1e78297376..a371e5f4a9 100644 --- a/plugins/discourse-presence/assets/javascripts/discourse/components/composer-presence-display.js.es6 +++ b/plugins/discourse-presence/assets/javascripts/discourse/components/composer-presence-display.js.es6 @@ -1,12 +1,18 @@ -import { cancel, debounce, once } from "@ember/runloop"; import Component from "@ember/component"; +import { getOwner } from "@ember/application"; +import { cancel } from "@ember/runloop"; import { equal, gt } from "@ember/object/computed"; -import { Promise } from "rsvp"; -import { ajax } from "discourse/lib/ajax"; -import computed, { observes, on } from "discourse-common/utils/decorators"; - -export const keepAliveDuration = 10000; -export const bufferTime = 3000; +import discourseComputed, { + observes, + on +} from "discourse-common/utils/decorators"; +import { + REPLYING, + CLOSED, + EDITING, + COMPOSER_TYPE +} from "../lib/presence-manager"; +import { REPLY, EDIT } from "discourse/models/composer"; export default Component.extend({ // Passed in variables @@ -15,115 +21,105 @@ export default Component.extend({ topic: null, reply: null, title: null, + isWhispering: null, + presenceManager: null, - // Internal variables - previousState: null, - currentState: null, - presenceUsers: null, - channel: null, + init() { + this._super(...arguments); + + this.setProperties({ + presenceManager: getOwner(this).lookup("presence-manager:main") + }); + }, + + @discourseComputed("topic.id") + users(topicId) { + return this.presenceManager.users(topicId); + }, + + @discourseComputed("topic.id") + editingUsers(topicId) { + return this.presenceManager.editingUsers(topicId); + }, isReply: equal("action", "reply"), - shouldDisplay: gt("users.length", 0), @on("didInsertElement") - composerOpened() { - this._lastPublish = new Date(); - once(this, "updateState"); + subscribe() { + this.presenceManager.subscribe(this.get("topic.id"), COMPOSER_TYPE); }, - @observes("action", "post.id", "topic.id") - composerStateChanged() { - once(this, "updateState"); + @discourseComputed( + "post.id", + "editingUsers.@each.last_seen", + "users.@each.last_seen", + "action" + ) + presenceUsers(postId, editingUsers, users, action) { + if (action === EDIT) { + return editingUsers.filterBy("post_id", postId); + } else if (action === REPLY) { + return users; + } + return []; }, + shouldDisplay: gt("presenceUsers.length", 0), + @observes("reply", "title") typing() { - if (new Date() - this._lastPublish > keepAliveDuration) { - this.publish({ current: this.currentState }); + const action = this.action; + + if (action !== REPLY && action !== EDIT) { + return; + } + + let data = { + topicId: this.get("topic.id"), + state: action === EDIT ? EDITING : REPLYING, + whisper: this.whisper, + postId: this.get("post.id") + }; + + this._prevPublishData = data; + + this._throttle = this.presenceManager.throttlePublish( + data.topicId, + data.state, + data.whisper, + data.postId + ); + }, + + @observes("whisper") + cancelThrottle() { + this._cancelThrottle(); + }, + + @observes("action", "topic.id") + composerState() { + if (this._prevPublishData) { + this.presenceManager.publish( + this._prevPublishData.topicId, + CLOSED, + this._prevPublishData.whisper, + this._prevPublishData.postId + ); + this._prevPublishData = null; } }, @on("willDestroyElement") - composerClosing() { - this.publish({ previous: this.currentState }); - cancel(this._pingTimer); - cancel(this._clearTimer); + closeComposer() { + this._cancelThrottle(); + this._prevPublishData = null; + this.presenceManager.cleanUpPresence(COMPOSER_TYPE); }, - updateState() { - let state = null; - const action = this.action; - - if (action === "reply" || action === "edit") { - state = { action }; - if (action === "reply") state.topic_id = this.get("topic.id"); - if (action === "edit") state.post_id = this.get("post.id"); + _cancelThrottle() { + if (this._throttle) { + cancel(this._throttle); + this._throttle = null; } - - this.set("previousState", this.currentState); - this.set("currentState", state); - }, - - @observes("currentState") - currentStateChanged() { - if (this.channel) { - this.messageBus.unsubscribe(this.channel); - this.set("channel", null); - } - - this.clear(); - - if (!["reply", "edit"].includes(this.action)) { - return; - } - - this.publish({ - response_needed: true, - previous: this.previousState, - current: this.currentState - }).then(r => { - if (this.isDestroyed) { - return; - } - this.set("presenceUsers", r.users); - this.set("channel", r.messagebus_channel); - - if (!r.messagebus_channel) { - return; - } - - this.messageBus.subscribe( - r.messagebus_channel, - message => { - if (!this.isDestroyed) this.set("presenceUsers", message.users); - this._clearTimer = debounce( - this, - "clear", - keepAliveDuration + bufferTime - ); - }, - r.messagebus_id - ); - }); - }, - - clear() { - if (!this.isDestroyed) this.set("presenceUsers", []); - }, - - publish(data) { - this._lastPublish = new Date(); - - // Don't publish presence if disabled - if (this.currentUser.hide_profile_and_presence) { - return Promise.resolve(); - } - - return ajax("/presence/publish", { type: "POST", data }); - }, - - @computed("presenceUsers", "currentUser.id") - users(users, currentUserId) { - return (users || []).filter(user => user.id !== currentUserId); } }); diff --git a/plugins/discourse-presence/assets/javascripts/discourse/components/topic-presence-display.js.es6 b/plugins/discourse-presence/assets/javascripts/discourse/components/topic-presence-display.js.es6 index 1089246fb6..2f683ca741 100644 --- a/plugins/discourse-presence/assets/javascripts/discourse/components/topic-presence-display.js.es6 +++ b/plugins/discourse-presence/assets/javascripts/discourse/components/topic-presence-display.js.es6 @@ -1,59 +1,32 @@ -import { cancel, debounce } from "@ember/runloop"; import Component from "@ember/component"; +import { getOwner } from "@ember/application"; import { gt } from "@ember/object/computed"; -import computed, { on } from "discourse-common/utils/decorators"; -import { - keepAliveDuration, - bufferTime -} from "discourse/plugins/discourse-presence/discourse/components/composer-presence-display"; - -const MB_GET_LAST_MESSAGE = -2; +import discourseComputed, { on } from "discourse-common/utils/decorators"; +import { TOPIC_TYPE } from "../lib/presence-manager"; export default Component.extend({ - topicId: null, - presenceUsers: null, + topic: null, + presenceManager: null, + + init() { + this._super(...arguments); + this.set("presenceManager", getOwner(this).lookup("presence-manager:main")); + }, + + @discourseComputed("topic.id") + users(topicId) { + return this.presenceManager.users(topicId); + }, shouldDisplay: gt("users.length", 0), - clear() { - if (!this.isDestroyed) this.set("presenceUsers", []); - }, - @on("didInsertElement") - _inserted() { - this.clear(); - - this.messageBus.subscribe( - this.channel, - message => { - if (!this.isDestroyed) this.set("presenceUsers", message.users); - this._clearTimer = debounce( - this, - "clear", - keepAliveDuration + bufferTime - ); - }, - MB_GET_LAST_MESSAGE - ); + subscribe() { + this.presenceManager.subscribe(this.get("topic.id"), TOPIC_TYPE); }, @on("willDestroyElement") _destroyed() { - cancel(this._clearTimer); - this.messageBus.unsubscribe(this.channel); - }, - - @computed("topicId") - channel(topicId) { - return `/presence/topic/${topicId}`; - }, - - @computed("presenceUsers", "currentUser.{id,ignored_users}") - users(users, currentUser) { - const ignoredUsers = currentUser.ignored_users || []; - return (users || []).filter( - user => - user.id !== currentUser.id && !ignoredUsers.includes(user.username) - ); + this.presenceManager.unsubscribe(this.get("topic.id"), TOPIC_TYPE); } }); diff --git a/plugins/discourse-presence/assets/javascripts/discourse/initializers/discourse-presence.js.es6 b/plugins/discourse-presence/assets/javascripts/discourse/initializers/discourse-presence.js.es6 new file mode 100644 index 0000000000..1009fc1453 --- /dev/null +++ b/plugins/discourse-presence/assets/javascripts/discourse/initializers/discourse-presence.js.es6 @@ -0,0 +1,32 @@ +import { withPluginApi } from "discourse/lib/plugin-api"; +import PresenceManager from "../lib/presence-manager"; +import ENV from "discourse-common/config/environment"; + +function initializeDiscoursePresence(api, { app }) { + const currentUser = api.getCurrentUser(); + + if (currentUser) { + app.register( + "presence-manager:main", + PresenceManager.create({ + currentUser, + messageBus: api.container.lookup("message-bus:main"), + siteSettings: api.container.lookup("site-settings:main") + }), + { instantiate: false } + ); + } +} + +export default { + name: "discourse-presence", + after: "message-bus", + + initialize(container, app) { + const siteSettings = container.lookup("site-settings:main"); + + if (siteSettings.presence_enabled && ENV.environment !== "test") { + withPluginApi("0.8.40", initializeDiscoursePresence, { app }); + } + } +}; diff --git a/plugins/discourse-presence/assets/javascripts/discourse/lib/presence-manager.js.es6 b/plugins/discourse-presence/assets/javascripts/discourse/lib/presence-manager.js.es6 new file mode 100644 index 0000000000..1be35640ca --- /dev/null +++ b/plugins/discourse-presence/assets/javascripts/discourse/lib/presence-manager.js.es6 @@ -0,0 +1,286 @@ +import EmberObject from "@ember/object"; +import { cancel, later, throttle } from "@ember/runloop"; +import { ajax } from "discourse/lib/ajax"; +import discourseComputed from "discourse-common/utils/decorators"; + +// The durations chosen here determines the accuracy of the presence feature and +// is tied closely with the server side implementation. Decreasing the duration +// to increase the accuracy will come at the expense of having to more network +// calls to publish the client's state. +// +// Logic walk through of our heuristic implementation: +// - When client A is typing, a message is published every KEEP_ALIVE_DURATION_SECONDS. +// - Client B receives the message and stores each user in an array and marks +// the user with a client-side timestamp of when the user was seen. +// - If client A continues to type, client B will continue to receive messages to +// update the client-side timestamp of when client A was last seen. +// - If client A disconnects or becomes inactive, the state of client A will be +// cleaned up on client B by a scheduler that runs every TIMER_INTERVAL_MILLISECONDS +const KEEP_ALIVE_DURATION_SECONDS = 10; +const BUFFER_DURATION_SECONDS = KEEP_ALIVE_DURATION_SECONDS + 2; + +const MESSAGE_BUS_LAST_ID = 0; +const TIMER_INTERVAL_MILLISECONDS = 2000; + +export const REPLYING = "replying"; +export const EDITING = "editing"; +export const CLOSED = "closed"; + +export const TOPIC_TYPE = "topic"; +export const COMPOSER_TYPE = "composer"; + +const Presence = EmberObject.extend({ + users: null, + editingUsers: null, + subscribers: null, + topicId: null, + currentUser: null, + messageBus: null, + siteSettings: null, + + init() { + this._super(...arguments); + + this.setProperties({ + users: [], + editingUsers: [], + subscribers: new Set() + }); + }, + + subscribe(type) { + if (this.subscribers.size === 0) { + this.messageBus.subscribe( + this.channel, + message => { + const { user, state } = message; + if (this.get("currentUser.id") === user.id) return; + + switch (state) { + case REPLYING: + this._appendUser(this.users, user); + break; + case EDITING: + this._appendUser(this.editingUsers, user, { + post_id: parseInt(message.post_id, 10) + }); + break; + case CLOSED: + this._removeUser(user); + break; + } + }, + MESSAGE_BUS_LAST_ID + ); + } + + this.subscribers.add(type); + }, + + unsubscribe(type) { + this.subscribers.delete(type); + const noSubscribers = this.subscribers.size === 0; + + if (noSubscribers) { + this.messageBus.unsubscribe(this.channel); + this._stopTimer(); + + this.setProperties({ + users: [], + editingUsers: [] + }); + } + + return noSubscribers; + }, + + @discourseComputed("topicId") + channel(topicId) { + return `/presence/${topicId}`; + }, + + throttlePublish(state, whisper, postId) { + return throttle( + this, + this.publish, + state, + whisper, + postId, + KEEP_ALIVE_DURATION_SECONDS * 1000 + ); + }, + + publish(state, whisper, postId) { + if (this.get("currentUser.hide_profile_and_presence")) return; + + const data = { + state, + topic_id: this.topicId + }; + + if (whisper) { + data.is_whisper = 1; + } + + if (postId && state === EDITING) { + data.post_id = postId; + } + + return ajax("/presence/publish", { + type: "POST", + data + }); + }, + + _removeUser(user) { + [this.users, this.editingUsers].forEach(users => { + const existingUser = users.findBy("id", user.id); + if (existingUser) users.removeObject(existingUser); + }); + }, + + _cleanUpUsers() { + [this.users, this.editingUsers].forEach(users => { + const staleUsers = []; + + users.forEach(user => { + if (user.last_seen <= Date.now() - BUFFER_DURATION_SECONDS * 1000) { + staleUsers.push(user); + } + }); + + users.removeObjects(staleUsers); + }); + + return this.users.length === 0 && this.editingUsers.length === 0; + }, + + _appendUser(users, user, attrs) { + let existingUser; + let usersLength = 0; + + users.forEach(u => { + if (u.id === user.id) { + existingUser = u; + } + + if (attrs && attrs.post_id) { + if (u.post_id === attrs.post_id) usersLength++; + } else { + usersLength++; + } + }); + + const props = attrs || {}; + props.last_seen = Date.now(); + + if (existingUser) { + existingUser.setProperties(props); + } else { + const limit = this.get("siteSettings.presence_max_users_shown"); + + if (usersLength < limit) { + users.pushObject(EmberObject.create(Object.assign(user, props))); + } + } + + this._startTimer(() => { + this._cleanUpUsers(); + }); + }, + + _scheduleTimer(callback) { + return later( + this, + () => { + const stop = callback(); + + if (!stop) { + this.set("_timer", this._scheduleTimer(callback)); + } + }, + TIMER_INTERVAL_MILLISECONDS + ); + }, + + _stopTimer() { + cancel(this._timer); + }, + + _startTimer(callback) { + if (!this._timer) { + this.set("_timer", this._scheduleTimer(callback)); + } + } +}); + +const PresenceManager = EmberObject.extend({ + presences: null, + currentUser: null, + messageBus: null, + siteSettings: null, + + init() { + this._super(...arguments); + + this.setProperties({ + presences: {} + }); + }, + + subscribe(topicId, type) { + if (!topicId) return; + this._getPresence(topicId).subscribe(type); + }, + + unsubscribe(topicId, type) { + if (!topicId) return; + const presence = this._getPresence(topicId); + + if (presence.unsubscribe(type)) { + delete this.presences[topicId]; + } + }, + + users(topicId) { + if (!topicId) return []; + return this._getPresence(topicId).users; + }, + + editingUsers(topicId) { + if (!topicId) return []; + return this._getPresence(topicId).editingUsers; + }, + + throttlePublish(topicId, state, whisper, postId) { + if (!topicId) return; + return this._getPresence(topicId).throttlePublish(state, whisper, postId); + }, + + publish(topicId, state, whisper, postId) { + if (!topicId) return; + return this._getPresence(topicId).publish(state, whisper, postId); + }, + + cleanUpPresence(type) { + Object.keys(this.presences).forEach(key => { + this.publish(key, CLOSED); + this.unsubscribe(key, type); + }); + }, + + _getPresence(topicId) { + if (!this.presences[topicId]) { + this.presences[topicId] = Presence.create({ + messageBus: this.messageBus, + siteSettings: this.siteSettings, + currentUser: this.currentUser, + topicId + }); + } + + return this.presences[topicId]; + } +}); + +export default PresenceManager; diff --git a/plugins/discourse-presence/assets/javascripts/discourse/templates/components/composer-presence-display.hbs b/plugins/discourse-presence/assets/javascripts/discourse/templates/components/composer-presence-display.hbs index 97936135d0..453b13d07a 100644 --- a/plugins/discourse-presence/assets/javascripts/discourse/templates/components/composer-presence-display.hbs +++ b/plugins/discourse-presence/assets/javascripts/discourse/templates/components/composer-presence-display.hbs @@ -1,7 +1,7 @@ {{#if shouldDisplay}}
- {{#each users as |user|}} + {{#each presenceUsers as |user|}} {{avatar user avatarTemplatePath="avatar_template" usernamePath="username" imageSize="small"}} {{/each}}
@@ -16,4 +16,4 @@ --}}...
-{{/if}} \ No newline at end of file +{{/if}} diff --git a/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/composer-fields/presence.hbs b/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/composer-fields/presence.hbs index af4de7c592..8fa1fb3862 100644 --- a/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/composer-fields/presence.hbs +++ b/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/composer-fields/presence.hbs @@ -4,4 +4,5 @@ topic=model.topic reply=model.reply title=model.title + whisper=model.whisper }} diff --git a/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/composer-fields/presence.js.es6 b/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/composer-fields/presence.js.es6 index 00fbc34d91..5165da1a21 100644 --- a/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/composer-fields/presence.js.es6 +++ b/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/composer-fields/presence.js.es6 @@ -1,5 +1,5 @@ export default { - shouldRender(_, ctx) { - return ctx.siteSettings.presence_enabled; + shouldRender(_, component) { + return component.siteSettings.presence_enabled; } }; diff --git a/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/topic-above-footer-buttons/presence.hbs b/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/topic-above-footer-buttons/presence.hbs index 0ee449cf1d..c8514c7edc 100644 --- a/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/topic-above-footer-buttons/presence.hbs +++ b/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/topic-above-footer-buttons/presence.hbs @@ -1 +1 @@ -{{topic-presence-display topicId=model.id}} +{{topic-presence-display topic=model}} diff --git a/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/topic-above-footer-buttons/presence.js.es6 b/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/topic-above-footer-buttons/presence.js.es6 index 00fbc34d91..5165da1a21 100644 --- a/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/topic-above-footer-buttons/presence.js.es6 +++ b/plugins/discourse-presence/assets/javascripts/discourse/templates/connectors/topic-above-footer-buttons/presence.js.es6 @@ -1,5 +1,5 @@ export default { - shouldRender(_, ctx) { - return ctx.siteSettings.presence_enabled; + shouldRender(_, component) { + return component.siteSettings.presence_enabled; } }; diff --git a/plugins/discourse-presence/config/settings.yml b/plugins/discourse-presence/config/settings.yml index 07c96c3d2b..21fbddf5ff 100644 --- a/plugins/discourse-presence/config/settings.yml +++ b/plugins/discourse-presence/config/settings.yml @@ -4,5 +4,6 @@ plugins: client: true presence_max_users_shown: default: 5 + client: true min: 1 max: 50 diff --git a/plugins/discourse-presence/plugin.rb b/plugins/discourse-presence/plugin.rb index 54d694b069..ce91b1ad2e 100644 --- a/plugins/discourse-presence/plugin.rb +++ b/plugins/discourse-presence/plugin.rb @@ -2,8 +2,8 @@ # name: discourse-presence # about: Show which users are writing a reply to a topic -# version: 1.0 -# authors: André Pereira, David Taylor +# version: 2.0 +# authors: André Pereira, David Taylor, tgxworld # url: https://github.com/discourse/discourse/tree/master/plugins/discourse-presence enabled_site_setting :presence_enabled @@ -15,161 +15,155 @@ PLUGIN_NAME ||= -"discourse-presence" after_initialize do + MessageBus.register_client_message_filter('/presence/') do |message| + published_at = message.data["published_at"] + + if published_at + (Time.zone.now.to_i - published_at) <= ::Presence::MAX_BACKLOG_AGE_SECONDS + else + false + end + end + module ::Presence + MAX_BACKLOG_AGE_SECONDS = 10 + class Engine < ::Rails::Engine engine_name PLUGIN_NAME isolate_namespace Presence end end - module ::Presence::PresenceManager - MAX_BACKLOG_AGE ||= 60 - - def self.get_redis_key(type, id) - "presence:#{type}:#{id}" - end - - def self.get_messagebus_channel(type, id) - "/presence/#{type}/#{id}" - end - - # return true if a key was added - def self.add(type, id, user_id) - key = get_redis_key(type, id) - result = Discourse.redis.hset(key, user_id, Time.zone.now) - Discourse.redis.expire(key, MAX_BACKLOG_AGE) - result - end - - # return true if a key was deleted - def self.remove(type, id, user_id) - key = get_redis_key(type, id) - Discourse.redis.expire(key, MAX_BACKLOG_AGE) - Discourse.redis.hdel(key, user_id) > 0 - end - - def self.get_users(type, id) - user_ids = Discourse.redis.hkeys(get_redis_key(type, id)).map(&:to_i) - User.where(id: user_ids) - end - - def self.publish(type, id) - users = get_users(type, id) - serialized_users = users.map { |u| BasicUserSerializer.new(u, root: false) } - message = { users: serialized_users, time: Time.now.to_i } - messagebus_channel = get_messagebus_channel(type, id) - - topic = type == 'post' ? Post.find_by(id: id).topic : Topic.find_by(id: id) - - if topic.private_message? - user_ids = User.where('admin OR moderator').pluck(:id) + topic.allowed_users.pluck(:id) - group_ids = topic.allowed_groups.pluck(:id) - - MessageBus.publish( - messagebus_channel, - message.as_json, - user_ids: user_ids, - group_ids: group_ids, - max_backlog_age: MAX_BACKLOG_AGE - ) - else - MessageBus.publish( - messagebus_channel, - message.as_json, - group_ids: topic.secure_group_ids, - max_backlog_age: MAX_BACKLOG_AGE - ) - end - - users - end - - def self.cleanup(type, id) - has_changed = false - - # Delete entries older than 20 seconds - hash = Discourse.redis.hgetall(get_redis_key(type, id)) - hash.each do |user_id, time| - if Time.zone.now - Time.parse(time) >= 20 - has_changed |= remove(type, id, user_id) - end - end - - has_changed - end - - end - require_dependency "application_controller" class Presence::PresencesController < ::ApplicationController requires_plugin PLUGIN_NAME before_action :ensure_logged_in + before_action :ensure_presence_enabled - ACTIONS ||= [-"edit", -"reply"].freeze + EDITING_STATE = 'editing' + REPLYING_STATE = 'replying' + CLOSED_STATE = 'closed' - def publish - raise Discourse::NotFound if current_user.blank? || current_user.user_option.hide_profile_and_presence? - - data = params.permit( - :response_needed, - current: [:action, :topic_id, :post_id], - previous: [:action, :topic_id, :post_id] - ) - - payload = {} - - if data[:previous] && data[:previous][:action].in?(ACTIONS) - type = data[:previous][:post_id] ? 'post' : 'topic' - id = data[:previous][:post_id] ? data[:previous][:post_id] : data[:previous][:topic_id] - - topic = type == 'post' ? Post.find_by(id: id)&.topic : Topic.find_by(id: id) - - if topic - guardian.ensure_can_see!(topic) - - Presence::PresenceManager.remove(type, id, current_user.id) - Presence::PresenceManager.cleanup(type, id) - Presence::PresenceManager.publish(type, id) - end + def handle_message + [:state, :topic_id].each do |key| + raise ActionController::ParameterMissing.new(key) unless params.key?(key) end - if data[:current] && data[:current][:action].in?(ACTIONS) - type = data[:current][:post_id] ? 'post' : 'topic' - id = data[:current][:post_id] ? data[:current][:post_id] : data[:current][:topic_id] + topic_id = permitted_params[:topic_id] + topic = Topic.find_by(id: topic_id) - topic = type == 'post' ? Post.find_by(id: id)&.topic : Topic.find_by(id: id) + raise Discourse::InvalidParameters.new(:topic_id) unless topic + guardian.ensure_can_see!(topic) - if topic - guardian.ensure_can_see!(topic) + post = nil - Presence::PresenceManager.add(type, id, current_user.id) - Presence::PresenceManager.cleanup(type, id) - users = Presence::PresenceManager.publish(type, id) + if (permitted_params[:post_id]) + if (permitted_params[:state] != EDITING_STATE) + raise Discourse::InvalidParameters.new(:state) + end - if data[:response_needed] - messagebus_channel = Presence::PresenceManager.get_messagebus_channel(type, id) - users ||= Presence::PresenceManager.get_users(type, id) - payload = json_payload(messagebus_channel, users) + post = Post.find_by(id: permitted_params[:post_id]) + raise Discourse::InvalidParameters.new(:topic_id) unless post + + guardian.ensure_can_edit!(post) + end + + opts = { + max_backlog_age: Presence::MAX_BACKLOG_AGE_SECONDS + } + + case permitted_params[:state] + when EDITING_STATE + opts[:group_ids] = [Group::AUTO_GROUPS[:staff]] + + if !post.locked? && !permitted_params[:is_whisper] + opts[:user_ids] = [post.user_id] + + if topic.private_message? + if post.wiki + opts[:user_ids] = opts[:user_ids].concat( + topic.allowed_users.where( + "trust_level >= ? AND NOT admin OR moderator", + SiteSetting.min_trust_to_edit_wiki_post + ).pluck(:id) + ) + + opts[:user_ids].uniq! + + # Ignore trust level and just publish to all allowed groups since + # trying to figure out which users in the allowed groups have + # the necessary trust levels can lead to a large array of user ids + # if the groups are big. + opts[:group_ids] = opts[:group_ids].concat( + topic.allowed_groups.pluck(:id) + ) + end + else + if post.wiki + opts[:group_ids] << Group::AUTO_GROUPS[:"trust_level_#{SiteSetting.min_trust_to_edit_wiki_post}"] + elsif SiteSetting.trusted_users_can_edit_others? + opts[:group_ids] << Group::AUTO_GROUPS[:trust_level_4] + end end end + when REPLYING_STATE + if permitted_params[:is_whisper] + opts[:group_ids] = [Group::AUTO_GROUPS[:staff]] + elsif topic.private_message? + opts[:user_ids] = topic.allowed_users.pluck(:id) + + opts[:group_ids] = [Group::AUTO_GROUPS[:staff]].concat( + topic.allowed_groups.pluck(:id) + ) + else + opts[:group_ids] = topic.secure_group_ids + end + when CLOSED_STATE + if topic.private_message? + opts[:user_ids] = topic.allowed_users.pluck(:id) + + opts[:group_ids] = [Group::AUTO_GROUPS[:staff]].concat( + topic.allowed_groups.pluck(:id) + ) + else + opts[:group_ids] = topic.secure_group_ids + end end - render json: payload - end - - def json_payload(channel, users) - { - messagebus_channel: channel, - messagebus_id: MessageBus.last_id(channel), - users: users.limit(SiteSetting.presence_max_users_shown).map { |u| BasicUserSerializer.new(u, root: false) } + payload = { + user: BasicUserSerializer.new(current_user, root: false).as_json, + state: permitted_params[:state], + is_whisper: permitted_params[:is_whisper].present?, + published_at: Time.zone.now.to_i } + + if (post_id = permitted_params[:post_id]).present? + payload[:post_id] = post_id + end + + MessageBus.publish("/presence/#{topic_id}", payload, opts) + + render json: success_json end + private + + def ensure_presence_enabled + if !SiteSetting.presence_enabled || + current_user.user_option.hide_profile_and_presence? + + raise Discourse::NotFound + end + end + + def permitted_params + params.permit(:state, :topic_id, :post_id, :is_whisper) + end end Presence::Engine.routes.draw do - post '/publish' => 'presences#publish' + post '/publish' => 'presences#handle_message' end Discourse::Application.routes.append do diff --git a/plugins/discourse-presence/spec/presence_manager_spec.rb b/plugins/discourse-presence/spec/presence_manager_spec.rb deleted file mode 100644 index b6cf1155ce..0000000000 --- a/plugins/discourse-presence/spec/presence_manager_spec.rb +++ /dev/null @@ -1,108 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe ::Presence::PresenceManager do - - let(:user1) { Fabricate(:user) } - let(:user2) { Fabricate(:user) } - let(:user3) { Fabricate(:user) } - let(:manager) { ::Presence::PresenceManager } - - let(:post1) { Fabricate(:post) } - let(:post2) { Fabricate(:post) } - - after(:each) do - Discourse.redis.del("presence:topic:#{post1.topic.id}") - Discourse.redis.del("presence:topic:#{post2.topic.id}") - Discourse.redis.del("presence:post:#{post1.id}") - Discourse.redis.del("presence:post:#{post2.id}") - end - - it 'adds, removes and lists users correctly' do - expect(manager.get_users('post', post1.id).count).to eq(0) - - expect(manager.add('post', post1.id, user1.id)).to be true - expect(manager.add('post', post1.id, user2.id)).to be true - expect(manager.add('post', post2.id, user3.id)).to be true - - expect(manager.get_users('post', post1.id).count).to eq(2) - expect(manager.get_users('post', post2.id).count).to eq(1) - - expect(manager.get_users('post', post1.id)).to contain_exactly(user1, user2) - expect(manager.get_users('post', post2.id)).to contain_exactly(user3) - - expect(manager.remove('post', post1.id, user1.id)).to be true - expect(manager.get_users('post', post1.id).count).to eq(1) - expect(manager.get_users('post', post1.id)).to contain_exactly(user2) - end - - it 'publishes correctly' do - expect(manager.get_users('post', post1.id).count).to eq(0) - - manager.add('post', post1.id, user1.id) - manager.add('post', post1.id, user2.id) - - messages = MessageBus.track_publish do - manager.publish('post', post1.id) - end - - expect(messages.count).to eq (1) - message = messages.first - - expect(message.channel).to eq("/presence/post/#{post1.id}") - - expect(message.data["users"].map { |u| u[:id] }).to contain_exactly(user1.id, user2.id) - end - - it 'publishes private message securely' do - private_post = Fabricate(:private_message_post) - manager.add('post', private_post.id, user2.id) - - messages = MessageBus.track_publish do - manager.publish('post', private_post.id) - end - - expect(messages.count).to eq (1) - message = messages.first - - expect(message.channel).to eq("/presence/post/#{private_post.id}") - - user_ids = User.where('admin or moderator').pluck(:id) - user_ids += private_post.topic.allowed_users.pluck(:id) - expect(message.user_ids).to contain_exactly(*user_ids) - end - - it 'publishes private category securely' do - group = Fabricate(:group) - category = Fabricate(:private_category, group: group) - private_topic = Fabricate(:topic, category: category) - - manager.add('topic', private_topic.id, user2.id) - - messages = MessageBus.track_publish do - manager.publish('topic', private_topic.id) - end - - expect(messages.count).to eq (1) - message = messages.first - - expect(message.channel).to eq("/presence/topic/#{private_topic.id}") - - expect(message.group_ids).to contain_exactly(*private_topic.secure_group_ids) - end - - it 'cleans up correctly' do - freeze_time Time.zone.now do - expect(manager.add('post', post1.id, user1.id)).to be true - expect(manager.cleanup('post', post1.id)).to be false # Nothing to cleanup - expect(manager.get_users('post', post1.id).count).to eq(1) - end - - # Anything older than 20 seconds should be cleaned up - freeze_time 30.seconds.from_now do - expect(manager.cleanup('post', post1.id)).to be true - expect(manager.get_users('post', post1.id).count).to eq(0) - end - end -end diff --git a/plugins/discourse-presence/spec/requests/presence_controller_spec.rb b/plugins/discourse-presence/spec/requests/presence_controller_spec.rb index 80547019a7..c13e04fa6c 100644 --- a/plugins/discourse-presence/spec/requests/presence_controller_spec.rb +++ b/plugins/discourse-presence/spec/requests/presence_controller_spec.rb @@ -3,170 +3,442 @@ require 'rails_helper' describe ::Presence::PresencesController do - before do - SiteSetting.presence_enabled = true - end + describe '#handle_message' do + context 'when not logged in' do + it 'should raise the right error' do + post '/presence/publish.json' - let(:user1) { Fabricate(:user) } - let(:user2) { Fabricate(:user) } - let(:user3) { Fabricate(:user) } + expect(response.status).to eq(403) + end + end - let(:post1) { Fabricate(:post) } - let(:post2) { Fabricate(:post) } + context 'when logged in' do + fab!(:user) { Fabricate(:user) } + fab!(:user2) { Fabricate(:user) } + fab!(:admin) { Fabricate(:admin) } - let(:manager) { ::Presence::PresenceManager } + fab!(:group) do + group = Fabricate(:group) + group.add(user) + group + end - after do - Discourse.redis.del("presence:topic:#{post1.topic.id}") - Discourse.redis.del("presence:topic:#{post2.topic.id}") - Discourse.redis.del("presence:post:#{post1.id}") - Discourse.redis.del("presence:post:#{post2.id}") - end + fab!(:category) { Fabricate(:private_category, group: group) } + fab!(:private_topic) { Fabricate(:topic, category: category) } + fab!(:public_topic) { Fabricate(:topic, first_post: Fabricate(:post)) } - context 'when not logged in' do - it 'should raise the right error' do - post '/presence/publish.json' - expect(response.status).to eq(403) + fab!(:private_message) do + Fabricate(:private_message_topic, + allowed_groups: [group] + ) + end + + before do + sign_in(user) + end + + it 'returns the right response when user disables the presence feature' do + user.user_option.update_column(:hide_profile_and_presence, true) + + post '/presence/publish.json' + + expect(response.status).to eq(404) + end + + it 'returns the right response when the presence site settings is disabled' do + SiteSetting.presence_enabled = false + + post '/presence/publish.json' + + expect(response.status).to eq(404) + end + + it 'returns the right response if required params are missing' do + post '/presence/publish.json' + + expect(response.status).to eq(400) + end + + it 'returns the right response if topic_id is invalid' do + post '/presence/publish.json', params: { topic_id: -999, state: 'replying' } + + expect(response.status).to eq(400) + end + + it 'returns the right response when user does not have access to the topic' do + group.remove(user) + + post '/presence/publish.json', params: { topic_id: private_topic.id, state: 'replying' } + + expect(response.status).to eq(403) + end + + it 'returns the right response when an invalid state is provided with a post_id' do + post '/presence/publish.json', params: { + topic_id: public_topic.id, + post_id: public_topic.first_post.id, + state: 'some state' + } + + expect(response.status).to eq(400) + end + + it 'returns the right response when user can not edit a post' do + Fabricate(:post, topic: private_topic, user: private_topic.user) + + post '/presence/publish.json', params: { + topic_id: private_topic.id, + post_id: private_topic.first_post.id, + state: 'editing' + } + + expect(response.status).to eq(403) + end + + it 'returns the right response when an invalid post_id is given' do + post '/presence/publish.json', params: { + topic_id: public_topic.id, + post_id: -9, + state: 'editing' + } + + expect(response.status).to eq(400) + end + + it 'publishes the right message for a public topic' do + freeze_time + + messages = MessageBus.track_publish do + post '/presence/publish.json', params: { topic_id: public_topic.id, state: 'replying' } + + expect(response.status).to eq(200) + end + + expect(messages.length).to eq(1) + + message = messages.first + + expect(message.channel).to eq("/presence/#{public_topic.id}") + expect(message.data.dig(:user, :id)).to eq(user.id) + expect(message.data[:published_at]).to eq(Time.zone.now.to_i) + expect(message.group_ids).to eq(nil) + expect(message.user_ids).to eq(nil) + end + + it 'publishes the right message for a restricted topic' do + freeze_time + + messages = MessageBus.track_publish do + post '/presence/publish.json', params: { + topic_id: private_topic.id, + state: 'replying' + } + + expect(response.status).to eq(200) + end + + expect(messages.length).to eq(1) + + message = messages.first + + expect(message.channel).to eq("/presence/#{private_topic.id}") + expect(message.data.dig(:user, :id)).to eq(user.id) + expect(message.data[:published_at]).to eq(Time.zone.now.to_i) + expect(message.group_ids).to contain_exactly(group.id) + expect(message.user_ids).to eq(nil) + end + + it 'publishes the right message for a private message' do + messages = MessageBus.track_publish do + post '/presence/publish.json', params: { + topic_id: private_message.id, + state: 'replying' + } + + expect(response.status).to eq(200) + end + + expect(messages.length).to eq(1) + + message = messages.first + + expect(message.group_ids).to contain_exactly( + group.id, + Group::AUTO_GROUPS[:staff] + ) + + expect(message.user_ids).to contain_exactly( + *private_message.topic_allowed_users.pluck(:user_id) + ) + end + + it 'publishes the message to staff group when user is whispering' do + SiteSetting.enable_whispers = true + + messages = MessageBus.track_publish do + post '/presence/publish.json', params: { + topic_id: public_topic.id, + state: 'replying', + is_whisper: true + } + + expect(response.status).to eq(200) + end + + expect(messages.length).to eq(1) + + message = messages.first + + expect(message.group_ids).to contain_exactly(Group::AUTO_GROUPS[:staff]) + expect(message.user_ids).to eq(nil) + end + + it 'publishes the message to staff group when a staff is editing a whisper' do + SiteSetting.enable_whispers = true + sign_in(admin) + + messages = MessageBus.track_publish do + post '/presence/publish.json', params: { + topic_id: public_topic.id, + post_id: public_topic.first_post.id, + state: 'editing', + is_whisper: true + } + + expect(response.status).to eq(200) + end + + expect(messages.length).to eq(1) + + message = messages.first + + expect(message.group_ids).to contain_exactly(Group::AUTO_GROUPS[:staff]) + expect(message.user_ids).to eq(nil) + end + + it 'publishes the message to staff group when a staff is editing a locked post' do + SiteSetting.enable_whispers = true + sign_in(admin) + locked_post = Fabricate(:post, topic: public_topic, locked_by_id: admin.id) + + messages = MessageBus.track_publish do + post '/presence/publish.json', params: { + topic_id: public_topic.id, + post_id: locked_post.id, + state: 'editing', + } + + expect(response.status).to eq(200) + end + + expect(messages.length).to eq(1) + + message = messages.first + + expect(message.group_ids).to contain_exactly(Group::AUTO_GROUPS[:staff]) + expect(message.user_ids).to eq(nil) + end + + it 'publishes the message to author, staff group and TL4 group when editing a public post' do + post = Fabricate(:post, topic: public_topic, user: user) + + messages = MessageBus.track_publish do + post '/presence/publish.json', params: { + topic_id: public_topic.id, + post_id: post.id, + state: 'editing', + } + + expect(response.status).to eq(200) + end + + expect(messages.length).to eq(1) + + message = messages.first + + expect(message.group_ids).to contain_exactly( + Group::AUTO_GROUPS[:trust_level_4], + Group::AUTO_GROUPS[:staff] + ) + + expect(message.user_ids).to contain_exactly(user.id) + end + + it 'publishes the message to author and staff group when editing a public post ' \ + 'if SiteSettings.trusted_users_can_edit_others is set to false' do + + post = Fabricate(:post, topic: public_topic, user: user) + SiteSetting.trusted_users_can_edit_others = false + + messages = MessageBus.track_publish do + post '/presence/publish.json', params: { + topic_id: public_topic.id, + post_id: post.id, + state: 'editing', + } + + expect(response.status).to eq(200) + end + + expect(messages.length).to eq(1) + + message = messages.first + + expect(message.group_ids).to contain_exactly(Group::AUTO_GROUPS[:staff]) + expect(message.user_ids).to contain_exactly(user.id) + end + + it 'publishes the message to SiteSetting.min_trust_to_edit_wiki_post group ' \ + 'and staff group when editing a wiki in a public topic' do + + post = Fabricate(:post, topic: public_topic, user: user, wiki: true) + SiteSetting.min_trust_to_edit_wiki_post = TrustLevel.levels[:basic] + + messages = MessageBus.track_publish do + post '/presence/publish.json', params: { + topic_id: public_topic.id, + post_id: post.id, + state: 'editing', + } + + expect(response.status).to eq(200) + end + + expect(messages.length).to eq(1) + + message = messages.first + + expect(message.group_ids).to contain_exactly( + Group::AUTO_GROUPS[:trust_level_1], + Group::AUTO_GROUPS[:staff] + ) + + expect(message.user_ids).to contain_exactly(user.id) + end + + it 'publishes the message to author and staff group when editing a private message' do + post = Fabricate(:post, topic: private_message, user: user) + + messages = MessageBus.track_publish do + post '/presence/publish.json', params: { + topic_id: private_message.id, + post_id: post.id, + state: 'editing', + } + + expect(response.status).to eq(200) + end + + expect(messages.length).to eq(1) + + message = messages.first + + expect(message.group_ids).to contain_exactly( + Group::AUTO_GROUPS[:staff], + ) + + expect(message.user_ids).to contain_exactly(user.id) + end + + it 'publishes the message to users with trust levels of SiteSetting.min_trust_to_edit_wiki_post ' \ + 'and staff group when editing a wiki in a private message' do + + post = Fabricate(:post, + topic: private_message, + user: private_message.user, + wiki: true + ) + + user2.update!(trust_level: TrustLevel.levels[:newuser]) + group.add(user2) + + SiteSetting.min_trust_to_edit_wiki_post = TrustLevel.levels[:basic] + + messages = MessageBus.track_publish do + post '/presence/publish.json', params: { + topic_id: private_message.id, + post_id: post.id, + state: 'editing', + } + + expect(response.status).to eq(200) + end + + expect(messages.length).to eq(1) + + message = messages.first + + expect(message.group_ids).to contain_exactly( + Group::AUTO_GROUPS[:staff], + group.id + ) + + expect(message.user_ids).to contain_exactly( + *private_message.allowed_users.pluck(:id) + ) + end + + it 'publises the right message when closing composer in public topic' do + messages = MessageBus.track_publish do + post '/presence/publish.json', params: { + topic_id: public_topic.id, + state: described_class::CLOSED_STATE, + } + + expect(response.status).to eq(200) + end + + expect(messages.length).to eq(1) + + message = messages.first + + expect(message.group_ids).to eq(nil) + expect(message.user_ids).to eq(nil) + end + + it 'publises the right message when closing composer in private topic' do + messages = MessageBus.track_publish do + post '/presence/publish.json', params: { + topic_id: private_topic.id, + state: described_class::CLOSED_STATE, + } + + expect(response.status).to eq(200) + end + + expect(messages.length).to eq(1) + + message = messages.first + + expect(message.group_ids).to contain_exactly(group.id) + expect(message.user_ids).to eq(nil) + end + + it 'publises the right message when closing composer in private message' do + post = Fabricate(:post, topic: private_message, user: user) + + messages = MessageBus.track_publish do + post '/presence/publish.json', params: { + topic_id: private_message.id, + state: described_class::CLOSED_STATE, + } + + expect(response.status).to eq(200) + end + + expect(messages.length).to eq(1) + + message = messages.first + + expect(message.group_ids).to contain_exactly( + Group::AUTO_GROUPS[:staff], + group.id + ) + + expect(message.user_ids).to contain_exactly( + *private_message.allowed_users.pluck(:id) + ) + end end end - - context 'when logged in' do - before do - sign_in(user1) - end - - it "doesn't produce an error" do - expect { post '/presence/publish.json' }.not_to raise_error - end - - it "does not publish for users with disabled presence features" do - user1.user_option.update_column(:hide_profile_and_presence, true) - post '/presence/publish.json' - expect(response.code).to eq("404") - end - - it "uses guardian to secure endpoint" do - private_post = Fabricate(:private_message_post) - - post '/presence/publish.json', params: { - current: { action: 'edit', post_id: private_post.id } - } - - expect(response.code.to_i).to eq(403) - - group = Fabricate(:group) - category = Fabricate(:private_category, group: group) - private_topic = Fabricate(:topic, category: category) - - post '/presence/publish.json', params: { - current: { action: 'edit', topic_id: private_topic.id } - } - - expect(response.code.to_i).to eq(403) - end - - it "returns a response when requested" do - messages = MessageBus.track_publish do - post '/presence/publish.json', params: { - current: { compose_state: 'open', action: 'edit', post_id: post1.id }, response_needed: true - } - end - - expect(messages.count).to eq(1) - - data = JSON.parse(response.body) - - expect(data['messagebus_channel']).to eq("/presence/post/#{post1.id}") - expect(data['messagebus_id']).to eq(MessageBus.last_id("/presence/post/#{post1.id}")) - expect(data['users'][0]["id"]).to eq(user1.id) - end - - it "doesn't return a response when not requested" do - messages = MessageBus.track_publish do - post '/presence/publish.json', params: { - current: { compose_state: 'open', action: 'edit', post_id: post1.id } - } - end - - expect(messages.count).to eq(1) - - data = JSON.parse(response.body) - expect(data).to eq({}) - end - - it "does send duplicate messagebus messages" do - messages = MessageBus.track_publish do - post '/presence/publish.json', params: { - current: { compose_state: 'open', action: 'edit', post_id: post1.id } - } - end - - expect(messages.count).to eq(1) - - messages = MessageBus.track_publish do - post '/presence/publish.json', params: { - current: { compose_state: 'open', action: 'edit', post_id: post1.id } - } - end - - # we do this cause we also publish time - expect(messages.count).to eq(1) - end - - it "clears 'previous' state when supplied" do - messages = MessageBus.track_publish do - post '/presence/publish.json', params: { - current: { compose_state: 'open', action: 'edit', post_id: post1.id } - } - - post '/presence/publish.json', params: { - current: { compose_state: 'open', action: 'edit', post_id: post2.id }, - previous: { compose_state: 'open', action: 'edit', post_id: post1.id } - } - end - - expect(messages.count).to eq(3) - end - - it 'cleans up old users when requested' do - freeze_time Time.zone.now do - manager.add('topic', post1.topic.id, user2.id) - end - - # Anything older than 20 seconds should be cleaned up - freeze_time 30.seconds.from_now do - post '/presence/publish.json', params: { - current: { compose_state: 'open', action: 'reply', topic_id: post1.topic.id }, response_needed: true - } - - data = JSON.parse(response.body) - - expect(data['users'].length).to eq(1) - end - - end - - describe 'when post has been deleted' do - it 'should return an empty response' do - post1.destroy! - - post '/presence/publish.json', params: { - current: { compose_state: 'open', action: 'edit', post_id: post1.id } - } - - expect(response.status).to eq(200) - expect(JSON.parse(response.body)).to eq({}) - - post '/presence/publish.json', params: { - current: { compose_state: 'open', action: 'edit', post_id: post2.id }, - previous: { compose_state: 'open', action: 'edit', post_id: post1.id } - } - - expect(response.status).to eq(200) - expect(JSON.parse(response.body)).to eq({}) - end - end - - end - end diff --git a/plugins/discourse-unsupported-browser/assets/javascripts/initializers/discourse-unsupported-browser.js.es6 b/plugins/discourse-unsupported-browser/assets/javascripts/initializers/discourse-unsupported-browser.js.es6 new file mode 100644 index 0000000000..a2c96deb82 --- /dev/null +++ b/plugins/discourse-unsupported-browser/assets/javascripts/initializers/discourse-unsupported-browser.js.es6 @@ -0,0 +1,23 @@ +import { withPluginApi } from "discourse/lib/plugin-api"; + +function initializeInternetExplorerDeprecation(api) { + const siteSettings = api.container.lookup("site-settings:main"); + if (siteSettings.browser_deprecation_warning) { + const { isIE11 } = api.container.lookup("capabilities:main"); + if (isIE11) { + api.addGlobalNotice( + I18n.t("discourse_unsupported_browser.deprecation_warning"), + "browser-deprecation-warning", + { dismissable: true, dismissDuration: moment.duration(1, "week") } + ); + } + } +} + +export default { + name: "discourse-unsupported-browser", + + initialize() { + withPluginApi("0.8.37", initializeInternetExplorerDeprecation); + } +}; diff --git a/plugins/discourse-internet-explorer/assets/stylesheets/ie.scss b/plugins/discourse-unsupported-browser/assets/stylesheets/ie.scss similarity index 100% rename from plugins/discourse-internet-explorer/assets/stylesheets/ie.scss rename to plugins/discourse-unsupported-browser/assets/stylesheets/ie.scss diff --git a/plugins/discourse-unsupported-browser/config/locales/client.en.yml b/plugins/discourse-unsupported-browser/config/locales/client.en.yml new file mode 100644 index 0000000000..fca8ed0b1e --- /dev/null +++ b/plugins/discourse-unsupported-browser/config/locales/client.en.yml @@ -0,0 +1,4 @@ +en: + js: + discourse_unsupported_browser: + deprecation_warning: This site will soon remove support for Internet Explorer 11 - please update your browser diff --git a/plugins/discourse-unsupported-browser/config/locales/server.en.yml b/plugins/discourse-unsupported-browser/config/locales/server.en.yml new file mode 100644 index 0000000000..aa0ed026bc --- /dev/null +++ b/plugins/discourse-unsupported-browser/config/locales/server.en.yml @@ -0,0 +1,4 @@ +en: + site_settings: + discourse_unsupported_browser_enabled: "Enable temporary support for old browsers. This plugin is an effort to maintain compatibility with older browsers and will be completely removed in the near future." + browser_deprecation_warning: "Show a warning to deprecated browsers" diff --git a/plugins/discourse-unsupported-browser/config/settings.yml b/plugins/discourse-unsupported-browser/config/settings.yml new file mode 100644 index 0000000000..6aa3ccf598 --- /dev/null +++ b/plugins/discourse-unsupported-browser/config/settings.yml @@ -0,0 +1,6 @@ +plugins: + discourse_unsupported_browser_enabled: + default: true + browser_deprecation_warning: + default: true + client: true diff --git a/plugins/discourse-unsupported-browser/plugin.rb b/plugins/discourse-unsupported-browser/plugin.rb new file mode 100644 index 0000000000..c27d442090 --- /dev/null +++ b/plugins/discourse-unsupported-browser/plugin.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +# name: discourse-unsupported-browser +# about: Attempts to provide support for old and unsupported browser through polyfills +# version: 1.0 +# authors: Joffrey Jaffeux, David Taylor, Daniel Waterworth, Robin Ward +# url: https://github.com/discourse/discourse/tree/master/plugins/discourse-unsupported-browser + +enabled_site_setting :discourse_unsupported_browser_enabled +hide_plugin if self.respond_to?(:hide_plugin) + +register_asset 'stylesheets/ie.scss' + +# We can't use register asset for an optional resource. Instead copy it after plugins have +# been activated so it can be uploaded to CDNs. +DiscourseEvent.on(:after_plugin_activation) do || + polyfill_path = "#{Plugin::Instance.js_path}/#{self.directory_name}-optional.js" + FileUtils.cp("#{Rails.root}/public/plugins/discourse-unsupported-browser/js/ie.js", polyfill_path) + Rails.configuration.assets.precompile << "plugins/discourse-unsupported-browser-optional.js" +end + +after_initialize do + # Conditionally load the stylesheet + register_asset_filter do |type, request| + request.nil? || request.env['HTTP_USER_AGENT'] =~ /MSIE|Trident/ + end + + register_anonymous_cache_key(:ie) do + unless defined?(@is_ie) + session = @env[self.class::RACK_SESSION] + # don't initialize params until later + # otherwise you get a broken params on the request + params = {} + + @is_ie = BrowserDetection.browser(@env[self.class::USER_AGENT]) == :ie + end + + @is_ie + end + + # not using patch on preload_script as js is fine and we need this file + # to be loaded before other files + register_html_builder('server:before-script-load') do |controller| + if BrowserDetection.browser(controller.request.env['HTTP_USER_AGENT']) == :ie + path = controller.helpers.script_asset_path('plugins/discourse-unsupported-browser-optional') + + <<~JAVASCRIPT + + JAVASCRIPT + end + end +end diff --git a/plugins/discourse-internet-explorer/public/js/ie.js b/plugins/discourse-unsupported-browser/public/js/ie.js similarity index 100% rename from plugins/discourse-internet-explorer/public/js/ie.js rename to plugins/discourse-unsupported-browser/public/js/ie.js diff --git a/plugins/discourse-internet-explorer/spec/middleware/anonymous_cache_spec.rb b/plugins/discourse-unsupported-browser/spec/middleware/anonymous_cache_spec.rb similarity index 100% rename from plugins/discourse-internet-explorer/spec/middleware/anonymous_cache_spec.rb rename to plugins/discourse-unsupported-browser/spec/middleware/anonymous_cache_spec.rb diff --git a/plugins/discourse-unsupported-browser/spec/requests/bootstrap_request_spec.rb b/plugins/discourse-unsupported-browser/spec/requests/bootstrap_request_spec.rb new file mode 100644 index 0000000000..036e1ced50 --- /dev/null +++ b/plugins/discourse-unsupported-browser/spec/requests/bootstrap_request_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Bootstrapping the Discourse App' do + let(:ie_agent) { "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko" } + + context "when disabled" do + before do + SiteSetting.discourse_unsupported_browser_enabled = false + end + + it "does not include the IE stylesheet or Javascript" do + get "/categories", headers: { "HTTP_USER_AGENT" => ie_agent } + expect(response.body).not_to match(/discourse-unsupported-browser-optional.js/) + expect(response.body).not_to match(/stylesheets\/discourse-unsupported-browser/) + end + end + + context "when enabled" do + before do + SiteSetting.discourse_unsupported_browser_enabled = true + end + + it "includes the IE js and css" do + get "/categories", headers: { "HTTP_USER_AGENT" => ie_agent } + expect(response.body).to match(/discourse-unsupported-browser-optional.js/) + expect(response.body).to match(/stylesheets\/discourse-unsupported-browser/) + end + + it "doesn't include IE stuff for non-IE browsers" do + get "/categories", headers: { "HTTP_USER_AGENT" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36" } + expect(response.body).not_to match(/discourse-unsupported-browser-optional.js/) + expect(response.body).not_to match(/stylesheets\/discourse-unsupported-browser/) + end + end +end diff --git a/plugins/lazy-yt/assets/javascripts/lazyYT.js b/plugins/lazy-yt/assets/javascripts/lazyYT.js index 10673ebd13..897c15497d 100644 --- a/plugins/lazy-yt/assets/javascripts/lazyYT.js +++ b/plugins/lazy-yt/assets/javascripts/lazyYT.js @@ -98,7 +98,7 @@ } $thumb = $el.find('.ytp-thumbnail').css({ - 'background-image': ['url(//img.youtube.com/vi/', id, '/', thumb_img, ')'].join('') + 'background-image': ['url(https://img.youtube.com/vi/', id, '/', thumb_img, ')'].join('') }) .addClass('lazyYT-image-loaded') .on('click', function (e) { diff --git a/plugins/lazy-yt/plugin.rb b/plugins/lazy-yt/plugin.rb index 02d143b371..9d0af49153 100644 --- a/plugins/lazy-yt/plugin.rb +++ b/plugins/lazy-yt/plugin.rb @@ -27,7 +27,19 @@ class Onebox::Engine::YoutubeOnebox # Put in the LazyYT div instead of the iframe escaped_title = ERB::Util.html_escape(video_title) - "
" + + <<~EOF +
+ + + +
+ EOF else yt_onebox_to_html end diff --git a/plugins/poll/app/models/poll.rb b/plugins/poll/app/models/poll.rb index 4f7e0bd584..44ce17f46c 100644 --- a/plugins/poll/app/models/poll.rb +++ b/plugins/poll/app/models/poll.rb @@ -4,7 +4,7 @@ class Poll < ActiveRecord::Base # because we want to use the 'type' column and don't want to use STI self.inheritance_column = nil - belongs_to :post + belongs_to :post, -> { unscope(:where) } has_many :poll_options, -> { order(:id) }, dependent: :destroy has_many :poll_votes @@ -51,7 +51,7 @@ class Poll < ActiveRecord::Base end def is_me?(user) - user && post.user&.id == user&.id + user && post && post.user&.id == user&.id end def has_voted?(user) diff --git a/plugins/poll/assets/javascripts/controllers/poll-ui-builder.js.es6 b/plugins/poll/assets/javascripts/controllers/poll-ui-builder.js.es6 index e5ca3d05d6..a653b8113b 100644 --- a/plugins/poll/assets/javascripts/controllers/poll-ui-builder.js.es6 +++ b/plugins/poll/assets/javascripts/controllers/poll-ui-builder.js.es6 @@ -15,8 +15,14 @@ export default Controller.extend({ closedPollResult: "on_close", staffPollResult: "staff_only", pollChartTypes: [ - { name: BAR_CHART_TYPE.capitalize(), value: BAR_CHART_TYPE }, - { name: PIE_CHART_TYPE.capitalize(), value: PIE_CHART_TYPE } + { + name: I18n.t("poll.ui_builder.poll_chart_type.bar"), + value: BAR_CHART_TYPE + }, + { + name: I18n.t("poll.ui_builder.poll_chart_type.pie"), + value: PIE_CHART_TYPE + } ], pollType: null, diff --git a/plugins/poll/config/locales/client.en.yml b/plugins/poll/config/locales/client.en.yml index ae4a258e88..035630f421 100644 --- a/plugins/poll/config/locales/client.en.yml +++ b/plugins/poll/config/locales/client.en.yml @@ -118,6 +118,8 @@ en: label: Allowed groups poll_chart_type: label: Chart type + bar: Bar + pie: Pie poll_config: max: Max min: Min diff --git a/plugins/poll/config/locales/client.he.yml b/plugins/poll/config/locales/client.he.yml index bc872cf83f..9362da2ee6 100644 --- a/plugins/poll/config/locales/client.he.yml +++ b/plugins/poll/config/locales/client.he.yml @@ -103,6 +103,8 @@ he: label: קבוצות מורשות poll_chart_type: label: סוג תרשים + bar: עמודות + pie: עוגה poll_config: max: מרבי min: מזערי diff --git a/plugins/poll/config/locales/client.it.yml b/plugins/poll/config/locales/client.it.yml index 042475014e..ae32f0db6f 100644 --- a/plugins/poll/config/locales/client.it.yml +++ b/plugins/poll/config/locales/client.it.yml @@ -93,6 +93,8 @@ it: label: Gruppi ammessi poll_chart_type: label: Tipo di grafico + bar: Barra + pie: Torta poll_config: max: Massimo min: Minimo diff --git a/plugins/poll/config/locales/client.ko.yml b/plugins/poll/config/locales/client.ko.yml index ff5fc69310..30ffe031fb 100644 --- a/plugins/poll/config/locales/client.ko.yml +++ b/plugins/poll/config/locales/client.ko.yml @@ -13,6 +13,17 @@ ko: total_votes: other: "전체 투표" average_rating: "평균: %{average}." + public: + title: "투표는 공개 입니다." + results: + groups: + title: "이 여론 조사에 투표하려면 %{groups} 회원이어야합니다." + vote: + title: "투표 결과가 표시됩니다." + closed: + title: "결과가 닫히면 표시 됩니다." + staff: + title: "결과는 직원 에게만 표시됩니다." multiple: help: at_least_min_options: @@ -30,7 +41,15 @@ ko: label: "결과 보기" hide-results: title: "투표로 돌아가기" + label: "투표 표시" + group-results: + title: "사용자 필드 별 그룹 투표" + label: "고장 표시" + ungroup-results: + title: "모든 투표를 결합" + label: "고장 숨기기" export-results: + title: "설문 조사 결과 내보내기" label: "내보내기" open: title: "투표 열기" @@ -40,14 +59,20 @@ ko: title: "투표 닫기" label: "닫기" confirm: "정말 이 투표를 닫으시겠어요?" + automatic_close: + closes_in: "%{timeLeft} 에서 닫습니다." + age: "휴관일 %{age}" error_while_toggling_status: "죄송합니다. 이 투표의 상태를 바꾸는 도중 에러가 발생하였습니다." error_while_casting_votes: "죄송합니다. 투표를 하는 도중 에러가 발생하였습니다." error_while_fetching_voters: "죄송합니다. 투표한 사람을 표시하는 도중 에러가 발생하였습니다." + error_while_exporting_results: "설문 조사 결과를 내보내는 중에 오류가 발생했습니다." ui_builder: title: 투표 만들기 insert: 투표 삽입하기 help: + options_count: 최소 1 개의 옵션을 입력하십시오 invalid_values: 최소값은 최대값보다는 작아야 합니다. + min_step_value: 최소 단계 값은 1입니다. poll_type: label: 유형 regular: 단일 선택 @@ -55,6 +80,14 @@ ko: number: 점수 매기기 poll_result: label: 검색 결과 + always: 항상 보이는 + vote: 투표에 + closed: 닫을 때 + staff: 직원 만 + poll_groups: + label: 허용 된 그룹 + poll_chart_type: + label: 차트 종류 poll_config: max: 최대 min: 최소 @@ -63,3 +96,5 @@ ko: label: 투표한 사람 보기 poll_options: label: 투표 선택지는 한줄에 하나씩 입력하세요 + automatic_close: + label: 설문 조사 자동 종료 diff --git a/plugins/poll/config/locales/client.nl.yml b/plugins/poll/config/locales/client.nl.yml index 83dff4bef1..1fdc3c18db 100644 --- a/plugins/poll/config/locales/client.nl.yml +++ b/plugins/poll/config/locales/client.nl.yml @@ -93,6 +93,8 @@ nl: label: Toegestane groepen poll_chart_type: label: Diagramtype + bar: Staaf + pie: Cirkel poll_config: max: Max min: Min diff --git a/plugins/poll/config/locales/client.ru.yml b/plugins/poll/config/locales/client.ru.yml index 0c7ffd71e2..9e50d65702 100644 --- a/plugins/poll/config/locales/client.ru.yml +++ b/plugins/poll/config/locales/client.ru.yml @@ -103,6 +103,8 @@ ru: label: Разрешенные группы poll_chart_type: label: Тип диаграммы + bar: Гистограмма + pie: Круговая poll_config: max: Макс. min: Мин. diff --git a/plugins/poll/config/locales/client.sv.yml b/plugins/poll/config/locales/client.sv.yml index d7e50b2411..ea5d5d65ee 100644 --- a/plugins/poll/config/locales/client.sv.yml +++ b/plugins/poll/config/locales/client.sv.yml @@ -93,6 +93,8 @@ sv: label: Tillåtna grupper poll_chart_type: label: Diagramtyp + bar: Stapel + pie: Cirkel poll_config: max: Max min: Min diff --git a/plugins/poll/config/locales/client.zh_CN.yml b/plugins/poll/config/locales/client.zh_CN.yml index f4a5ee570b..c7475e3025 100644 --- a/plugins/poll/config/locales/client.zh_CN.yml +++ b/plugins/poll/config/locales/client.zh_CN.yml @@ -88,6 +88,8 @@ zh_CN: label: 允许的群组 poll_chart_type: label: 图表类型 + bar: 条形 + pie: 饼状 poll_config: max: 最大 min: 最小 diff --git a/plugins/poll/config/locales/server.ko.yml b/plugins/poll/config/locales/server.ko.yml index 4805460e33..fc975d5d5a 100644 --- a/plugins/poll/config/locales/server.ko.yml +++ b/plugins/poll/config/locales/server.ko.yml @@ -7,25 +7,42 @@ ko: site_settings: + poll_enabled: "설문 조사를 허용 하시겠습니까?" poll_maximum_options: "한 투표 당 설정할 수 있는 최대 투표 항목 수" poll_edit_window_mins: "포스트 생성 이후 투표를 편집할 수 있는 시간(분)" + poll_minimum_trust_level_to_create: "설문 조사를 작성하는 데 필요한 최소 신뢰 레벨을 정의하십시오." + poll_groupable_user_fields: "설문 조사 결과를 그룹화하고 필터링하는 데 사용할 수있는 사용자 필드 이름 세트입니다." + poll_export_data_explorer_query_id: "폴링 결과를 내보내는 데 사용할 Data Explorer Query의 ID입니다 (0은 사용 안함)." poll: + poll: "투표" + invalid_argument: "'%{argument}'인수에 대해 '%{value}'값이 잘못되었습니다." multiple_polls_without_name: "이름없는 투표가 여러 개 있습니다. 'name' 속성을 사용해서 투표에 특색을 부여해보세요." multiple_polls_with_same_name: "같은 이름 %{name} 으로 투표가 여러 개 있습니다. 'name' 속성을 사용하여 투표를 구분해보세요." + default_poll_must_have_at_least_1_option: "설문 조사에는 1 개 이상의 옵션이 있어야합니다." + named_poll_must_have_at_least_1_option: "이름이 %{name} 인 설문 조사에는 하나 이상의 옵션이 있어야합니다." default_poll_must_have_less_options: other: "투표 항목은 %{count}개보다 적어야합니다." named_poll_must_have_less_options: other: "%{name} 투표 에는 최소 %{count} 개의 투표 항목이 있어야 합니다." default_poll_must_have_different_options: "투표 항목은 각각의 내용이 달라야 합니다." named_poll_must_have_different_options: "%{name} 투표의 투표 항목 내용이 제각기 달라야 합니다." + default_poll_must_not_have_any_empty_options: "설문 조사에는 빈 옵션이 없어야합니다." + named_poll_must_not_have_any_empty_options: "이름이 %{name} 인 폴에는 빈 옵션이 없어야 합니다." default_poll_with_multiple_choices_has_invalid_parameters: "복수응답 가능한 투표가 잘못된 매개변수를 가지고 있습니다." named_poll_with_multiple_choices_has_invalid_parameters: "복수응답 가능한 %{name} 투표가 잘못된 매개변수를 가지고 있습니다." requires_at_least_1_valid_option: "유효한 투표 항목을 적어도 1개는 선택해야 합니다." + edit_window_expired: + cannot_edit_default_poll_with_votes: "처음 %{minutes} 분 후에는 폴링을 변경할 수 없습니다." + cannot_edit_named_poll_with_votes: "처음 %{minutes} 분 후에는 폴 이름 $ {name} 을 (를) 변경할 수 없습니다." no_poll_with_this_name: "이 포스트와 관련한 %{name} 라는 이름의 투표는 없습니다." post_is_deleted: "지워진 포스트에는 불가능합니다." + user_cant_post_in_topic: "이 주제에 게시 할 수 없으므로 투표 할 수 없습니다." topic_must_be_open_to_vote: "토픽이 열려야 투표를 할 수 있습니다." poll_must_be_open_to_vote: "투표가 열려있어야 표결할 수 있습니다." topic_must_be_open_to_toggle_status: "토픽이 열려야 상태 변경을 할 수 있습니다." only_staff_or_op_can_toggle_status: "운영진이나 작성자만이 투표 상태를 변경할 수 있습니다." + insufficient_rights_to_create: "설문 조사를 만들 수 없습니다." email: link_to_poll: "클릭해서 투표보기" + user_field: + no_data: "데이터 없음" diff --git a/plugins/poll/spec/models/poll_spec.rb b/plugins/poll/spec/models/poll_spec.rb index 55e6567d47..fed3310b84 100644 --- a/plugins/poll/spec/models/poll_spec.rb +++ b/plugins/poll/spec/models/poll_spec.rb @@ -69,4 +69,18 @@ describe ::DiscoursePoll::Poll do expect(poll.can_see_results?(user)).to eq(true) end end + + describe 'when post is trashed' do + it "maintains the association" do + user = Fabricate(:user) + post = Fabricate(:post, raw: "[poll results=staff_only]\n- A\n- B\n[/poll]", user: user) + poll = post.polls.first + + post.trash! + poll.reload + + expect(poll.post).to eq(post) + end + + end end diff --git a/script/bulk_import/base.rb b/script/bulk_import/base.rb index 8af89155e1..9fc7b1cd17 100644 --- a/script/bulk_import/base.rb +++ b/script/bulk_import/base.rb @@ -26,7 +26,7 @@ module BulkImport; end class BulkImport::Base - NOW ||= "now()".freeze + NOW ||= "now()" PRIVATE_OFFSET ||= 2**30 # rubocop:disable Layout/HashAlignment @@ -660,7 +660,7 @@ class BulkImport::Base imported_ids << mapped[:imported_id] unless mapped[:imported_id].nil? imported_ids |= mapped[:imported_ids] unless mapped[:imported_ids].nil? @raw_connection.put_copy_data columns.map { |c| processed[c] } - print "\r%7d - %6d/sec".freeze % [imported_ids.size, imported_ids.size.to_f / (Time.now - start)] if imported_ids.size % 5000 == 0 + print "\r%7d - %6d/sec" % [imported_ids.size, imported_ids.size.to_f / (Time.now - start)] if imported_ids.size % 5000 == 0 rescue => e puts "\n" puts "ERROR: #{e.inspect}" @@ -669,7 +669,7 @@ class BulkImport::Base end if imported_ids.size > 0 - print "\r%7d - %6d/sec".freeze % [imported_ids.size, imported_ids.size.to_f / (Time.now - start)] + print "\r%7d - %6d/sec" % [imported_ids.size, imported_ids.size.to_f / (Time.now - start)] puts end diff --git a/script/bulk_import/discourse_merger.rb b/script/bulk_import/discourse_merger.rb index 9029bdb28a..35ff800822 100644 --- a/script/bulk_import/discourse_merger.rb +++ b/script/bulk_import/discourse_merger.rb @@ -4,7 +4,7 @@ require_relative "base" class BulkImport::DiscourseMerger < BulkImport::Base - NOW ||= "now()".freeze + NOW ||= "now()" CUSTOM_FIELDS = ['category', 'group', 'post', 'topic', 'user'] # DB_NAME: name of database being merged into the current local db diff --git a/script/bulk_import/vanilla.rb b/script/bulk_import/vanilla.rb index 2efed5f31f..71307dba0a 100644 --- a/script/bulk_import/vanilla.rb +++ b/script/bulk_import/vanilla.rb @@ -209,7 +209,7 @@ class BulkImport::Vanilla < BulkImport::Base User.find_each do |u| count += 1 - print "\r%7d - %6d/sec".freeze % [count, count.to_f / (Time.now - start)] + print "\r%7d - %6d/sec" % [count, count.to_f / (Time.now - start)] next unless u.custom_fields["import_id"] @@ -276,7 +276,7 @@ class BulkImport::Vanilla < BulkImport::Base Post.where("raw LIKE '%/us.v-cdn.net/%' OR raw LIKE '%[attachment%'").find_each do |post| count += 1 - print "\r%7d - %6d/sec".freeze % [count, count.to_f / (Time.now - start)] + print "\r%7d - %6d/sec" % [count, count.to_f / (Time.now - start)] new_raw = post.raw.dup new_raw.gsub!(attachment_regex) do |s| @@ -613,7 +613,7 @@ class BulkImport::Vanilla < BulkImport::Base ) end - print "\r%7d - %6d/sec".freeze % [count, count.to_f / (Time.now - start)] if count % 5000 == 0 + print "\r%7d - %6d/sec" % [count, count.to_f / (Time.now - start)] if count % 5000 == 0 end end @@ -645,7 +645,7 @@ class BulkImport::Vanilla < BulkImport::Base end end - print "\r%7d - %6d/sec".freeze % [count, count.to_f / (Time.now - start)] if count % 5000 == 0 + print "\r%7d - %6d/sec" % [count, count.to_f / (Time.now - start)] if count % 5000 == 0 end end end diff --git a/script/bulk_import/vbulletin.rb b/script/bulk_import/vbulletin.rb index fef661fa91..b437137c38 100644 --- a/script/bulk_import/vbulletin.rb +++ b/script/bulk_import/vbulletin.rb @@ -608,7 +608,7 @@ class BulkImport::VBulletin < BulkImport::Base count = 0 Dir.foreach(AVATAR_DIR) do |item| - print "\r%7d - %6d/sec".freeze % [count, count.to_f / (Time.now - start)] + print "\r%7d - %6d/sec" % [count, count.to_f / (Time.now - start)] next if item == ('.') || item == ('..') || item == ('.DS_Store') next unless item =~ /avatar(\d+)_(\d).gif/ diff --git a/script/import_scripts/base.rb b/script/import_scripts/base.rb index ea43db2730..48bd67e516 100644 --- a/script/import_scripts/base.rb +++ b/script/import_scripts/base.rb @@ -606,9 +606,10 @@ class ImportScripts::Base skipped += 1 puts "Skipping bookmark for user id #{params[:user_id]} and post id #{params[:post_id]}" else - result = PostActionCreator.create(user, post, :bookmark) - created += 1 if result.success? - skipped += 1 if result.failed? + result = BookmarkManager.new(user).create(post_id: post.id) + + created += 1 if result.errors.none? + skipped += 1 if result.errors.any? end end diff --git a/script/import_scripts/mbox/support/indexer.rb b/script/import_scripts/mbox/support/indexer.rb index 7017c2a59f..dc6e092c29 100644 --- a/script/import_scripts/mbox/support/indexer.rb +++ b/script/import_scripts/mbox/support/indexer.rb @@ -39,7 +39,7 @@ module ImportScripts::Mbox private - METADATA_FILENAME = 'metadata.yml'.freeze + METADATA_FILENAME = 'metadata.yml' IGNORED_FILE_EXTENSIONS = ['.dbindex', '.dbnames', '.digest', '.subjects', '.yml'] def index_category(directory) diff --git a/script/import_scripts/vbulletin5.rb b/script/import_scripts/vbulletin5.rb index 38489314b2..682cbcdc50 100644 --- a/script/import_scripts/vbulletin5.rb +++ b/script/import_scripts/vbulletin5.rb @@ -6,14 +6,19 @@ require 'htmlentities' class ImportScripts::VBulletin < ImportScripts::Base BATCH_SIZE = 1000 - DBPREFIX = "vb_" ROOT_NODE = 2 - - # CHANGE THESE BEFORE RUNNING THE IMPORTER - DATABASE = "yourforum" TIMEZONE = "America/Los_Angeles" - ATTACHMENT_DIR = '/home/discourse/yourforum/customattachments/' - AVATAR_DIR = '/home/discourse/yourforum/avatars/' + + # override these using environment vars + + URL_PREFIX ||= ENV['URL_PREFIX'] || "forum/" + DB_PREFIX ||= ENV['DB_PREFIX'] || "vb_" + DB_HOST ||= ENV['DB_HOST'] || "localhost" + DB_NAME ||= ENV['DB_NAME'] || "vbulletin" + DB_PASS ||= ENV['DB_PASS'] || "password" + DB_USER ||= ENV['DB_USER'] || "username" + ATTACH_DIR ||= ENV['ATTACH_DIR'] || "/home/discourse/vbulletin/attach" + AVATAR_DIR ||= ENV['AVATAR_DIR'] || "/home/discourse/vbulletin/avatars" def initialize super @@ -25,12 +30,15 @@ class ImportScripts::VBulletin < ImportScripts::Base @htmlentities = HTMLEntities.new @client = Mysql2::Client.new( - host: "localhost", - username: "root", - database: DATABASE, - password: "password" + host: DB_HOST, + username: DB_USER, + database: DB_NAME, + password: DB_PASS ) + @forum_typeid = mysql_query("SELECT contenttypeid FROM #{DB_PREFIX}contenttype WHERE class='Forum'").first['contenttypeid'] + @channel_typeid = mysql_query("SELECT contenttypeid FROM #{DB_PREFIX}contenttype WHERE class='Channel'").first['contenttypeid'] + @text_typeid = mysql_query("SELECT contenttypeid FROM #{DB_PREFIX}contenttype WHERE class='Text'").first['contenttypeid'] end def execute @@ -40,8 +48,10 @@ class ImportScripts::VBulletin < ImportScripts::Base import_topics import_posts import_attachments + import_tags close_topics post_process_posts + create_permalinks end def import_groups @@ -49,7 +59,7 @@ class ImportScripts::VBulletin < ImportScripts::Base groups = mysql_query <<-SQL SELECT usergroupid, title - FROM #{DBPREFIX}usergroup + FROM #{DB_PREFIX}usergroup ORDER BY usergroupid SQL @@ -64,7 +74,7 @@ class ImportScripts::VBulletin < ImportScripts::Base def import_users puts "", "importing users" - user_count = mysql_query("SELECT COUNT(userid) count FROM #{DBPREFIX}user").first["count"] + user_count = mysql_query("SELECT COUNT(userid) count FROM #{DB_PREFIX}user").first["count"] batches(BATCH_SIZE) do |offset| users = mysql_query <<-SQL @@ -73,8 +83,8 @@ class ImportScripts::VBulletin < ImportScripts::Base WHEN u.scheme='legacy' THEN REPLACE(token, ' ', ':') END AS password, IF(ug.title = 'Administrators', 1, 0) AS admin - FROM #{DBPREFIX}user u - LEFT JOIN #{DBPREFIX}usergroup ug ON ug.usergroupid = u.usergroupid + FROM #{DB_PREFIX}user u + LEFT JOIN #{DB_PREFIX}usergroup ug ON ug.usergroupid = u.usergroupid ORDER BY userid LIMIT #{BATCH_SIZE} OFFSET #{offset} @@ -101,7 +111,7 @@ class ImportScripts::VBulletin < ImportScripts::Base post_create_action: proc do |u| @old_username_to_new_usernames[user["username"]] = u.username import_profile_picture(user, u) - import_profile_background(user, u) + # import_profile_background(user, u) end } end @@ -111,7 +121,7 @@ class ImportScripts::VBulletin < ImportScripts::Base def import_profile_picture(old_user, imported_user) query = mysql_query <<-SQL SELECT filedata, filename - FROM #{DBPREFIX}customavatar + FROM #{DB_PREFIX}customavatar WHERE userid = #{old_user["userid"]} ORDER BY dateline DESC LIMIT 1 @@ -148,7 +158,7 @@ class ImportScripts::VBulletin < ImportScripts::Base def import_profile_background(old_user, imported_user) query = mysql_query <<-SQL SELECT filedata, filename - FROM #{DBPREFIX}customprofilepic + FROM #{DB_PREFIX}customprofilepic WHERE userid = #{old_user["userid"]} ORDER BY dateline DESC LIMIT 1 @@ -176,13 +186,13 @@ class ImportScripts::VBulletin < ImportScripts::Base puts "", "importing top level categories..." categories = mysql_query("SELECT nodeid AS forumid, title, description, displayorder, parentid - FROM #{DBPREFIX}node + FROM #{DB_PREFIX}node WHERE parentid=#{ROOT_NODE} UNION SELECT nodeid, title, description, displayorder, parentid - FROM #{DBPREFIX}node - WHERE contenttypeid = 23 - AND parentid IN (SELECT nodeid FROM #{DBPREFIX}node WHERE parentid=#{ROOT_NODE})").to_a + FROM #{DB_PREFIX}node + WHERE contenttypeid = #{@channel_typeid} + AND parentid IN (SELECT nodeid FROM #{DB_PREFIX}node WHERE parentid=#{ROOT_NODE})").to_a top_level_categories = categories.select { |c| c["parentid"] == ROOT_NODE } @@ -224,19 +234,26 @@ class ImportScripts::VBulletin < ImportScripts::Base # keep track of closed topics @closed_topic_ids = [] - topic_count = mysql_query("select count(nodeid) cnt from #{DBPREFIX}node where parentid in ( - select nodeid from #{DBPREFIX}node where contenttypeid=23 ) and contenttypeid=22;").first["cnt"] + topic_count = mysql_query("SELECT COUNT(nodeid) cnt + FROM #{DB_PREFIX}node + WHERE (unpublishdate = 0 OR unpublishdate IS NULL) + AND (approved = 1 AND showapproved = 1) + AND parentid IN ( + SELECT nodeid FROM #{DB_PREFIX}node WHERE contenttypeid=#{@channel_typeid} ) AND contenttypeid=#{@text_typeid};" + ).first["cnt"] batches(BATCH_SIZE) do |offset| topics = mysql_query <<-SQL SELECT t.nodeid AS threadid, t.title, t.parentid AS forumid,t.open,t.userid AS postuserid,t.publishdate AS dateline, nv.count views, 1 AS visible, t.sticky, CONVERT(CAST(rawtext AS BINARY)USING utf8) AS raw - FROM #{DBPREFIX}node t - LEFT JOIN #{DBPREFIX}nodeview nv ON nv.nodeid=t.nodeid - LEFT JOIN #{DBPREFIX}text txt ON txt.nodeid=t.nodeid - WHERE t.parentid in ( select nodeid from #{DBPREFIX}node where contenttypeid=23 ) - AND t.contenttypeid = 22 + FROM #{DB_PREFIX}node t + LEFT JOIN #{DB_PREFIX}nodeview nv ON nv.nodeid=t.nodeid + LEFT JOIN #{DB_PREFIX}text txt ON txt.nodeid=t.nodeid + WHERE t.parentid in ( select nodeid from #{DB_PREFIX}node where contenttypeid=#{@channel_typeid} ) + AND t.contenttypeid = #{@text_typeid} + AND (t.unpublishdate = 0 OR t.unpublishdate IS NULL) + AND t.approved = 1 AND t.showapproved = 1 ORDER BY t.nodeid LIMIT #{BATCH_SIZE} OFFSET #{offset} @@ -277,19 +294,19 @@ class ImportScripts::VBulletin < ImportScripts::Base rescue end - post_count = mysql_query("SELECT COUNT(nodeid) cnt FROM #{DBPREFIX}node WHERE parentid NOT IN ( - SELECT nodeid FROM #{DBPREFIX}node WHERE contenttypeid=23 ) AND contenttypeid=22;").first["cnt"] + post_count = mysql_query("SELECT COUNT(nodeid) cnt FROM #{DB_PREFIX}node WHERE parentid NOT IN ( + SELECT nodeid FROM #{DB_PREFIX}node WHERE contenttypeid=#{@channel_typeid} ) AND contenttypeid=#{@text_typeid};").first["cnt"] batches(BATCH_SIZE) do |offset| posts = mysql_query <<-SQL SELECT p.nodeid AS postid, p.userid AS userid, p.parentid AS threadid, CONVERT(CAST(rawtext AS BINARY)USING utf8) AS raw, p.publishdate AS dateline, 1 AS visible, p.parentid AS parentid - FROM #{DBPREFIX}node p - LEFT JOIN #{DBPREFIX}nodeview nv ON nv.nodeid=p.nodeid - LEFT JOIN #{DBPREFIX}text txt ON txt.nodeid=p.nodeid - WHERE p.parentid NOT IN ( select nodeid from #{DBPREFIX}node where contenttypeid=23 ) - AND p.contenttypeid = 22 + FROM #{DB_PREFIX}node p + LEFT JOIN #{DB_PREFIX}nodeview nv ON nv.nodeid=p.nodeid + LEFT JOIN #{DB_PREFIX}text txt ON txt.nodeid=p.nodeid + WHERE p.parentid NOT IN ( select nodeid from #{DB_PREFIX}node where contenttypeid=#{@channel_typeid} ) + AND p.contenttypeid = #{@text_typeid} ORDER BY postid LIMIT #{BATCH_SIZE} OFFSET #{offset} @@ -320,86 +337,65 @@ class ImportScripts::VBulletin < ImportScripts::Base end end - # find the uploaded file information from the db - def find_upload(post, attachment_id) - sql = "SELECT a.filedataid, a.filename, fd.userid, LENGTH(fd.filedata) AS dbsize, filedata - FROM #{DBPREFIX}attach a - LEFT JOIN #{DBPREFIX}filedata fd ON fd.filedataid = a.filedataid - WHERE a.nodeid = #{attachment_id}" - results = mysql_query(sql) - - unless (row = results.first) - puts "Couldn't find attachment record for post.id = #{post.id}, import_id = #{post.custom_fields['import_id']}" - return nil - end - - filename = File.join(ATTACHMENT_DIR, row['userid'].to_s.split('').join('/'), "#{row['filedataid']}.attach") - real_filename = row['filename'] - real_filename.prepend SecureRandom.hex if real_filename[0] == '.' - - unless File.exists?(filename) - if row['dbsize'].to_i == 0 - puts "Attachment file #{row['filedataid']} doesn't exist" - return nil - end - - tmpfile = 'attach_' + row['filedataid'].to_s - filename = File.join('/tmp/', tmpfile) - File.open(filename, 'wb') { |f| - #f.write(PG::Connection.unescape_bytea(row['filedata'])) - f.write(row['filedata']) - } - end - - upload = create_upload(post.user.id, filename, real_filename) - - if upload.nil? || !upload.valid? - puts "Upload not valid :(" - puts upload.errors.inspect if upload - return nil - end - - [upload, real_filename] - rescue Mysql2::Error => e - puts "SQL Error" - puts e.message - puts sql - nil - end - def import_attachments puts '', 'importing attachments...' + ext = mysql_query("SELECT GROUP_CONCAT(DISTINCT(extension)) exts FROM #{DB_PREFIX}filedata").first['exts'].split(',') + SiteSetting.authorized_extensions = (SiteSetting.authorized_extensions.split("|") + ext).uniq.join("|") + + uploads = mysql_query <<-SQL + SELECT n.parentid nodeid, a.filename, fd.userid, LENGTH(fd.filedata) AS dbsize, filedata, fd.filedataid + FROM #{DB_PREFIX}attach a + LEFT JOIN #{DB_PREFIX}filedata fd ON fd.filedataid = a.filedataid + LEFT JOIN #{DB_PREFIX}node n on n.nodeid = a.nodeid + SQL + current_count = 0 - total_count = mysql_query("SELECT COUNT(nodeid) cnt FROM #{DBPREFIX}node WHERE contenttypeid=22 ").first["cnt"] + total_count = uploads.count - success_count = 0 - fail_count = 0 + uploads.each do |upload| + post_id = PostCustomField.where(name: 'import_id').where(value: upload['nodeid']).first&.post_id + post_id = PostCustomField.where(name: 'import_id').where(value: "thread-#{upload['nodeid']}").first&.post_id unless post_id + if post_id.nil? + puts "Post for #{upload['nodeid']} not found" + next + end + post = Post.find(post_id) - attachment_regex = /\[attach[^\]]*\]n(\d+)\[\/attach\]/i + filename = File.join(ATTACH_DIR, upload['userid'].to_s.split('').join('/'), "#{upload['filedataid']}.attach") + real_filename = upload['filename'] + real_filename.prepend SecureRandom.hex if real_filename[0] == '.' - Post.find_each do |post| - current_count += 1 - print_status current_count, total_count - - new_raw = post.raw.dup - new_raw.gsub!(attachment_regex) do |s| - matches = attachment_regex.match(s) - attachment_id = matches[1] - - upload, filename = find_upload(post, attachment_id) - unless upload - fail_count += 1 + unless File.exists?(filename) + # attachments can be on filesystem or in database + # try to retrieve from database if the file did not exist on filesystem + if upload['dbsize'].to_i == 0 + puts "Attachment file #{upload['filedataid']} doesn't exist" next end - html_for_upload(upload, filename) + + tmpfile = 'attach_' + upload['filedataid'].to_s + filename = File.join('/tmp/', tmpfile) + File.open(filename, 'wb') { |f| + #f.write(PG::Connection.unescape_bytea(row['filedata'])) + f.write(upload['filedata']) + } end - if new_raw != post.raw - PostRevisor.new(post).revise!(post.user, { raw: new_raw }, bypass_bump: true, edit_reason: 'Import attachments from vBulletin') + upl_obj = create_upload(post.user.id, filename, real_filename) + if upl_obj&.persisted? + html = html_for_upload(upl_obj, real_filename) + if !post.raw[html] + post.raw += "\n\n#{html}\n\n" + post.save! + PostUpload.create!(post: post, upload: upl_obj) unless PostUpload.where(post: post, upload: upl_obj).exists? + end + else + puts "Fail" + exit end - - success_count += 1 + current_count += 1 + print_status(current_count, total_count) end end @@ -619,6 +615,105 @@ class ImportScripts::VBulletin < ImportScripts::Base raw end + def create_permalinks + puts "", "creating permalinks..." + + current_count = 0 + total_count = mysql_query("SELECT COUNT(nodeid) cnt + FROM #{DB_PREFIX}node + WHERE (unpublishdate = 0 OR unpublishdate IS NULL) + AND (approved = 1 AND showapproved = 1) + AND parentid IN ( + SELECT nodeid FROM #{DB_PREFIX}node WHERE contenttypeid=#{@channel_typeid} ) AND contenttypeid=#{@text_typeid};" + ).first["cnt"] + + batches(BATCH_SIZE) do |offset| + topics = mysql_query <<-SQL + SELECT p.urlident p1, f.urlident p2, t.nodeid, t.urlident p3 + FROM #{DB_PREFIX}node f + LEFT JOIN #{DB_PREFIX}node t ON t.parentid = f.nodeid + LEFT JOIN #{DB_PREFIX}node p ON p.nodeid = f.parentid + WHERE f.contenttypeid = #{@channel_typeid} + AND t.contenttypeid = #{@text_typeid} + AND t.approved = 1 AND t.showapproved = 1 + AND (t.unpublishdate = 0 OR t.unpublishdate IS NULL) + ORDER BY t.nodeid + LIMIT #{BATCH_SIZE} + OFFSET #{offset} + SQL + + break if topics.size < 1 + + topics.each do |topic| + current_count += 1 + print_status current_count, total_count + disc_topic = topic_lookup_from_imported_post_id("thread-#{topic['nodeid']}") + + Permalink.create( + url: "#{URL_PREFIX}#{topic['p1']}/#{topic['p2']}/#{topic['nodeid']}-#{topic['p3']}", + topic_id: disc_topic[:topic_id] + ) rescue nil + end + end + + # cats + cats = mysql_query <<-SQL + SELECT nodeid, urlident + FROM #{DB_PREFIX}node + WHERE contenttypeid=#{@channel_typeid} + AND parentid=#{ROOT_NODE}; + SQL + cats.each do |c| + category_id = CategoryCustomField.where(name: 'import_id').where(value: c['nodeid']).first.category_id + Permalink.create(url: "#{URL_PREFIX}#{c['urlident']}", category_id: category_id) rescue nil + end + + # subcats + subcats = mysql_query <<-SQL + SELECT n1.nodeid,n2.urlident p1,n1.urlident p2 + FROM #{DB_PREFIX}node n1 + LEFT JOIN #{DB_PREFIX}node n2 ON n2.nodeid=n1.parentid + WHERE n2.parentid = #{ROOT_NODE} + AND n1.contenttypeid=#{@channel_typeid}; + SQL + subcats.each do |sc| + category_id = CategoryCustomField.where(name: 'import_id').where(value: sc['nodeid']).first.category_id + Permalink.create(url: "#{URL_PREFIX}#{sc['p1']}/#{sc['p2']}", category_id: category_id) rescue nil + end + end + + def import_tags + puts "", "importing tags..." + + SiteSetting.tagging_enabled = true + SiteSetting.max_tags_per_topic = 100 + staff_guardian = Guardian.new(Discourse.system_user) + + records = mysql_query(<<~SQL + SELECT nodeid, GROUP_CONCAT(tagtext) tags + FROM #{DB_PREFIX}tag t + LEFT JOIN #{DB_PREFIX}tagnode tn ON tn.tagid = t.tagid + WHERE t.tagid IS NOT NULL + AND tn.nodeid IS NOT NULL + GROUP BY nodeid + SQL + ).to_a + + current_count = 0 + total_count = records.count + + records.each do |rec| + current_count += 1 + print_status current_count, total_count + tl = topic_lookup_from_imported_post_id("thread-#{rec['nodeid']}") + next if tl.nil? # topic might have been deleted + + topic = Topic.find(tl[:topic_id]) + tag_names = rec['tags'].force_encoding("UTF-8").split(',') + DiscourseTagging.tag_topic_by_names(topic, staff_guardian, tag_names) + end + end + def parse_timestamp(timestamp) Time.zone.at(@tz.utc_to_local(timestamp)) end @@ -626,7 +721,6 @@ class ImportScripts::VBulletin < ImportScripts::Base def mysql_query(sql) @client.query(sql, cache_rows: false) end - end ImportScripts::VBulletin.new.perform diff --git a/spec/components/auth/github_authenticator_spec.rb b/spec/components/auth/github_authenticator_spec.rb index 37c14b1546..ae50424c90 100644 --- a/spec/components/auth/github_authenticator_spec.rb +++ b/spec/components/auth/github_authenticator_spec.rb @@ -60,6 +60,17 @@ describe Auth::GithubAuthenticator do expect(result.email_valid).to eq(true) end + it 'can authenticate and update GitHub screen_name for existing user' do + GithubUserInfo.create!(user_id: user.id, github_user_id: 100, screen_name: "boris") + + result = authenticator.after_authenticate(data) + + expect(result.user.id).to eq(user.id) + expect(result.email).to eq(user.email) + expect(result.email_valid).to eq(true) + expect(GithubUserInfo.where(user_id: user.id).pluck(:screen_name)).to eq([user.username]) + end + it 'should use primary email for new user creation over other available emails' do hash = { extra: { diff --git a/spec/components/cooked_post_processor_spec.rb b/spec/components/cooked_post_processor_spec.rb index 94d87ce0b0..47262f1342 100644 --- a/spec/components/cooked_post_processor_spec.rb +++ b/spec/components/cooked_post_processor_spec.rb @@ -552,7 +552,8 @@ describe CookedPostProcessor do upload.update(secure: true, access_control_post: post) end - it "handles secure images with the correct lightbox link href" do + # TODO fix this spec, it is sometimes getting CDN links when it runs concurrently + xit "handles secure images with the correct lightbox link href" do cpp.post_process expect(cpp.html).to match_html cooked_html diff --git a/spec/components/discourse_tagging_spec.rb b/spec/components/discourse_tagging_spec.rb index 35ff67a9a9..b8d328f980 100644 --- a/spec/components/discourse_tagging_spec.rb +++ b/spec/components/discourse_tagging_spec.rb @@ -475,7 +475,7 @@ describe DiscourseTagging do describe "clean_tag" do it "downcases new tags if setting enabled" do - expect(DiscourseTagging.clean_tag("HeLlO".freeze)).to eq("hello") + expect(DiscourseTagging.clean_tag("HeLlO")).to eq("hello") SiteSetting.force_lowercase_tags = false expect(DiscourseTagging.clean_tag("HeLlO")).to eq("HeLlO") diff --git a/spec/components/guardian/user_guardian_spec.rb b/spec/components/guardian/user_guardian_spec.rb index e870843549..b812fa9526 100644 --- a/spec/components/guardian/user_guardian_spec.rb +++ b/spec/components/guardian/user_guardian_spec.rb @@ -341,4 +341,73 @@ describe UserGuardian do include_examples "can_delete_user staff examples" end end + + describe "#can_merge_user?" do + shared_examples "can_merge_user examples" do + it "isn't allowed if user is a staff" do + staff = Fabricate(:moderator) + expect(guardian.can_merge_user?(staff)).to eq(false) + end + end + + context "for moderators" do + let(:guardian) { Guardian.new(moderator) } + include_examples "can_merge_user examples" + + it "isn't allowed if current_user is not an admin" do + expect(guardian.can_merge_user?(user)).to eq(false) + end + end + + context "for admins" do + let(:guardian) { Guardian.new(admin) } + include_examples "can_merge_user examples" + end + end + + describe "#can_see_review_queue?" do + it 'returns true when the user is a staff member' do + guardian = Guardian.new(moderator) + expect(guardian.can_see_review_queue?).to eq(true) + end + + it 'returns false for a regular user' do + guardian = Guardian.new(user) + expect(guardian.can_see_review_queue?).to eq(false) + end + + it "returns true when the user's group can review an item in the queue" do + group = Fabricate(:group) + group.add(user) + guardian = Guardian.new(user) + SiteSetting.enable_category_group_review = true + + Fabricate(:reviewable_flagged_post, reviewable_by_group: group, category: nil) + + expect(guardian.can_see_review_queue?).to eq(true) + end + + it 'returns false if category group review is disabled' do + group = Fabricate(:group) + group.add(user) + guardian = Guardian.new(user) + SiteSetting.enable_category_group_review = false + + Fabricate(:reviewable_flagged_post, reviewable_by_group: group, category: nil) + + expect(guardian.can_see_review_queue?).to eq(false) + end + + it 'returns false if the reviewable is under a read restricted category' do + group = Fabricate(:group) + group.add(user) + guardian = Guardian.new(user) + SiteSetting.enable_category_group_review = true + category = Fabricate(:category, read_restricted: true) + + Fabricate(:reviewable_flagged_post, reviewable_by_group: group, category: category) + + expect(guardian.can_see_review_queue?).to eq(false) + end + end end diff --git a/spec/components/html_to_markdown_spec.rb b/spec/components/html_to_markdown_spec.rb index 266e875aca..3d19c66f9a 100644 --- a/spec/components/html_to_markdown_spec.rb +++ b/spec/components/html_to_markdown_spec.rb @@ -10,7 +10,7 @@ describe HtmlToMarkdown do end it "remove whitespaces" do - expect(html_to_markdown(<<-HTML + html = <<-HTML
Hello,

    This is the 1st paragraph.   
@@ -20,11 +20,54 @@ describe HtmlToMarkdown do
HTML - )).to eq("Hello,\n\nThis is the 1st paragraph.\n\nThis is another paragraph") + + expect(html_to_markdown(html)).to eq("Hello,\n\nThis is the 1st paragraph.\n\nThis is another paragraph") + + html = <<~HTML + +

Let me see if it happens by answering your message through + Thunderbird.

+

Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 + Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 + Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 + Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 + Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 + Long sentence 1 +

+ + HTML + + markdown = <<~MD + Let me see if it happens by answering your message through Thunderbird. + + Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 Long sentence 1 + MD + + expect(html_to_markdown(html)).to eq(markdown.strip) + + html = <<~HTML +

This post + has lots
of + space +

+
    This     space    was   left untouched     !
+ HTML + + markdown = <<~MD + This post has lots + of space + + ``` + This space was left untouched ! + ``` + MD + + expect(html_to_markdown(html)).to eq(markdown.strip) end it "skips hidden tags" do expect(html_to_markdown(%Q{

Hello cruel World!

})).to eq("Hello World!") + expect(html_to_markdown(%Q{

Hello World!

})).to eq("Hello World!") end it "converts " do @@ -37,13 +80,15 @@ describe HtmlToMarkdown do expect(html_to_markdown("B*ld")).to eq("__B*ld__") html = <<~HTML + Before

Bold

+ After HTML - expect(html_to_markdown(html)).to eq("**Bold**") + expect(html_to_markdown(html)).to eq("Before\n\n**Bold**\n\nAfter") end it "converts " do @@ -60,6 +105,11 @@ describe HtmlToMarkdown do expect(html_to_markdown(%Q{Discourse})).to eq("[Discourse](https://www.discourse.org)") end + it "supports SiteSetting.allowed_href_schemes" do + SiteSetting.allowed_href_schemes = "tel|steam" + expect(html_to_markdown(%Q{LIMBO})).to eq("[LIMBO](steam://store/48000)") + end + it "removes empty & invalid " do expect(html_to_markdown(%Q{Discourse})).to eq("Discourse") expect(html_to_markdown(%Q{Discourse})).to eq("Discourse") @@ -67,7 +117,7 @@ describe HtmlToMarkdown do end HTML_WITH_IMG ||= %Q{Discourse Logo} - HTML_WITH_CID_IMG ||= %Q{Discourse Logo} + HTML_WITH_CID_IMG ||= %Q{} it "converts " do expect(html_to_markdown(HTML_WITH_IMG)).to eq("![Discourse Logo](https://www.discourse.org/logo.svg)") @@ -84,8 +134,7 @@ describe HtmlToMarkdown do end it "keeps with src='cid:' whith 'keep_cid_imgs'" do - expect(html_to_markdown(HTML_WITH_CID_IMG, keep_cid_imgs: true)).to eq("![Discourse Logo](cid:ii_1525434659ddb4cb)") - expect(html_to_markdown(HTML_WITH_CID_IMG, keep_img_tags: true, keep_cid_imgs: true)).to eq("\"Discourse") + expect(html_to_markdown(HTML_WITH_CID_IMG, keep_cid_imgs: true)).to eq(HTML_WITH_CID_IMG) end it "skips hidden " do @@ -95,6 +144,12 @@ describe HtmlToMarkdown do expect(html_to_markdown(%Q{})).to eq("") end + it "supports width/height on " do + expect(html_to_markdown(%Q{})).to eq("![](https://www.discourse.org/logo.svg)") + expect(html_to_markdown(%Q{})).to eq("![](https://www.discourse.org/logo.svg)") + expect(html_to_markdown(%Q{})).to eq("![|200x100](https://www.discourse.org/logo.svg)") + end + (1..6).each do |n| it "converts " do expect(html_to_markdown("Header #{n}")).to eq("#" * n + " Header #{n}") @@ -150,11 +205,11 @@ describe HtmlToMarkdown do end it "supports " do - expect(html_to_markdown("Strike Through")).to eq("Strike Through") + expect(html_to_markdown("Strike Through")).to eq("~~Strike Through~~") end it "supports " do - expect(html_to_markdown("Strike Through")).to eq("Strike Through") + expect(html_to_markdown("Strike Through")).to eq("~~Strike Through~~") end it "supports
" do @@ -221,11 +276,11 @@ describe HtmlToMarkdown do it "handles

" do expect(html_to_markdown("

1st paragraph

2nd paragraph

")).to eq("1st paragraph\n\n2nd paragraph") - expect(html_to_markdown("

1st paragraph

\n

2nd paragraph\n 2nd paragraph

\n

3rd paragraph

")).to eq("1st paragraph\n\n2nd paragraph\n2nd paragraph\n\n3rd paragraph") + expect(html_to_markdown("

1st paragraph

\n

2nd paragraph\n 2nd paragraph

\n

3rd paragraph

")).to eq("1st paragraph\n\n2nd paragraph 2nd paragraph\n\n3rd paragraph") end it "handles
" do - expect(html_to_markdown("
1st div
2nd div
")).to eq("1st div\n\n2nd div") + expect(html_to_markdown("
1st div
2nd div
")).to eq("1st div\n2nd div") end it "swallows " do @@ -257,15 +312,19 @@ describe HtmlToMarkdown do context "with an oddly placed
" do it "handles " do - expect(html_to_markdown("
Bold
")).to eq("**Bold**") - expect(html_to_markdown("Bold
")).to eq("**Bold**") - expect(html_to_markdown("Bold
text
")).to eq("**Bold\ntext**") + expect(html_to_markdown("Hello
Bold
World")).to eq("Hello\n**Bold** World") + expect(html_to_markdown("Hello Bold
World")).to eq("Hello **Bold**\nWorld") + expect(html_to_markdown("Hello Bold
text
World")).to eq("Hello **Bold**\n**text** World") end it "handles " do - expect(html_to_markdown("
Italic
")).to eq("*Italic*") - expect(html_to_markdown("Italic
")).to eq("*Italic*") - expect(html_to_markdown("Italic
text
")).to eq("*Italic\ntext*") + expect(html_to_markdown("Hello
Italic
World")).to eq("Hello\n*Italic* World") + expect(html_to_markdown("Hello Italic
World")).to eq("Hello *Italic*\nWorld") + expect(html_to_markdown("Hello Italic
text
World")).to eq("Hello *Italic*\n*text* World") + end + + it "works" do + expect(html_to_markdown("
A B C
D
E
F
G
")).to eq("A __B *C*__\n__*D* E__\n**F** G") end end @@ -314,4 +373,64 @@ describe HtmlToMarkdown do end + it "supoorts " do + html = <<~HTML +
+ + + + + + + + + + + + + + + + + + + + + + +
Thisistheheaders
I amthefirstrow
And thisis the2ndline
+ HTML + + markdown = <<~MD + | This | is | the | *headers* | + | - | - | - | - | + | I am | the | **first** | row | + | And this | is the | 2nd | line | + MD + + expect(html_to_markdown(html)).to eq(markdown.strip) + + expect(html_to_markdown("
HelloWorld
")).to eq("| Hello | World |\n| - | - |") + end + + it "doesn't swallow badly formatted " do + html = <<~HTML +
+ + + + + + + + + + + +
1234
OneTwoThree
+ HTML + + expect(html_to_markdown(html)).to eq("1 2 3 4 \nOne Two Three") + end + end diff --git a/spec/components/plugin/metadata_spec.rb b/spec/components/plugin/metadata_spec.rb index b8ad2ab97c..fe838d8c7b 100644 --- a/spec/components/plugin/metadata_spec.rb +++ b/spec/components/plugin/metadata_spec.rb @@ -45,7 +45,6 @@ TEXT official("customer-flair") official("discourse-adplugin") official("discourse-akismet") - official("discourse-backup-uploads-to-s3") official("discourse-cakeday") official("Canned Replies") official("discourse-data-explorer") diff --git a/spec/components/post_revisor_spec.rb b/spec/components/post_revisor_spec.rb index e5467f44e8..b79490b139 100644 --- a/spec/components/post_revisor_spec.rb +++ b/spec/components/post_revisor_spec.rb @@ -6,7 +6,7 @@ require 'post_revisor' describe PostRevisor do fab!(:topic) { Fabricate(:topic) } - fab!(:newuser) { Fabricate(:newuser) } + fab!(:newuser) { Fabricate(:newuser, last_seen_at: Date.today) } fab!(:user) { Fabricate(:user) } fab!(:admin) { Fabricate(:admin) } fab!(:moderator) { Fabricate(:moderator) } @@ -196,6 +196,19 @@ describe PostRevisor do subject.revise!(post.user, { raw: 'updated body' }, revised_at: post.updated_at + SiteSetting.editing_grace_period + 1.seconds) }.to change { post.topic.bumped_at } end + + it "should send muted and latest message" do + TopicUser.create!(topic: post.topic, user: post.user, notification_level: 0) + messages = MessageBus.track_publish("/latest") do + subject.revise!(post.user, { raw: 'updated body' }, revised_at: post.updated_at + SiteSetting.editing_grace_period + 1.seconds) + end + + muted_message = messages.find { |message| message.data["message_type"] == "muted" } + latest_message = messages.find { |message| message.data["message_type"] == "latest" } + + expect(muted_message.data["topic_id"]).to eq(topic.id) + expect(latest_message.data["topic_id"]).to eq(topic.id) + end end describe 'edit reasons' do diff --git a/spec/fabricators/post_fabricator.rb b/spec/fabricators/post_fabricator.rb index cd18b78967..412504c7c4 100644 --- a/spec/fabricators/post_fabricator.rb +++ b/spec/fabricators/post_fabricator.rb @@ -20,7 +20,7 @@ end Fabricator(:old_post, from: :post) do topic { |attrs| Fabricate(:topic, user: attrs[:user], created_at: (DateTime.now - 100)) } - created_at (DateTime.now - 100) + created_at { 100.days.ago } end Fabricator(:moderator_post, from: :post) do diff --git a/spec/fabricators/topic_fabricator.rb b/spec/fabricators/topic_fabricator.rb index 8fc0307929..3bcee07d2e 100644 --- a/spec/fabricators/topic_fabricator.rb +++ b/spec/fabricators/topic_fabricator.rb @@ -9,7 +9,7 @@ Fabricator(:topic) do end Fabricator(:deleted_topic, from: :topic) do - deleted_at Time.now + deleted_at { 1.minute.ago } end Fabricator(:closed_topic, from: :topic) do diff --git a/spec/fabricators/topic_timer_fabricator.rb b/spec/fabricators/topic_timer_fabricator.rb index 99bacf7cb5..56e3bbae13 100644 --- a/spec/fabricators/topic_timer_fabricator.rb +++ b/spec/fabricators/topic_timer_fabricator.rb @@ -3,6 +3,6 @@ Fabricator(:topic_timer) do user topic - execute_at Time.zone.now + 1.hour + execute_at { 1.hour.from_now } status_type TopicTimer.types[:close] end diff --git a/spec/fabricators/upload_fabricator.rb b/spec/fabricators/upload_fabricator.rb index 72bcb6c723..c2f6952736 100644 --- a/spec/fabricators/upload_fabricator.rb +++ b/spec/fabricators/upload_fabricator.rb @@ -45,7 +45,7 @@ Fabricator(:video_upload, from: :upload) do end Fabricator(:secure_upload, from: :upload) do - secure { true } + secure true sha1 { SecureRandom.hex(20) } original_sha1 { sequence(:sha1) { |n| Digest::SHA1.hexdigest(n.to_s) } } end @@ -67,7 +67,7 @@ Fabricator(:upload_s3, from: :upload) do end Fabricator(:secure_upload_s3, from: :upload_s3) do - secure { true } + secure true sha1 { SecureRandom.hex(20) } original_sha1 { sequence(:sha1) { |n| Digest::SHA1.hexdigest(n.to_s) } } end diff --git a/spec/fabricators/watched_word_fabricator.rb b/spec/fabricators/watched_word_fabricator.rb index b3796cad15..521cb2fded 100644 --- a/spec/fabricators/watched_word_fabricator.rb +++ b/spec/fabricators/watched_word_fabricator.rb @@ -2,5 +2,5 @@ Fabricator(:watched_word) do word { sequence(:word) { |i| "word#{i}" } } - action { WatchedWord.actions[:block] } + action WatchedWord.actions[:block] end diff --git a/spec/fabricators/web_crawler_request_fabricator.rb b/spec/fabricators/web_crawler_request_fabricator.rb index 2d2be02fdf..a20ab4225f 100644 --- a/spec/fabricators/web_crawler_request_fabricator.rb +++ b/spec/fabricators/web_crawler_request_fabricator.rb @@ -2,6 +2,6 @@ Fabricator(:web_crawler_request) do user_agent { sequence(:ua) { |i| "Googlebot #{i}.0" } } - date Time.zone.now.to_date + date { Time.zone.now.to_date } count 0 end diff --git a/spec/fixtures/json/base-import-data.json b/spec/fixtures/json/base-import-data.json new file mode 100644 index 0000000000..08f3f400c7 --- /dev/null +++ b/spec/fixtures/json/base-import-data.json @@ -0,0 +1,57 @@ +{ + "bookmarks":[ + { + "post_id":10, + "user_id":20 + }, + { + "post_id":11, + "user_id":20 + }, + { + "post_id":12, + "user_id":20 + }, + { + "post_id":13, + "user_id":20 + }, + { + "post_id":14, + "user_id":20 + } + ], + "posts":[ + { + "user_id":20, + "id":10, + "raw":"This is test post 1" + }, + { + "user_id":20, + "id":11, + "raw":"This is test post 2" + }, + { + "user_id":20, + "id":12, + "raw":"This is test post 3" + }, + { + "user_id":20, + "id":13, + "raw":"This is test post 4" + }, + { + "user_id":20, + "id":14, + "raw":"This is test post 5" + } + ], + "users":[ + { + "id":20, + "email":"testimportuser@test.com" + } + ] +} diff --git a/spec/integration/multisite_spec.rb b/spec/integration/multisite_spec.rb index 4646cab066..4aa8af580e 100644 --- a/spec/integration/multisite_spec.rb +++ b/spec/integration/multisite_spec.rb @@ -1,69 +1,65 @@ # frozen_string_literal: true -# require 'rails_helper' -# -# describe 'multisite' do -# -# class DBNameMiddleware -# def initialize(app, config = {}) -# @app = app -# end -# -# def call(env) -# # note current_db is already being ruined on boot cause its not multisite -# [200, {}, [RailsMultisite::ConnectionManagement.current_hostname]] -# end -# end -# -# let :session do -# RailsMultisite::ConnectionManagement.config_filename = "spec/fixtures/multisite/two_dbs.yml" -# RailsMultisite::ConnectionManagement.load_settings! -# -# stack = ActionDispatch::MiddlewareStack.new -# stack.use RailsMultisite::ConnectionManagement, RailsMultisite::DiscoursePatches.config -# stack.use DBNameMiddleware -# -# routes = ActionDispatch::Routing::RouteSet.new -# stack.build(routes) -# end -# -# it "should always allow /srv/status through" do -# headers = { -# "HTTP_HOST" => "unknown.com", -# "REQUEST_METHOD" => "GET", -# "PATH_INFO" => "/srv/status", -# "rack.input" => StringIO.new -# } -# -# code, _, body = session.call(headers) -# expect(code).to eq(200) -# expect(body.join).to eq("test.localhost") -# end -# -# it "should 404 on unknown routes" do -# headers = { -# "HTTP_HOST" => "unknown.com", -# "REQUEST_METHOD" => "GET", -# "PATH_INFO" => "/topics", -# "rack.input" => StringIO.new -# } -# -# code, _ = session.call(headers) -# expect(code).to eq(404) -# end -# -# it "should hit correct site elsewise" do -# -# headers = { -# "HTTP_HOST" => "test2.localhost", -# "REQUEST_METHOD" => "GET", -# "PATH_INFO" => "/topics", -# "rack.input" => StringIO.new -# } -# -# code, _, body = session.call(headers) -# expect(code).to eq(200) -# expect(body.join).to eq("test2.localhost") -# end -# -# end +require 'rails_helper' + +describe 'multisite', type: :multisite do + class DBNameMiddleware + def initialize(app, config = {}) + @app = app + end + + def call(env) + # note current_db is already being ruined on boot cause its not multisite + [200, {}, [RailsMultisite::ConnectionManagement.current_hostname]] + end + end + + let :session do + stack = ActionDispatch::MiddlewareStack.new + stack.use RailsMultisite::Middleware, RailsMultisite::DiscoursePatches.config + stack.use DBNameMiddleware + + routes = ActionDispatch::Routing::RouteSet.new + stack.build(routes) + end + + it "should always allow /srv/status through" do + headers = { + "HTTP_HOST" => "unknown.com", + "REQUEST_METHOD" => "GET", + "PATH_INFO" => "/srv/status", + "rack.input" => StringIO.new + } + + code, _, body = session.call(headers) + expect(code).to eq(200) + expect(body.join).to eq("test.localhost") + end + + it "should 404 on unknown routes" do + headers = { + "HTTP_HOST" => "unknown.com", + "REQUEST_METHOD" => "GET", + "PATH_INFO" => "/topics", + "rack.input" => StringIO.new + } + + code, _ = session.call(headers) + expect(code).to eq(404) + end + + it "should hit correct site elsewise" do + + headers = { + "HTTP_HOST" => "test2.localhost", + "REQUEST_METHOD" => "GET", + "PATH_INFO" => "/topics", + "rack.input" => StringIO.new + } + + code, _, body = session.call(headers) + expect(code).to eq(200) + expect(body.join).to eq("test2.localhost") + end + +end diff --git a/spec/jobs/automatic_group_membership_spec.rb b/spec/jobs/automatic_group_membership_spec.rb index afac2b7f3f..8a6611e52c 100644 --- a/spec/jobs/automatic_group_membership_spec.rb +++ b/spec/jobs/automatic_group_membership_spec.rb @@ -20,7 +20,7 @@ describe Jobs::AutomaticGroupMembership do user6 = Fabricate(:user, email: "sso2@wat.com") user6.create_single_sign_on_record(external_id: 456, external_email: "sso2@wat.com", last_payload: "") - group = Fabricate(:group, automatic_membership_email_domains: "wat.com", automatic_membership_retroactive: true) + group = Fabricate(:group, automatic_membership_email_domains: "wat.com") begin automatic = nil diff --git a/spec/jobs/export_csv_file_spec.rb b/spec/jobs/export_csv_file_spec.rb index 8322265a72..9182f9f37d 100644 --- a/spec/jobs/export_csv_file_spec.rb +++ b/spec/jobs/export_csv_file_spec.rb @@ -36,6 +36,13 @@ describe Jobs::ExportCsvFile do expect(system_message.id).to eq(UserExport.last.topic_id) expect(system_message.closed).to eq(true) + + files = [] + Zip::File.open(Discourse.store.path_for(upload)) do |zip_file| + zip_file.each { |entry| files << entry.name } + end + + expect(files.size).to eq(2) ensure user.uploads.each(&:destroy!) end diff --git a/spec/jobs/notify_reviewable_spec.rb b/spec/jobs/notify_reviewable_spec.rb index d4d9691591..5d8702dbd5 100644 --- a/spec/jobs/notify_reviewable_spec.rb +++ b/spec/jobs/notify_reviewable_spec.rb @@ -102,4 +102,15 @@ describe Jobs::NotifyReviewable do expect(group_msg.data[:reviewable_count]).to eq(0) end end + + it 'skips sending notifications if user_ids is empty' do + reviewable = Fabricate(:reviewable, reviewable_by_moderator: true) + regular_user = Fabricate(:user) + + messages = MessageBus.track_publish("/reviewable_counts") do + described_class.new.execute(reviewable_id: reviewable.id) + end + + expect(messages.size).to eq(1) + end end diff --git a/spec/jobs/user_email_spec.rb b/spec/jobs/user_email_spec.rb index 3cea6c3078..e6def350b2 100644 --- a/spec/jobs/user_email_spec.rb +++ b/spec/jobs/user_email_spec.rb @@ -672,32 +672,4 @@ describe Jobs::UserEmail do end end - - context "canonical emails" do - it "correctly creates canonical emails" do - expect(UserEmail.canonical('s.a.m+1@gmail.com')).to eq('sam@gmail.com') - expect(UserEmail.canonical('sa.m+1@googlemail.com')).to eq('sam@googlemail.com') - expect(UserEmail.canonical('sa.m+1722@sam.com')).to eq('sa.m@sam.com') - expect(UserEmail.canonical('sa.m@sam.com')).to eq('sa.m@sam.com') - end - - it "correctly bans non canonical emails" do - - email = UserEmail.create!(email: 'sam@sam.com', user_id: user.id) - expect(email.canonical_email).to eq(nil) - - email = UserEmail.create!(email: 'sam+1@sam.com', user_id: user.id) - expect(email.canonical_email).to eq(nil) - - SiteSetting.enforce_canonical_emails = true - - email = UserEmail.create!(email: 'Sam+5@sam.com', user_id: user.id) - expect(email.canonical_email).to eq('sam@sam.com') - - expect do - UserEmail.create!(email: 'saM+3@sam.com', user_id: user.id) - end.to raise_error(ActiveRecord::RecordInvalid) - - end - end end diff --git a/spec/lib/backup_restore/uploads_restorer_spec.rb b/spec/lib/backup_restore/uploads_restorer_spec.rb index 15fbcd24ce..fba41193fe 100644 --- a/spec/lib/backup_restore/uploads_restorer_spec.rb +++ b/spec/lib/backup_restore/uploads_restorer_spec.rb @@ -73,9 +73,7 @@ describe BackupRestore::UploadsRestorer do def uploads_path(database) path = File.join("uploads", database) - if Discourse.is_parallel_test? - path = File.join(path, ENV['TEST_ENV_NUMBER'].presence || '1') - end + path = File.join(path, "test_#{ENV['TEST_ENV_NUMBER'].presence || '0'}") "/#{path}/" end diff --git a/spec/lib/bookmark_manager_spec.rb b/spec/lib/bookmark_manager_spec.rb index 9dfe6ff23a..34b029b515 100644 --- a/spec/lib/bookmark_manager_spec.rb +++ b/spec/lib/bookmark_manager_spec.rb @@ -21,6 +21,16 @@ RSpec.describe BookmarkManager do expect(bookmark.topic_id).to eq(post.topic_id) end + it "updates the topic user bookmarked column to true if any post is bookmarked" do + subject.create(post_id: post.id, name: name, reminder_type: reminder_type, reminder_at: reminder_at) + tu = TopicUser.find_by(user: user) + expect(tu.bookmarked).to eq(true) + tu.update(bookmarked: false) + subject.create(post_id: Fabricate(:post, topic: post.topic).id) + tu.reload + expect(tu.bookmarked).to eq(true) + end + context "when a reminder time + type is provided" do it "saves the values correctly" do subject.create(post_id: post.id, name: name, reminder_type: reminder_type, reminder_at: reminder_at) @@ -32,14 +42,6 @@ RSpec.describe BookmarkManager do end end - context "when bookmarking the topic level (post is OP)" do - it "updates the topic user bookmarked column to true" do - subject.create(post_id: post.id, name: name, reminder_type: reminder_type, reminder_at: reminder_at) - tu = TopicUser.find_by(user: user) - expect(tu.bookmarked).to eq(true) - end - end - context "when the reminder type is at_desktop" do let(:reminder_type) { 'at_desktop' } let(:reminder_at) { nil } @@ -134,6 +136,15 @@ RSpec.describe BookmarkManager do expect(result[:topic_bookmarked]).to eq(true) end + context "if the bookmark is the last one bookmarked in the topic" do + it "marks the topic user bookmarked column as false" do + TopicUser.create(user: user, topic: bookmark.post.topic, bookmarked: true) + subject.destroy(bookmark.id) + tu = TopicUser.find_by(user: user) + expect(tu.bookmarked).to eq(false) + end + end + context "if the bookmark is belonging to some other user" do let!(:bookmark) { Fabricate(:bookmark, user: Fabricate(:admin), post: post) } it "raises an invalid access error" do diff --git a/spec/lib/bookmark_query_spec.rb b/spec/lib/bookmark_query_spec.rb index c627abfc85..de71757538 100644 --- a/spec/lib/bookmark_query_spec.rb +++ b/spec/lib/bookmark_query_spec.rb @@ -4,20 +4,16 @@ require 'rails_helper' RSpec.describe BookmarkQuery do fab!(:user) { Fabricate(:user) } - fab!(:bookmark1) { Fabricate(:bookmark, user: user) } - fab!(:bookmark2) { Fabricate(:bookmark, user: user) } let(:params) { {} } def bookmark_query(user: nil, params: nil) BookmarkQuery.new(user: user || self.user, params: params || self.params) end - before do - TopicUser.change(user.id, bookmark1.topic_id, total_msecs_viewed: 1) - TopicUser.change(user.id, bookmark2.topic_id, total_msecs_viewed: 1) - end - describe "#list_all" do + fab!(:bookmark1) { Fabricate(:bookmark, user: user) } + fab!(:bookmark2) { Fabricate(:bookmark, user: user) } + it "returns all the bookmarks for a user" do expect(bookmark_query.list_all.count).to eq(2) end @@ -143,4 +139,21 @@ RSpec.describe BookmarkQuery do end end end + + describe "#list_all ordering" do + let!(:bookmark1) { Fabricate(:bookmark, user: user, updated_at: 1.day.ago) } + let!(:bookmark2) { Fabricate(:bookmark, user: user, updated_at: 2.days.ago) } + let!(:bookmark3) { Fabricate(:bookmark, user: user, updated_at: 6.days.ago) } + let!(:bookmark4) { Fabricate(:bookmark, user: user, updated_at: 4.days.ago) } + let!(:bookmark5) { Fabricate(:bookmark, user: user, updated_at: 3.days.ago) } + it "orders by updated_at" do + expect(bookmark_query.list_all.map(&:id)).to eq([ + bookmark1.id, + bookmark2.id, + bookmark5.id, + bookmark4.id, + bookmark3.id + ]) + end + end end diff --git a/spec/lib/content_security_policy_spec.rb b/spec/lib/content_security_policy_spec.rb index 68a5dc2da2..168887cd47 100644 --- a/spec/lib/content_security_policy_spec.rb +++ b/spec/lib/content_security_policy_spec.rb @@ -212,6 +212,29 @@ describe ContentSecurityPolicy do expect(parse(theme_policy)['script-src']).to_not include('https://from-theme-flag.script') expect(parse(theme_policy)['worker-src']).to_not include('from-theme-flag.worker') end + + it 'is extended automatically when themes reference external scripts' do + policy # call this first to make sure further actions clear the cache + + theme.set_field(target: :common, name: "header", value: <<~SCRIPT) + + SCRIPT + + theme.set_field(target: :desktop, name: "header", value: "") + theme.save! + + expect(parse(theme_policy)['script-src']).to include('https://example.com/myscript.js') + expect(parse(theme_policy)['script-src']).to include('example2.com/protocol-less-script.js') + expect(parse(theme_policy)['script-src']).not_to include('domain-only.com') + expect(parse(theme_policy)['script-src']).not_to include(a_string_matching /^\/theme-javascripts/) + + theme.destroy! + + expect(parse(theme_policy)['script-src']).to_not include('https://example.com/myscript.js') + end end it 'can be extended by site setting' do diff --git a/spec/lib/mini_sql_multisite_connection_spec.rb b/spec/lib/mini_sql_multisite_connection_spec.rb index 4d404a4c92..9cfa452178 100644 --- a/spec/lib/mini_sql_multisite_connection_spec.rb +++ b/spec/lib/mini_sql_multisite_connection_spec.rb @@ -49,6 +49,19 @@ describe MiniSqlMultisiteConnection do expect(outputString).to eq("123") end + + it "runs immediately if there is no transaction" do + outputString = "1" + + DB.after_commit do + outputString += "2" + end + + outputString += "3" + + expect(outputString).to eq("123") + end + end end diff --git a/spec/models/badge_spec.rb b/spec/models/badge_spec.rb index 221569de08..73cd39ef0e 100644 --- a/spec/models/badge_spec.rb +++ b/spec/models/badge_spec.rb @@ -113,6 +113,14 @@ describe Badge do expect(Badge.find_system_badge_id_from_translation_key(translation_key)).to eq(nil) end end + + context "when translation key doesn't match its class" do + let(:translation_key) { "badges.licensed.long_description" } + + it "returns nil" do + expect(Badge.find_system_badge_id_from_translation_key(translation_key)).to eq(nil) + end + end end context "First Quote" do diff --git a/spec/models/discourse_single_sign_on_spec.rb b/spec/models/discourse_single_sign_on_spec.rb index 538d18d212..fb318d16bc 100644 --- a/spec/models/discourse_single_sign_on_spec.rb +++ b/spec/models/discourse_single_sign_on_spec.rb @@ -33,6 +33,7 @@ describe DiscourseSingleSignOn do sso.custom_fields["a"] = "Aa" sso.custom_fields["b.b"] = "B.b" sso.website = "https://www.discourse.org/" + sso.location = "Home" sso end @@ -53,6 +54,7 @@ describe DiscourseSingleSignOn do expect(parsed.custom_fields["a"]).to eq "Aa" expect(parsed.custom_fields["b.b"]).to eq "B.b" expect(parsed.website).to eq sso.website + expect(parsed.location).to eq sso.location end it "can do round trip parsing correctly" do diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index 96e7f27757..0cb8362c80 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -942,27 +942,25 @@ describe Group do end describe '#automatic_group_membership' do - describe 'for a automatic_membership_retroactive group' do - let(:group) { Fabricate(:group, automatic_membership_retroactive: true) } + let(:group) { Fabricate(:group, automatic_membership_email_domains: "example.com") } - it "should be triggered on create and update" do - expect { group } - .to change { Jobs::AutomaticGroupMembership.jobs.size }.by(1) + it "should be triggered on create and update" do + expect { group } + .to change { Jobs::AutomaticGroupMembership.jobs.size }.by(1) - job = Jobs::AutomaticGroupMembership.jobs.last + job = Jobs::AutomaticGroupMembership.jobs.last - expect(job["args"].first["group_id"]).to eq(group.id) + expect(job["args"].first["group_id"]).to eq(group.id) - Jobs::AutomaticGroupMembership.jobs.clear + Jobs::AutomaticGroupMembership.jobs.clear - expect do - group.update!(name: 'asdiaksjdias') - end.to change { Jobs::AutomaticGroupMembership.jobs.size }.by(1) + expect do + group.update!(name: 'asdiaksjdias') + end.to change { Jobs::AutomaticGroupMembership.jobs.size }.by(1) - job = Jobs::AutomaticGroupMembership.jobs.last + job = Jobs::AutomaticGroupMembership.jobs.last - expect(job["args"].first["group_id"]).to eq(group.id) - end + expect(job["args"].first["group_id"]).to eq(group.id) end end diff --git a/spec/models/screened_email_spec.rb b/spec/models/screened_email_spec.rb index aeefe195d3..2b33144c10 100644 --- a/spec/models/screened_email_spec.rb +++ b/spec/models/screened_email_spec.rb @@ -26,6 +26,7 @@ describe ScreenedEmail do describe '#block' do context 'email is not being blocked' do + it 'creates a new record with default action of :block' do record = ScreenedEmail.block(email) expect(record).not_to be_new_record @@ -57,6 +58,14 @@ describe ScreenedEmail do describe '#should_block?' do subject { ScreenedEmail.should_block?(email) } + it "automatically blocks via email canonicalization" do + SiteSetting.levenshtein_distance_spammer_emails = 0 + ScreenedEmail.block('bad.acTor+1@gmail.com') + ScreenedEmail.block('bad.actOr+2@gmail.com') + + expect(ScreenedEmail.should_block?('b.a.dactor@gmail.com')).to eq(true) + end + it "returns false if a record with the email doesn't exist" do expect(subject).to eq(false) end diff --git a/spec/models/topic_tracking_state_spec.rb b/spec/models/topic_tracking_state_spec.rb index a68239512d..db0a13f7d2 100644 --- a/spec/models/topic_tracking_state_spec.rb +++ b/spec/models/topic_tracking_state_spec.rb @@ -72,6 +72,46 @@ describe TopicTrackingState do end end + describe '#publish_muted' do + let(:user) do + Fabricate(:user, last_seen_at: Date.today) + end + let(:post) do + create_post(user: user) + end + + it 'can correctly publish muted' do + TopicUser.find_by(topic: topic, user: post.user).update(notification_level: 0) + messages = MessageBus.track_publish("/latest") do + TopicTrackingState.publish_muted(topic) + end + + muted_message = messages.find { |message| message.data["message_type"] == "muted" } + + expect(muted_message.data["topic_id"]).to eq(topic.id) + expect(muted_message.data["message_type"]).to eq(described_class::MUTED_MESSAGE_TYPE) + end + + it 'should not publish any message when notification level is not muted' do + messages = MessageBus.track_publish("/latest") do + TopicTrackingState.publish_muted(topic) + end + muted_messages = messages.select { |message| message.data["message_type"] == "muted" } + + expect(muted_messages).to eq([]) + end + + it 'should not publish any message when the user was not seen in the last 7 days' do + TopicUser.find_by(topic: topic, user: post.user).update(notification_level: 0) + post.user.update(last_seen_at: 8.days.ago) + messages = MessageBus.track_publish("/latest") do + TopicTrackingState.publish_muted(topic) + end + muted_messages = messages.select { |message| message.data["message_type"] == "muted" } + expect(muted_messages).to eq([]) + end + end + describe '#publish_private_message' do fab!(:admin) { Fabricate(:admin) } diff --git a/spec/models/upload_spec.rb b/spec/models/upload_spec.rb index 739ab43d5a..680d0175e3 100644 --- a/spec/models/upload_spec.rb +++ b/spec/models/upload_spec.rb @@ -288,53 +288,6 @@ describe Upload do end end - describe ".consider_for_reuse" do - let(:post) { Fabricate(:post) } - let(:upload) { Fabricate(:upload) } - - it "returns nil when the provided upload is blank" do - expect(Upload.consider_for_reuse(nil, post)).to eq(nil) - end - - it "returns the upload when secure media is disabled" do - expect(Upload.consider_for_reuse(upload, post)).to eq(upload) - end - - context "when secure media enabled" do - before do - enable_secure_media - end - - context "when the upload access control post is != to the provided post" do - before do - upload.update(access_control_post_id: Fabricate(:post).id) - end - - it "returns nil" do - expect(Upload.consider_for_reuse(upload, post)).to eq(nil) - end - end - - context "when the upload original_sha1 is blank (pre-secure-media upload)" do - before do - upload.update(original_sha1: nil, access_control_post: post) - end - - it "returns nil" do - expect(Upload.consider_for_reuse(upload, post)).to eq(nil) - end - end - - context "when the upload original_sha1 is present and access control post is correct" do - let(:upload) { Fabricate(:secure_upload_s3, access_control_post: post) } - - it "returns the upload" do - expect(Upload.consider_for_reuse(upload, post)).to eq(upload) - end - end - end - end - describe '.update_secure_status' do it "respects the secure_override_value parameter if provided" do upload.update!(secure: true) diff --git a/spec/requests/api/categories_spec.rb b/spec/requests/api/categories_spec.rb new file mode 100644 index 0000000000..0c82cfa389 --- /dev/null +++ b/spec/requests/api/categories_spec.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true +require 'swagger_helper' + +describe 'categories' do + + let(:admin) { Fabricate(:admin) } + + before do + Jobs.run_immediately! + sign_in(admin) + end + + path '/categories.json' do + + post 'Creates a category' do + before do + Jobs.run_immediately! + sign_in(admin) + end + tags 'Category' + consumes 'application/json' + parameter name: :category, in: :body, schema: { + type: :object, + properties: { + name: { type: :string }, + color: { type: :string }, + text_color: { type: :string }, + }, + required: [ 'name', 'color', 'text_color' ] + } + + produces 'application/json' + response '200', 'category created' do + schema type: :object, properties: { + category: { + type: :object, + properties: { + id: { type: :integer }, + name: { type: :string }, + color: { type: :string }, + }, + required: ["id"] + } + }, required: ["category"] + + let(:category) { { name: 'todo', color: 'f94cb0', text_color: '412763' } } + run_test! + end + end + + get 'Retreives a list of categories' do + tags 'Category' + produces 'application/json' + + response '200', 'categories response' do + schema type: :object, properties: { + category_list: { + type: :object, + properties: { + can_create_category: { type: :boolean }, + can_create_topic: { type: :boolean }, + draft: { type: :string, nullable: true }, + draft_key: { type: :string }, + draft_sequence: { type: :integer }, + categories: { type: :array }, + }, required: ["categories"] + } + }, required: ["category_list"] + run_test! + end + end + end +end diff --git a/spec/requests/badges_controller_spec.rb b/spec/requests/badges_controller_spec.rb index 0a4971d180..777596a4ff 100644 --- a/spec/requests/badges_controller_spec.rb +++ b/spec/requests/badges_controller_spec.rb @@ -42,4 +42,54 @@ describe BadgesController do expect(response.media_type).to eq('application/rss+xml') end end + + context "user profiles" do + let(:titled_badge) { Fabricate(:badge, name: 'Protector of the Realm', allow_title: true) } + let!(:grant) { UserBadge.create!(user_id: user.id, badge_id: titled_badge.id, granted_at: 1.minute.ago, granted_by_id: -1) } + + it "can be assigned as a title by the user" do + sign_in(user) + put "/u/#{user.username}/preferences/badge_title.json", params: { + user_badge_id: grant.id, + } + expect(response.status).to eq(200) + user.reload + + expect(user.title).to eq(titled_badge.display_name) + expect(user.user_profile.granted_title_badge_id).to eq(titled_badge.id) + end + end + + describe "destroy" do + let(:admin) { Fabricate(:admin) } + + context "while assigned as a title" do + let(:titled_badge) { Fabricate(:badge, name: 'Protector of the Realm', allow_title: true) } + let!(:grant) { UserBadge.create!(user_id: user.id, badge_id: titled_badge.id, granted_at: 1.minute.ago, granted_by_id: -1) } + + before do + sign_in(user) + put "/u/#{user.username}/preferences/badge_title.json", params: { + user_badge_id: grant.id, + } + user.reload + sign_out + end + + it "succeeds and unassigns the title from the user" do + expect(user.title).to eq(titled_badge.display_name) + + sign_in(admin) + badge_id = titled_badge.id + + delete "/admin/badges/#{titled_badge.id}.json" + expect(response.status).to be(200) + expect(Badge.find_by(id: badge_id)).to be(nil) + + user.reload + expect(user.title).to_not eq(titled_badge.display_name) + expect(user.user_profile.granted_title_badge_id).to eq(nil) + end + end + end end diff --git a/spec/requests/groups_controller_spec.rb b/spec/requests/groups_controller_spec.rb index 0f1027edf3..5edf1bcb6f 100644 --- a/spec/requests/groups_controller_spec.rb +++ b/spec/requests/groups_controller_spec.rb @@ -657,8 +657,7 @@ describe GroupsController do mentionable_level: 2, messageable_level: 2, default_notification_level: 0, - grant_trust_level: 0, - automatic_membership_retroactive: false + grant_trust_level: 0 ) expect do @@ -668,7 +667,6 @@ describe GroupsController do messageable_level: 1, visibility_level: 1, automatic_membership_email_domains: 'test.org', - automatic_membership_retroactive: true, title: 'haha', primary_group: true, grant_trust_level: 1, @@ -707,7 +705,6 @@ describe GroupsController do expect(group.messageable_level).to eq(1) expect(group.default_notification_level).to eq(1) expect(group.automatic_membership_email_domains).to eq(nil) - expect(group.automatic_membership_retroactive).to eq(false) expect(group.title).to eq('haha') expect(group.primary_group).to eq(false) expect(group.incoming_email).to eq(nil) @@ -737,7 +734,6 @@ describe GroupsController do group.update!( visibility_level: 2, members_visibility_level: 2, - automatic_membership_retroactive: false, grant_trust_level: 0 ) @@ -748,7 +744,6 @@ describe GroupsController do incoming_email: 'test@mail.org', primary_group: true, automatic_membership_email_domains: 'test.org', - automatic_membership_retroactive: true, grant_trust_level: 2, visibility_level: 1, members_visibility_level: 3 @@ -765,7 +760,6 @@ describe GroupsController do expect(group.visibility_level).to eq(1) expect(group.members_visibility_level).to eq(3) expect(group.automatic_membership_email_domains).to eq('test.org') - expect(group.automatic_membership_retroactive).to eq(true) expect(group.grant_trust_level).to eq(2) expect(Jobs::AutomaticGroupMembership.jobs.first["args"].first["group_id"]) diff --git a/spec/requests/published_pages_controller_spec.rb b/spec/requests/published_pages_controller_spec.rb index ed50ed8811..6793761791 100644 --- a/spec/requests/published_pages_controller_spec.rb +++ b/spec/requests/published_pages_controller_spec.rb @@ -76,9 +76,21 @@ RSpec.describe PublishedPagesController do expect(response.status).to eq(404) end - it "returns 200 for a valid article" do - get published_page.path - expect(response.status).to eq(200) + context "the article is valid" do + before do + SiteSetting.tagging_enabled = true + published_page.topic.tags = [Fabricate(:tag, name: "recipes")] + end + + it "returns 200" do + get published_page.path + expect(response.status).to eq(200) + end + + it "defines correct css classes on body" do + get published_page.path + expect(response.body).to include("") + end end end diff --git a/spec/requests/reviewables_controller_spec.rb b/spec/requests/reviewables_controller_spec.rb index 3763b725e9..b89af08df5 100644 --- a/spec/requests/reviewables_controller_spec.rb +++ b/spec/requests/reviewables_controller_spec.rb @@ -590,7 +590,7 @@ describe ReviewablesController do end context "#destroy" do - fab!(:user) { Fabricate(:user) } + fab!(:user) { Fabricate(:admin) } before do sign_in(user) diff --git a/spec/requests/search_controller_spec.rb b/spec/requests/search_controller_spec.rb index 822ede7a0d..d1d8fff353 100644 --- a/spec/requests/search_controller_spec.rb +++ b/spec/requests/search_controller_spec.rb @@ -219,6 +219,70 @@ describe SearchController do end end + context "search priority" do + fab!(:low_priority_category) do + Fabricate( + :category, + search_priority: Searchable::PRIORITIES[:very_low] + ) + end + fab!(:high_priority_category) do + Fabricate( + :category, + search_priority: Searchable::PRIORITIES[:high] + ) + end + fab!(:very_high_priority_category) do + Fabricate( + :category, + search_priority: Searchable::PRIORITIES[:very_high] + ) + end + fab!(:low_priority_topic) { Fabricate(:topic, category: low_priority_category) } + fab!(:high_priority_topic) { Fabricate(:topic, category: high_priority_category) } + fab!(:very_high_priority_topic) { Fabricate(:topic, category: very_high_priority_category) } + fab!(:low_priority_post) do + SearchIndexer.enable + Fabricate(:post, topic: low_priority_topic, raw: "This is a Low Priority Post") + end + fab!(:hight_priority_post) do + SearchIndexer.enable + Fabricate(:post, topic: high_priority_topic, raw: "This is a High Priority Post") + end + fab!(:old_very_hight_priority_post) do + SearchIndexer.enable + Fabricate(:old_post, topic: very_high_priority_topic, raw: "This is a Old but Very High Priority Post") + end + + it "sort posts with search priority when search term is empty" do + get "/search.json", params: { q: 'status:open' } + expect(response.status).to eq(200) + data = JSON.parse(response.body) + post1 = data["posts"].find { |e| e["id"] == old_very_hight_priority_post.id } + post2 = data["posts"].find { |e| e["id"] == low_priority_post.id } + expect(data["posts"][0]["id"]).to eq(old_very_hight_priority_post.id) + expect(post1["id"]).to be > post2["id"] + end + + it "sort posts with search priority when no order query" do + get "/search.json", params: { q: 'status:open Priority Post' } + expect(response.status).to eq(200) + data = JSON.parse(response.body) + expect(data["posts"][0]["id"]).to eq(old_very_hight_priority_post.id) + expect(data["posts"][1]["id"]).to eq(hight_priority_post.id) + expect(data["posts"][2]["id"]).to eq(low_priority_post.id) + end + + it "doesn't sort posts with search piority when query with order" do + get "/search.json", params: { q: 'status:open order:latest Priority Post' } + expect(response.status).to eq(200) + data = JSON.parse(response.body) + expect(data["posts"][0]["id"]).to eq(hight_priority_post.id) + expect(data["posts"][1]["id"]).to eq(low_priority_post.id) + expect(data["posts"][2]["id"]).to eq(old_very_hight_priority_post.id) + end + end + context "search context" do it "raises an error with an invalid context type" do get "/search/query.json", params: { diff --git a/spec/requests/topics_controller_spec.rb b/spec/requests/topics_controller_spec.rb index e48a2f9483..ebb2b90f04 100644 --- a/spec/requests/topics_controller_spec.rb +++ b/spec/requests/topics_controller_spec.rb @@ -956,6 +956,16 @@ RSpec.describe TopicsController do expect(::JSON.parse(response.body)['basic_topic']).to be_present end + it "throws an error if it could not be saved" do + PostRevisor.any_instance.stubs(:should_revise?).returns(false) + put "/t/#{topic.slug}/#{topic.id}.json", params: { title: "brand new title" } + + expect(response.status).to eq(422) + expect(response.parsed_body['errors'].first).to eq( + I18n.t("activerecord.errors.models.topic.attributes.base.unable_to_update") + ) + end + it "can update a topic to an uncategorized topic" do topic.update!(category: Fabricate(:category)) diff --git a/spec/requests/users_controller_spec.rb b/spec/requests/users_controller_spec.rb index 9bb8992c70..5d09c1031f 100644 --- a/spec/requests/users_controller_spec.rb +++ b/spec/requests/users_controller_spec.rb @@ -654,6 +654,30 @@ describe UsersController do expect(User.find_by(username: @user.username).user_option.timezone).to eq("Australia/Brisbane") end end + + context "with local logins disabled" do + before do + SiteSetting.enable_local_logins = false + SiteSetting.enable_google_oauth2_logins = true + end + + it "blocks registration without authenticator information" do + post_user + expect(response.status).to eq(403) + end + + it "blocks with a regular api key" do + api_key = Fabricate(:api_key, user: user) + post "/u.json", params: post_user_params, headers: { HTTP_API_KEY: api_key.key } + expect(response.status).to eq(403) + end + + it "works with an admin api key" do + api_key = Fabricate(:api_key, user: Fabricate(:admin)) + post "/u.json", params: post_user_params, headers: { HTTP_API_KEY: api_key.key } + expect(response.status).to eq(200) + end + end end context 'when creating a non active user (unconfirmed email)' do diff --git a/spec/script/import_scripts/base_spec.rb b/spec/script/import_scripts/base_spec.rb new file mode 100644 index 0000000000..e7594d2fa5 --- /dev/null +++ b/spec/script/import_scripts/base_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'rails_helper' +require_relative '../../../script/import_scripts/base' + +describe ImportScripts::Base do + before do + STDOUT.stubs(:write) + end + + class MockSpecImporter < ImportScripts::Base + def initialize(data) + super() + @import_data = data + end + + def execute + import_users + import_posts + import_bookmarks + end + + def import_users + users = @import_data[:users] + create_users(users) do |row| + { email: row[:email], id: row[:id] } + end + end + + def import_posts + posts = @import_data[:posts] + create_posts(posts) do |row| + user_id = @lookup.user_id_from_imported_user_id(row[:user_id]) || -1 + { user_id: user_id, raw: row[:raw], id: row[:id], title: "Test topic for post #{row[:id]}" } + end + end + + def import_bookmarks + bookmarks = @import_data[:bookmarks] + create_bookmarks(bookmarks) do |row| + { post_id: row[:post_id], user_id: row[:user_id] } + end + end + end + + let(:import_data) do + import_file = Rack::Test::UploadedFile.new(file_from_fixtures("base-import-data.json", "json")) + ActiveSupport::HashWithIndifferentAccess.new(JSON.parse(import_file.read)) + end + + it "creates bookmarks, posts, and users" do + MockSpecImporter.new(import_data).perform + expect(Bookmark.count).to eq(5) + expect(Post.count).to eq(5) + expect(User.where('id > 0').count).to eq(1) + end +end diff --git a/spec/serializers/basic_group_serializer_spec.rb b/spec/serializers/basic_group_serializer_spec.rb index b905f5d4a1..7231e5d29a 100644 --- a/spec/serializers/basic_group_serializer_spec.rb +++ b/spec/serializers/basic_group_serializer_spec.rb @@ -41,19 +41,17 @@ describe BasicGroupSerializer do end describe '#automatic_membership_email_domains' do - fab!(:group) { Fabricate(:group, automatic_membership_email_domains: 'ilovediscourse.com', automatic_membership_retroactive: true) } + fab!(:group) { Fabricate(:group, automatic_membership_email_domains: 'ilovediscourse.com') } let(:admin_guardian) { Guardian.new(Fabricate(:admin)) } it 'should include email domains for admin' do subject = described_class.new(group, scope: admin_guardian, root: false, owner_group_ids: [group.id]) expect(subject.as_json[:automatic_membership_email_domains]).to eq('ilovediscourse.com') - expect(subject.as_json[:automatic_membership_retroactive]).to eq(true) end it 'should not include email domains for other users' do subject = described_class.new(group, scope: guardian, root: false, owner_group_ids: [group.id]) expect(subject.as_json[:automatic_membership_email_domains]).to eq(nil) - expect(subject.as_json[:automatic_membership_retroactive]).to eq(nil) end end diff --git a/spec/serializers/category_serializer_spec.rb b/spec/serializers/category_serializer_spec.rb index 1557850efd..e2a3399990 100644 --- a/spec/serializers/category_serializer_spec.rb +++ b/spec/serializers/category_serializer_spec.rb @@ -28,4 +28,19 @@ describe CategorySerializer do json = described_class.new(category, scope: Guardian.new, root: false).as_json expect(json[:custom_fields]).to be_present end + + it "includes the default notification level" do + json = described_class.new(category, scope: Guardian.new, root: false).as_json + expect(json[:notification_level]).to eq(CategoryUser.default_notification_level) + end + + describe "user notification level" do + fab!(:user) { Fabricate(:user) } + + it "includes the user's notification level" do + CategoryUser.set_notification_level_for_category(user, NotificationLevels.all[:watching], category.id) + json = described_class.new(category, scope: Guardian.new(user), root: false).as_json + expect(json[:notification_level]).to eq(NotificationLevels.all[:watching]) + end + end end diff --git a/spec/serializers/post_serializer_spec.rb b/spec/serializers/post_serializer_spec.rb index 8791db56c6..91ca676ecd 100644 --- a/spec/serializers/post_serializer_spec.rb +++ b/spec/serializers/post_serializer_spec.rb @@ -235,28 +235,12 @@ describe PostSerializer do s end - context "when a user post action for the bookmark exists" do - before do - PostActionCreator.create(current_user, post, :bookmark) - end - - it "returns true" do - expect(serialized.as_json[:bookmarked]).to eq(true) - end - end - - context "when a user post action for the bookmark does not exist" do - it "does not return the bookmarked attribute" do - expect(serialized.as_json.key?(:bookmarked)).to eq(false) - end - end - context "when a Bookmark record exists for the user on the post" do let!(:bookmark) { Fabricate(:bookmark_next_business_day_reminder, user: current_user, post: post) } context "bookmarks with reminders" do it "returns true" do - expect(serialized.as_json[:bookmarked_with_reminder]).to eq(true) + expect(serialized.as_json[:bookmarked]).to eq(true) end it "returns the reminder_at for the bookmark" do @@ -266,8 +250,8 @@ describe PostSerializer do context "if topic_view is blank" do let(:topic_view) { nil } - it "does not return the bookmarked_with_reminder attribute" do - expect(serialized.as_json.key?(:bookmarked_with_reminder)).to eq(false) + it "does not return the bookmarked attribute" do + expect(serialized.as_json.key?(:bookmarked)).to eq(false) end end end diff --git a/spec/serializers/topic_list_item_serializer_spec.rb b/spec/serializers/topic_list_item_serializer_spec.rb index 1ca54ef311..72acb82aef 100644 --- a/spec/serializers/topic_list_item_serializer_spec.rb +++ b/spec/serializers/topic_list_item_serializer_spec.rb @@ -83,5 +83,15 @@ describe TopicListItemSerializer do expect(json[:tags]).to eq([]) end + + it 'return posters' do + json = TopicListItemSerializer.new(topic, + scope: Guardian.new(user), + hidden_tag_names: [hidden_tag.name], + root: false + ).as_json + + expect(json[:posters].length).to eq(1) + end end end diff --git a/spec/services/post_alerter_spec.rb b/spec/services/post_alerter_spec.rb index 973f31c663..f5f0d14421 100644 --- a/spec/services/post_alerter_spec.rb +++ b/spec/services/post_alerter_spec.rb @@ -110,16 +110,28 @@ describe PostAlerter do admin = Fabricate(:admin) post.revise(admin, raw: 'I made a revision') - # skip this notification cause we already notified on a similar edit + # lets also like this post which should trigger a notification + PostActionCreator.new( + admin, + post, + PostActionType.types[:like] + ).perform + + # skip this notification cause we already notified on an edit by the same user + # in the previous edit freeze_time 2.hours.from_now post.revise(admin, raw: 'I made another revision') + # this we do not skip cause 1 day has passed + freeze_time 23.hours.from_now + post.revise(admin, raw: 'I made another revision xyz') + post.revise(Fabricate(:admin), raw: 'I made a revision') freeze_time 2.hours.from_now post.revise(admin, raw: 'I made another revision') - expect(Notification.where(post_number: 1, topic_id: post.topic_id).count).to eq(3) + expect(Notification.where(post_number: 1, topic_id: post.topic_id).count).to eq(5) end it 'notifies flaggers when flagged post gets unhidden by edit' do @@ -195,14 +207,13 @@ describe PostAlerter do user: evil_trout, data: { topic_title: "test topic" }.to_json ) - expect { - PostAlerter.post_created(post) + PostAlerter.post_edited(post) }.to change(evil_trout.notifications, :count).by(0) notification.destroy expect { - PostAlerter.post_created(post) + PostAlerter.post_edited(post) }.to change(evil_trout.notifications, :count).by(1) end diff --git a/spec/services/user_updater_spec.rb b/spec/services/user_updater_spec.rb index 5ca012fc13..158c943da6 100644 --- a/spec/services/user_updater_spec.rb +++ b/spec/services/user_updater_spec.rb @@ -249,6 +249,38 @@ describe UserUpdater do end end + context 'when sso overrides location' do + it 'does not change location' do + SiteSetting.sso_url = "https://www.example.com/sso" + SiteSetting.enable_sso = true + SiteSetting.sso_overrides_location = true + + user = Fabricate(:user) + updater = UserUpdater.new(acting_user, user) + + expect(updater.update(location: "new location")).to be_truthy + + user.reload + expect(user.user_profile.location).not_to eq 'new location' + end + end + + context 'when sso overrides website' do + it 'does not change website' do + SiteSetting.sso_url = "https://www.example.com/sso" + SiteSetting.enable_sso = true + SiteSetting.sso_overrides_website = true + + user = Fabricate(:user) + updater = UserUpdater.new(acting_user, user) + + expect(updater.update(website: "https://google.com")).to be_truthy + + user.reload + expect(user.user_profile.website).not_to eq 'https://google.com' + end + end + context 'when updating primary group' do let(:new_group) { Group.create(name: 'new_group') } let(:user) { Fabricate(:user) } @@ -416,6 +448,15 @@ describe UserUpdater do end end + context 'when website is invalid' do + it 'returns an error' do + user = Fabricate(:user) + updater = UserUpdater.new(acting_user, user) + + expect(updater.update(website: 'ʔ<')).to eq nil + end + end + context 'when custom_fields is empty string' do it "update is successful" do user = Fabricate(:user) diff --git a/spec/support/webauthn_integration_helpers.rb b/spec/support/webauthn_integration_helpers.rb index d6a32ffd35..09310d0f57 100644 --- a/spec/support/webauthn_integration_helpers.rb +++ b/spec/support/webauthn_integration_helpers.rb @@ -19,23 +19,23 @@ module WebauthnIntegrationHelpers # simulate_localhost_webautn_challenge for a real example. def valid_security_key_data { - credential_id: "9GiFosW50+s+juyJlyxKEVAsk3gZLo9XWIhX47eC4gHfDsldF3TWR43Tcl/+3gLTL5t1TjpmcbKA2DUV2eKrBw==".freeze, - public_key: "pQECAyYgASFYIPMGM1OpSuCU5uks+BulAdfVxdlJiYcgGac5Y+LnLXC9Ilgghy0BKvRvptmQdtWz33Jjnf8Y6+HD85XdRiqmo1KMGPE=".freeze + credential_id: "9GiFosW50+s+juyJlyxKEVAsk3gZLo9XWIhX47eC4gHfDsldF3TWR43Tcl/+3gLTL5t1TjpmcbKA2DUV2eKrBw==", + public_key: "pQECAyYgASFYIPMGM1OpSuCU5uks+BulAdfVxdlJiYcgGac5Y+LnLXC9Ilgghy0BKvRvptmQdtWz33Jjnf8Y6+HD85XdRiqmo1KMGPE=" } end def valid_security_key_auth_post_data { - signature: "MEYCIQC5xyUQvF4qTPZ2yX7crp/IEs1E/4wqhXgxC1EVAumhfgIhAIC/7w4BVEy+ew6vMYISahtnnIqbqsPZosBeTUSI8Y4j".freeze, - clientData: "eyJjaGFsbGVuZ2UiOiJOR1UzWW1Zek0yWTBNelkyWkdFM05EVTNZak5qWldVNFpUWTNOakJoTm1NMFlqVTVORFptTlRrd016Vm1ZMlZpTURVd01UZzJOemcxTW1RMSIsIm9yaWdpbiI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzAwMCIsInR5cGUiOiJ3ZWJhdXRobi5nZXQifQ==".freeze, - authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAA2Q==".freeze, + signature: "MEYCIQC5xyUQvF4qTPZ2yX7crp/IEs1E/4wqhXgxC1EVAumhfgIhAIC/7w4BVEy+ew6vMYISahtnnIqbqsPZosBeTUSI8Y4j", + clientData: "eyJjaGFsbGVuZ2UiOiJOR1UzWW1Zek0yWTBNelkyWkdFM05EVTNZak5qWldVNFpUWTNOakJoTm1NMFlqVTVORFptTlRrd016Vm1ZMlZpTURVd01UZzJOemcxTW1RMSIsIm9yaWdpbiI6Imh0dHA6Ly9sb2NhbGhvc3Q6MzAwMCIsInR5cGUiOiJ3ZWJhdXRobi5nZXQifQ==", + authenticatorData: "SZYN5YgOjGh0NBcPZHZgW4/krrmihjLHmVzzuoMdl2MBAAAA2Q==", credentialId: valid_security_key_data[:credential_id] } end def valid_security_key_challenge_data { - challenge: "4e7bf33f4366da7457b3cee8e6760a6c4b5946f59035fceb0501867852d5".freeze + challenge: "4e7bf33f4366da7457b3cee8e6760a6c4b5946f59035fceb0501867852d5" } end diff --git a/spec/swagger_helper.rb b/spec/swagger_helper.rb new file mode 100644 index 0000000000..5f7737384d --- /dev/null +++ b/spec/swagger_helper.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.configure do |config| + # Specify a root folder where Swagger JSON files are generated + # NOTE: If you're using the rswag-api to serve API descriptions, you'll need + # to ensure that it's configured to serve Swagger from the same folder + config.swagger_root = Rails.root.join('openapi').to_s + + # Define one or more Swagger documents and provide global metadata for each one + # When you run the 'rswag:specs:swaggerize' rake task, the complete Swagger will + # be generated at the provided relative path under swagger_root + # By default, the operations defined in spec files are added to the first + # document below. You can override this behavior by adding a swagger_doc tag to the + # the root example_group in your specs, e.g. describe '...', swagger_doc: 'v2/swagger.json' + config.swagger_docs = { + 'openapi.yaml' => { + openapi: '3.0.3', + info: { + title: 'Discourse API Documentation', + version: 'latest' + }, + paths: {}, + servers: [ + { + url: 'https://{defaultHost}', + variables: { + defaultHost: { + default: 'discourse.example.com' + } + } + } + ] + } + } + + # Specify the format of the output Swagger file when running 'rswag:specs:swaggerize'. + # The swagger_docs configuration option has the filename including format in + # the key, this may want to be changed to avoid putting yaml in json files. + # Defaults to json. Accepts ':json' and ':yaml'. + config.swagger_format = :yaml +end diff --git a/test/javascripts/acceptance/admin-user-index-test.js b/test/javascripts/acceptance/admin-user-index-test.js index 6ea2fd87f0..4c57cbbf97 100644 --- a/test/javascripts/acceptance/admin-user-index-test.js +++ b/test/javascripts/acceptance/admin-user-index-test.js @@ -15,7 +15,6 @@ acceptance("Admin - User Index", { alias_level: 99, visible: true, automatic_membership_email_domains: "", - automatic_membership_retroactive: false, primary_group: false, title: null, grant_trust_level: null, @@ -38,7 +37,9 @@ acceptance("Admin - User Index", { QUnit.test("can edit username", async assert => { pretender.put("/users/sam/preferences/username", () => [ 200, - { "Content-Type": "application/json" }, + { + "Content-Type": "application/json" + }, { id: 2, username: "new-sam" } ]); diff --git a/test/javascripts/acceptance/bookmarks-test.js b/test/javascripts/acceptance/bookmarks-test.js new file mode 100644 index 0000000000..6361d43261 --- /dev/null +++ b/test/javascripts/acceptance/bookmarks-test.js @@ -0,0 +1,200 @@ +import { acceptance, loggedInUser } from "helpers/qunit-helpers"; +import pretender from "helpers/create-pretender"; + +acceptance("Bookmarking", { loggedIn: true }); + +function handleRequest(assert, request) { + const body = request.requestBody; + const reminderType = body + .substr(0, body.indexOf("&")) + .replace("reminder_type=", ""); + + assert.step(reminderType || "none"); + + return [ + 200, + { + "Content-Type": "application/json" + }, + { + id: 999, + success: "OK" + } + ]; +} + +function mockSuccessfulBookmarkPost(assert) { + pretender.post("/bookmarks", request => handleRequest(assert, request)); + pretender.put("/bookmarks/999", request => handleRequest(assert, request)); +} + +async function openBookmarkModal() { + if (exists(".topic-post:first-child button.show-more-actions")) { + await click(".topic-post:first-child button.show-more-actions"); + } + + await click(".topic-post:first-child button.bookmark"); +} + +async function openEditBookmarkModal() { + await click(".topic-post:first-child button.bookmarked"); +} + +test("Bookmarks modal opening", async assert => { + await visit("/t/internationalization-localization/280"); + await openBookmarkModal(); + assert.ok(exists("#bookmark-reminder-modal"), "it shows the bookmark modal"); +}); + +test("Bookmarks modal selecting reminder type", async assert => { + mockSuccessfulBookmarkPost(assert); + + await visit("/t/internationalization-localization/280"); + + await openBookmarkModal(); + await click("#tap_tile_tomorrow"); + + await openBookmarkModal(); + await click("#tap_tile_start_of_next_business_week"); + + await openBookmarkModal(); + await click("#tap_tile_next_week"); + + await openBookmarkModal(); + await click("#tap_tile_next_month"); + + await openBookmarkModal(); + await click("#tap_tile_custom"); + assert.ok(exists("#tap_tile_custom.active"), "it selects custom"); + assert.ok(exists(".tap-tile-date-input"), "it shows the custom date input"); + assert.ok(exists(".tap-tile-time-input"), "it shows the custom time input"); + await click("#save-bookmark"); + + assert.verifySteps([ + "tomorrow", + "start_of_next_business_week", + "next_week", + "next_month", + "custom" + ]); +}); + +test("Saving a bookmark with a reminder", async assert => { + mockSuccessfulBookmarkPost(assert); + await visit("/t/internationalization-localization/280"); + await openBookmarkModal(); + await fillIn("input#bookmark-name", "Check this out later"); + await click("#tap_tile_tomorrow"); + + assert.ok( + exists(".topic-post:first-child button.bookmark.bookmarked"), + "it shows the bookmarked icon on the post" + ); + assert.ok( + exists( + ".topic-post:first-child button.bookmark.bookmarked > .d-icon-discourse-bookmark-clock" + ), + "it shows the bookmark clock icon because of the reminder" + ); + assert.verifySteps(["tomorrow"]); +}); + +test("Saving a bookmark with no reminder or name", async assert => { + mockSuccessfulBookmarkPost(assert); + await visit("/t/internationalization-localization/280"); + await openBookmarkModal(); + await click("#save-bookmark"); + + assert.ok( + exists(".topic-post:first-child button.bookmark.bookmarked"), + "it shows the bookmarked icon on the post" + ); + assert.not( + exists( + ".topic-post:first-child button.bookmark.bookmarked > .d-icon-discourse-bookmark-clock" + ), + "it shows the regular bookmark active icon" + ); + assert.verifySteps(["none"]); +}); + +test("Deleting a bookmark with a reminder", async assert => { + pretender.delete("/bookmarks/999", () => [ + 200, + { + "Content-Type": "application/json" + }, + { + success: "OK", + topic_bookmarked: false + } + ]); + + mockSuccessfulBookmarkPost(assert); + + await visit("/t/internationalization-localization/280"); + await openBookmarkModal(); + await click("#tap_tile_tomorrow"); + + assert.verifySteps(["tomorrow"]); + + await openEditBookmarkModal(); + + assert.ok(exists("#bookmark-reminder-modal"), "it shows the bookmark modal"); + + await click("#delete-bookmark"); + + assert.ok(exists(".bootbox.modal"), "it asks for delete confirmation"); + assert.ok( + find(".bootbox.modal") + .text() + .includes(I18n.t("bookmarks.confirm_delete")), + "it shows delete confirmation message" + ); + + await click(".bootbox.modal .btn-primary"); + + assert.not( + exists(".topic-post:first-child button.bookmark.bookmarked"), + "it no longer shows the bookmarked icon on the post after bookmark is deleted" + ); +}); + +test("Cancelling saving a bookmark", async assert => { + await visit("/t/internationalization-localization/280"); + await openBookmarkModal(); + await click(".d-modal-cancel"); + assert.not( + exists(".topic-post:first-child button.bookmark.bookmarked"), + "it does not show the bookmarked icon on the post because it is not saved" + ); +}); + +test("Editing a bookmark", async assert => { + mockSuccessfulBookmarkPost(assert); + + await visit("/t/internationalization-localization/280"); + let now = moment.tz(loggedInUser().resolvedTimezone()); + let tomorrow = now.add(1, "day").format("YYYY-MM-DD"); + await openBookmarkModal(); + await fillIn("input#bookmark-name", "Test name"); + await click("#tap_tile_tomorrow"); + + await openEditBookmarkModal(); + assert.equal( + find("#bookmark-name").val(), + "Test name", + "it should prefill the bookmark name" + ); + assert.equal( + find("#bookmark-custom-date > input").val(), + tomorrow, + "it should prefill the bookmark date" + ); + assert.equal( + find("#bookmark-custom-time").val(), + "08:00", + "it should prefill the bookmark time" + ); + assert.verifySteps(["tomorrow"]); +}); diff --git a/test/javascripts/acceptance/category-banner-test.js b/test/javascripts/acceptance/category-banner-test.js new file mode 100644 index 0000000000..6bd3251507 --- /dev/null +++ b/test/javascripts/acceptance/category-banner-test.js @@ -0,0 +1,89 @@ +import { acceptance } from "helpers/qunit-helpers"; +import DiscoveryFixtures from "fixtures/discovery_fixtures"; + +acceptance("Category Banners", { + pretend(server, helper) { + server.get("/c/test-read-only-without-banner/5/l/latest.json", () => { + return helper.response( + DiscoveryFixtures["/latest_can_create_topic.json"] + ); + }); + server.get("/c/test-read-only-with-banner/6/l/latest.json", () => { + return helper.response( + DiscoveryFixtures["/latest_can_create_topic.json"] + ); + }); + }, + loggedIn: true, + site: { + categories: [ + { + id: 5, + name: "test read only without banner", + slug: "test-read-only-without-banner", + permission: null + }, + { + id: 6, + name: "test read only with banner", + slug: "test-read-only-with-banner", + permission: null, + read_only_banner: + "You need to video yourself doing the secret handshake to post here" + } + ] + } +}); + +QUnit.test("Does not display category banners when not set", async assert => { + await visit("/c/test-read-only-without-banner"); + + await click("#create-topic"); + assert.ok(!visible(".bootbox.modal"), "it does not pop up a modal"); + assert.ok( + !visible(".category-read-only-banner"), + "it does not show a banner" + ); +}); + +QUnit.test("Displays category banners when set", async assert => { + await visit("/c/test-read-only-with-banner"); + + await click("#create-topic"); + assert.ok(visible(".bootbox.modal"), "it pops up a modal"); + + await click(".modal-footer>.btn-primary"); + assert.ok(!visible(".bootbox.modal"), "it closes the modal"); + assert.ok(visible(".category-read-only-banner"), "it shows a banner"); +}); + +acceptance("Anonymous Category Banners", { + pretend(server, helper) { + server.get("/c/test-read-only-with-banner/6/l/latest.json", () => { + return helper.response( + DiscoveryFixtures["/latest_can_create_topic.json"] + ); + }); + }, + loggedIn: false, + site: { + categories: [ + { + id: 6, + name: "test read only with banner", + slug: "test-read-only-with-banner", + permission: null, + read_only_banner: + "You need to video yourself doing the secret handshake to post here" + } + ] + } +}); + +QUnit.test("Does not display category banners when set", async assert => { + await visit("/c/test-read-only-with-banner"); + assert.ok( + !visible(".category-read-only-banner"), + "it does not show a banner" + ); +}); diff --git a/test/javascripts/acceptance/composer-test.js b/test/javascripts/acceptance/composer-test.js index 48237ff552..9520bd9d5c 100644 --- a/test/javascripts/acceptance/composer-test.js +++ b/test/javascripts/acceptance/composer-test.js @@ -524,7 +524,7 @@ QUnit.test( ); assert.ok( - find(".composer-fields .whisper") + find(".composer-fields .unlist") .text() .indexOf(I18n.t("composer.unlist")) > 0, "it sets the topic to unlisted" diff --git a/test/javascripts/acceptance/dashboard-test.js b/test/javascripts/acceptance/dashboard-test.js index affe6c0a9f..7f7e207765 100644 --- a/test/javascripts/acceptance/dashboard-test.js +++ b/test/javascripts/acceptance/dashboard-test.js @@ -4,6 +4,7 @@ import { acceptance } from "helpers/qunit-helpers"; acceptance("Dashboard", { loggedIn: true, settings: { + dashboard_visible_tabs: "moderation|security|reports", dashboard_general_tab_activity_metrics: "page_view_total_reqs" }, site: { @@ -20,8 +21,9 @@ acceptance("Dashboard", { } }); -QUnit.test("Dashboard", async assert => { +QUnit.test("default", async assert => { await visit("/admin"); + assert.ok(exists(".dashboard"), "has dashboard-next class"); }); @@ -57,7 +59,7 @@ QUnit.test("general tab", async assert => { ); }); -QUnit.test("general tab - activity metrics", async assert => { +QUnit.test("activity metrics", async assert => { await visit("/admin"); assert.ok(exists(".admin-report.page-view-total-reqs .today-count")); @@ -100,9 +102,9 @@ QUnit.test("reports tab", async assert => { ); }); -QUnit.test("report filters", async assert => { +QUnit.test("reports filters", async assert => { await visit( - '/admin/reports/signups?end_date=2018-07-16&filters=%7B"group"%3A88%7D&start_date=2018-06-16' + '/admin/reports/signups_with_groups?end_date=2018-07-16&filters=%7B"group"%3A88%7D&start_date=2018-06-16' ); const groupFilter = selectKit(".group-filter .combo-box"); @@ -113,3 +115,41 @@ QUnit.test("report filters", async assert => { "its set the value of the filter from the query params" ); }); + +acceptance("Dashboard: dashboard_visible_tabs", { + loggedIn: true, + settings: { + dashboard_visible_tabs: "general|security|reports" + } +}); + +QUnit.test("visible tabs", async assert => { + await visit("/admin"); + + assert.ok(exists(".dashboard .navigation-item.general"), "general tab"); + assert.notOk( + exists(".dashboard .navigation-item.moderation"), + "moderation tab" + ); + assert.ok(exists(".dashboard .navigation-item.security"), "security tab"); + assert.ok(exists(".dashboard .navigation-item.reports"), "reports tab"); +}); + +acceptance("Dashboard: dashboard_hidden_reports", { + loggedIn: true, + settings: { + dashboard_visible_tabs: "reports", + dashboard_hidden_reports: "posts|dau_by_mau" + } +}); + +QUnit.test("hidden reports", async assert => { + await visit("/admin"); + + assert.ok(exists(".admin-report.signups.is-visible"), "signups report"); + assert.notOk(exists(".admin-report.is-visible.posts"), "posts report"); + assert.notOk( + exists(".admin-report.is-visible.dau-by-mau"), + "dau-by-mau report" + ); +}); diff --git a/test/javascripts/acceptance/group-manage-logs-test.js b/test/javascripts/acceptance/group-manage-logs-test.js index 1a3d6ada4a..f0587b3b2e 100644 --- a/test/javascripts/acceptance/group-manage-logs-test.js +++ b/test/javascripts/acceptance/group-manage-logs-test.js @@ -13,7 +13,6 @@ acceptance("Group logs", { alias_level: 0, visible: true, automatic_membership_email_domains: "", - automatic_membership_retroactive: false, primary_group: true, title: "Team Snorlax", grant_trust_level: null, diff --git a/test/javascripts/acceptance/group-manage-membership-test.js b/test/javascripts/acceptance/group-manage-membership-test.js index e43678a7c8..c7837a3ec5 100644 --- a/test/javascripts/acceptance/group-manage-membership-test.js +++ b/test/javascripts/acceptance/group-manage-membership-test.js @@ -13,11 +13,6 @@ QUnit.test("As an admin", async assert => { "it should display automatic membership label" ); - assert.ok( - find(".groups-form-automatic-membership-retroactive").length === 1, - "it should display automatic membership retroactive checkbox" - ); - assert.ok( find(".groups-form-primary-group").length === 1, "it should display set as primary group checkbox" diff --git a/test/javascripts/acceptance/group-requests-test.js b/test/javascripts/acceptance/group-requests-test.js index 68ccf7f867..9c4e9a8a72 100644 --- a/test/javascripts/acceptance/group-requests-test.js +++ b/test/javascripts/acceptance/group-requests-test.js @@ -17,7 +17,6 @@ acceptance("Group Requests", { messageable_level: 0, visibility_level: 0, automatic_membership_email_domains: "", - automatic_membership_retroactive: false, primary_group: false, title: "Macdonald", grant_trust_level: null, diff --git a/test/javascripts/acceptance/raw-plugin-outlet-test.js b/test/javascripts/acceptance/raw-plugin-outlet-test.js index 62ea96028f..8f104ce37b 100644 --- a/test/javascripts/acceptance/raw-plugin-outlet-test.js +++ b/test/javascripts/acceptance/raw-plugin-outlet-test.js @@ -1,10 +1,11 @@ import { acceptance } from "helpers/qunit-helpers"; +import compile from "handlebars-compiler"; const CONNECTOR = "javascripts/raw-test/connectors/topic-list-before-status/lala"; acceptance("Raw Plugin Outlet", { beforeEach() { - Discourse.RAW_TEMPLATES[CONNECTOR] = Handlebars.compile( + Discourse.RAW_TEMPLATES[CONNECTOR] = compile( `{{context.topic.id}}` ); }, diff --git a/test/javascripts/acceptance/search-full-test.js b/test/javascripts/acceptance/search-full-test.js index e961e8015a..d869af65a3 100644 --- a/test/javascripts/acceptance/search-full-test.js +++ b/test/javascripts/acceptance/search-full-test.js @@ -30,7 +30,6 @@ acceptance("Search - Full Page", { alias_level: 0, visible: true, automatic_membership_email_domains: null, - automatic_membership_retroactive: false, primary_group: false, title: null, grant_trust_level: null, diff --git a/test/javascripts/acceptance/topic-test.js b/test/javascripts/acceptance/topic-test.js index b7edc5cc95..ab271369c3 100644 --- a/test/javascripts/acceptance/topic-test.js +++ b/test/javascripts/acceptance/topic-test.js @@ -248,10 +248,9 @@ QUnit.test("remove featured link", async assert => { "link to remove featured link" ); - // this test only works in a browser: - // await click('.title-wrapper .remove-featured-link'); - // await click('.title-wrapper .submit-edit'); - // assert.ok(!exists('.title-wrapper .topic-featured-link'), 'link is gone'); + await click(".title-wrapper .remove-featured-link"); + await click(".title-wrapper .submit-edit"); + assert.ok(!exists(".title-wrapper .topic-featured-link"), "link is gone"); }); QUnit.test("Converting to a public topic", async assert => { @@ -396,17 +395,6 @@ QUnit.test( } ); -acceptance("Topic + Post Bookmarks with Reminders", { - loggedIn: true -}); - -QUnit.test("Bookmarks Modal", async assert => { - await visit("/t/internationalization-localization/280"); - await click(".topic-post:first-child button.show-more-actions"); - await click(".topic-post:first-child button.bookmark"); - assert.ok(exists("#bookmark-reminder-modal"), "it shows the bookmark modal"); -}); - acceptance("Topic with title decorated", { loggedIn: true, beforeEach() { diff --git a/test/javascripts/acceptance/user-bookmarks-test.js b/test/javascripts/acceptance/user-bookmarks-test.js new file mode 100644 index 0000000000..3a276810c8 --- /dev/null +++ b/test/javascripts/acceptance/user-bookmarks-test.js @@ -0,0 +1,50 @@ +import { acceptance } from "helpers/qunit-helpers"; +import selectKit from "helpers/select-kit-helper"; +import pretender from "helpers/create-pretender"; + +acceptance("User's bookmarks", { + loggedIn: true, + + beforeEach() { + pretender.delete("/bookmarks/576", () => [ + 200, + { "Content-Type": "application/json" }, + {} + ]); + } +}); + +test("listing user bookmarks", async assert => { + await visit("/u/eviltrout/activity/bookmarks"); + + assert.ok(find(".bookmark-list-item").length); +}); + +test("removing a bookmark", async assert => { + await visit("/u/eviltrout/activity/bookmarks"); + + const dropdown = selectKit(".bookmark-actions-dropdown"); + await dropdown.expand(); + await dropdown.selectRowByValue("remove"); + + assert.ok(exists(".bootbox.modal")); + + await click(".bootbox.modal .btn-primary"); +}); + +test("listing users bookmarks - no bookmarks", async assert => { + pretender.get("/u/eviltrout/bookmarks.json", () => [ + 200, + { + "Content-Type": "application/json" + }, + { + bookmarks: [], + no_results_help: "no bookmarks" + } + ]); + + await visit("/u/eviltrout/activity/bookmarks"); + + assert.equal(find(".alert.alert-info").text(), "no bookmarks"); +}); diff --git a/test/javascripts/acceptance/user-card-test.js b/test/javascripts/acceptance/user-card-test.js index 8ced970f99..f15bbd3a7a 100644 --- a/test/javascripts/acceptance/user-card-test.js +++ b/test/javascripts/acceptance/user-card-test.js @@ -1,6 +1,69 @@ import { acceptance } from "helpers/qunit-helpers"; import DiscourseURL from "discourse/lib/url"; +import pretender from "helpers/create-pretender"; +import userFixtures from "fixtures/user_fixtures"; +import User from "discourse/models/user"; + +acceptance("User Card - Show Local Time", { + loggedIn: true, + settings: { display_local_time_in_user_card: true } +}); + +QUnit.test("user card local time", async assert => { + User.current().changeTimezone("Australia/Brisbane"); + let cardResponse = _.clone(userFixtures["/u/eviltrout/card.json"]); + cardResponse.user.timezone = "Australia/Perth"; + + pretender.get("/u/eviltrout/card.json", () => [ + 200, + { "Content-Type": "application/json" }, + cardResponse + ]); + + await visit("/t/internationalization-localization/280"); + assert.ok(invisible(".user-card"), "user card is invisible by default"); + await click("a[data-user-card=eviltrout]:first"); + + let expectedTime = moment + .tz("Australia/Brisbane") + .add(-2, "hours") + .format("h:mm a"); + + assert.ok(visible(".user-card"), "card should appear"); + assert.equal( + find(".user-card .local-time") + .text() + .trim(), + expectedTime, + "user card contains the user's local time" + ); + + cardResponse = _.clone(userFixtures["/u/charlie/card.json"]); + cardResponse.user.timezone = "America/New_York"; + + pretender.get("/u/charlie/card.json", () => [ + 200, + { "Content-Type": "application/json" }, + cardResponse + ]); + + await click("a[data-user-card=charlie]:first"); + + expectedTime = moment + .tz("Australia/Brisbane") + .add(-14, "hours") + .format("h:mm a"); + + assert.equal( + find(".user-card .local-time") + .text() + .trim(), + expectedTime, + "opening another user card updates the local time in the card (no caching)" + ); +}); + acceptance("User Card", { loggedIn: true }); QUnit.test("user card", async assert => { @@ -34,6 +97,11 @@ QUnit.test("user card", async assert => { "user card contains the data" ); + assert.ok( + !visible(".user-card .local-time"), + "local time with zone does not show by default" + ); + await click(".card-content .compose-pm button"); assert.ok( invisible(".user-card"), diff --git a/test/javascripts/components/date-input-test.js b/test/javascripts/components/date-input-test.js index 64686aba06..29f01b4f50 100644 --- a/test/javascripts/components/date-input-test.js +++ b/test/javascripts/components/date-input-test.js @@ -18,7 +18,7 @@ async function pika(year, month, day) { function noop() {} -const DEFAULT_DATE = new Date(2019, 0, 29); +const DEFAULT_DATE = moment("2019-01-29"); componentTest("default", { template: `{{date-input date=date}}`, @@ -44,7 +44,7 @@ componentTest("prevents mutations", { await click(dateInput()); await pika(2019, 0, 2); - assert.ok(this.date.getTime() === DEFAULT_DATE.getTime()); + assert.ok(this.date.isSame(DEFAULT_DATE)); } }); @@ -60,6 +60,6 @@ componentTest("allows mutations through actions", { await click(dateInput()); await pika(2019, 0, 2); - assert.ok(this.date.getTime() === new Date(2019, 0, 2).getTime()); + assert.ok(this.date.isSame(moment("2019-01-02"))); } }); diff --git a/test/javascripts/components/date-time-input-range-test.js b/test/javascripts/components/date-time-input-range-test.js index 69ff0a9d45..9ffa7e6ef6 100644 --- a/test/javascripts/components/date-time-input-range-test.js +++ b/test/javascripts/components/date-time-input-range-test.js @@ -3,40 +3,22 @@ import componentTest from "helpers/component-test"; moduleForComponent("date-time-input-range", { integration: true }); function fromDateInput() { - return find(".from .date-picker"); + return find(".from.d-date-time-input .date-picker")[0]; } -function fromHoursInput() { - return find(".from .field.hours"); -} - -function fromMinutesInput() { - return find(".from .field.minutes"); +function fromTimeInput() { + return find(".from.d-date-time-input .d-time-input .combo-box-header")[0]; } function toDateInput() { - return find(".to .date-picker"); + return find(".to.d-date-time-input .date-picker")[0]; } -function toHoursInput() { - return find(".to .field.hours"); +function toTimeInput() { + return find(".to.d-date-time-input .d-time-input .combo-box-header")[0]; } -function toMinutesInput() { - return find(".to .field.minutes"); -} - -function setDates(dates) { - this.setProperties(dates); -} - -async function pika(year, month, day) { - await click( - `.pika-button.pika-day[data-pika-year="${year}"][data-pika-month="${month}"][data-pika-day="${day}"]` - ); -} - -const DEFAULT_DATE_TIME = new Date(2019, 0, 29, 14, 45); +const DEFAULT_DATE_TIME = moment("2019-01-29 14:45"); componentTest("default", { template: `{{date-time-input-range from=from to=to}}`, @@ -46,60 +28,9 @@ componentTest("default", { }, test(assert) { - assert.equal(fromDateInput().val(), "January 29, 2019"); - assert.equal(fromHoursInput().val(), "14"); - assert.equal(fromMinutesInput().val(), "45"); - - assert.equal(toDateInput().val(), ""); - assert.equal(toHoursInput().val(), ""); - assert.equal(toMinutesInput().val(), ""); - } -}); - -componentTest("can switch panels", { - template: `{{date-time-input-range}}`, - - async test(assert) { - assert.ok(exists(".panel.from.visible")); - assert.notOk(exists(".panel.to.visible")); - - await click(".panels button.to-panel"); - - assert.ok(exists(".panel.to.visible")); - assert.notOk(exists(".panel.from.visible")); - } -}); - -componentTest("prevents toDate to be before fromDate", { - template: `{{date-time-input-range from=from to=to onChange=onChange}}`, - - beforeEach() { - this.setProperties({ - from: DEFAULT_DATE_TIME, - to: DEFAULT_DATE_TIME, - onChange: setDates - }); - }, - - async test(assert) { - assert.notOk(exists(".error"), "it begins with no error"); - - await click(".panels button.to-panel"); - await click(toDateInput()); - await pika(2019, 0, 1); - - assert.ok(exists(".error"), "it shows an error"); - assert.deepEqual(this.to, DEFAULT_DATE_TIME, "it didnt trigger a mutation"); - - await click(".panels button.to-panel"); - await click(toDateInput()); - await pika(2019, 0, 30); - - assert.notOk(exists(".error"), "it removes the error"); - assert.deepEqual( - this.to, - new Date(2019, 0, 30, 14, 45), - "it has changed the date" - ); + assert.equal(fromDateInput().value, "January 29, 2019"); + assert.equal(fromTimeInput().dataset.name, "14:45"); + assert.equal(toDateInput().value, ""); + assert.equal(toTimeInput().dataset.name, "--:--"); } }); diff --git a/test/javascripts/components/date-time-input-test.js b/test/javascripts/components/date-time-input-test.js index 2dd4ac8fcf..e56e3e0913 100644 --- a/test/javascripts/components/date-time-input-test.js +++ b/test/javascripts/components/date-time-input-test.js @@ -3,15 +3,11 @@ import componentTest from "helpers/component-test"; moduleForComponent("date-time-input", { integration: true }); function dateInput() { - return find(".date-picker"); + return find(".date-picker")[0]; } -function hoursInput() { - return find(".field.hours"); -} - -function minutesInput() { - return find(".field.minutes"); +function timeInput() { + return find(".d-time-input .combo-box-header")[0]; } function setDate(date) { @@ -24,7 +20,7 @@ async function pika(year, month, day) { ); } -const DEFAULT_DATE_TIME = new Date(2019, 0, 29, 14, 45); +const DEFAULT_DATE_TIME = moment("2019-01-29 14:45"); componentTest("default", { template: `{{date-time-input date=date}}`, @@ -34,9 +30,8 @@ componentTest("default", { }, test(assert) { - assert.equal(dateInput().val(), "January 29, 2019"); - assert.equal(hoursInput().val(), "14"); - assert.equal(minutesInput().val(), "45"); + assert.equal(dateInput().value, "January 29, 2019"); + assert.equal(timeInput().dataset.name, "14:45"); } }); @@ -51,7 +46,7 @@ componentTest("prevents mutations", { await click(dateInput()); await pika(2019, 0, 2); - assert.ok(this.date.getTime() === DEFAULT_DATE_TIME.getTime()); + assert.ok(this.date.isSame(DEFAULT_DATE_TIME)); } }); @@ -67,7 +62,7 @@ componentTest("allows mutations through actions", { await click(dateInput()); await pika(2019, 0, 2); - assert.ok(this.date.getTime() === new Date(2019, 0, 2, 14, 45).getTime()); + assert.ok(this.date.isSame(moment("2019-01-02 14:45"))); } }); @@ -79,6 +74,6 @@ componentTest("can hide time", { }, async test(assert) { - assert.notOk(exists(hoursInput())); + assert.notOk(exists(timeInput())); } }); diff --git a/test/javascripts/components/time-input-test.js b/test/javascripts/components/time-input-test.js index edbe7574c8..a6ef6606c9 100644 --- a/test/javascripts/components/time-input-test.js +++ b/test/javascripts/components/time-input-test.js @@ -1,21 +1,18 @@ +import selectKit from "helpers/select-kit-helper"; import componentTest from "helpers/component-test"; -moduleForComponent("time-input", { integration: true }); +moduleForComponent("time-input", { + integration: true, -function hoursInput() { - return find(".field.hours"); -} - -function minutesInput() { - return find(".field.minutes"); -} + beforeEach() { + this.set("subject", selectKit()); + } +}); function setTime(time) { this.setProperties(time); } -function noop() {} - componentTest("default", { template: `{{time-input hours=hours minutes=minutes}}`, @@ -24,8 +21,7 @@ componentTest("default", { }, test(assert) { - assert.equal(hoursInput().val(), "14"); - assert.equal(minutesInput().val(), "58"); + assert.equal(this.subject.header().name(), "14:58"); } }); @@ -37,11 +33,9 @@ componentTest("prevents mutations", { }, async test(assert) { - await fillIn(hoursInput(), "12"); - assert.ok(this.hours === "14"); - - await fillIn(minutesInput(), "36"); - assert.ok(this.minutes === "58"); + await this.subject.expand(); + await this.subject.selectRowByIndex(3); + assert.equal(this.subject.header().name(), "14:58"); } }); @@ -54,44 +48,8 @@ componentTest("allows mutations through actions", { }, async test(assert) { - await fillIn(hoursInput(), "12"); - assert.ok(this.hours === "12"); - - await fillIn(minutesInput(), "36"); - assert.ok(this.minutes === "36"); - } -}); - -componentTest("hours and minutes have boundaries", { - template: `{{time-input hours=14 minutes=58 onChange=onChange}}`, - - beforeEach() { - this.set("onChange", noop); - }, - - async test(assert) { - await fillIn(hoursInput(), "2"); - assert.equal(hoursInput().val(), "02"); - - await fillIn(hoursInput(), "@"); - assert.equal(hoursInput().val(), "00"); - - await fillIn(hoursInput(), "24"); - assert.equal(hoursInput().val(), "23"); - - await fillIn(hoursInput(), "-1"); - assert.equal(hoursInput().val(), "00"); - - await fillIn(minutesInput(), "@"); - assert.equal(minutesInput().val(), "00"); - - await fillIn(minutesInput(), "2"); - assert.equal(minutesInput().val(), "02"); - - await fillIn(minutesInput(), "60"); - assert.equal(minutesInput().val(), "59"); - - await fillIn(minutesInput(), "-1"); - assert.equal(minutesInput().val(), "00"); + await this.subject.expand(); + await this.subject.selectRowByIndex(3); + assert.equal(this.subject.header().name(), "00:45"); } }); diff --git a/test/javascripts/fixtures/discovery_fixtures.js b/test/javascripts/fixtures/discovery_fixtures.js index 01228b9437..9e09ab984a 100644 --- a/test/javascripts/fixtures/discovery_fixtures.js +++ b/test/javascripts/fixtures/discovery_fixtures.js @@ -6120,5 +6120,107 @@ export default { } ] } + }, + "/latest_can_create_topic.json": { + users: [ + { + id: 1, + username: "tt1", + name: null, + avatar_template: "/letter_avatar_proxy/v4/letter/t/6de8d8/{size}.png" + } + ], + primary_groups: [], + topic_list: { + can_create_topic: true, + draft: null, + draft_key: "new_topic", + draft_sequence: 0, + per_page: 30, + topics: [ + { + id: 30, + title: "I am also creating a new topic here new topic", + fancy_title: "I am also creating a new topic here new topic", + slug: "i-am-also-creating-a-new-topic-here-new-topic", + posts_count: 6, + reply_count: 0, + highest_post_number: 6, + image_url: null, + created_at: "2020-04-27T23:47:44.218Z", + last_posted_at: "2020-04-28T22:45:47.529Z", + bumped: true, + bumped_at: "2020-04-28T22:02:20.215Z", + archetype: "regular", + unseen: false, + last_read_post_number: 5, + unread: 0, + new_posts: 0, + pinned: false, + unpinned: null, + visible: true, + closed: false, + archived: false, + notification_level: 1, + bookmarked: false, + liked: false, + tags: ["test", "test-tag"], + views: 6, + like_count: 0, + has_summary: false, + last_poster_username: "tt1", + category_id: 5, + pinned_globally: false, + featured_link: null, + posters: [ + { + extras: "latest single", + description: "Original Poster, Most Recent Poster", + user_id: 1, + primary_group_id: null + } + ] + }, + { + id: 29, + title: "About the test category category", + fancy_title: "About the test category category", + slug: "about-the-test-category-category", + posts_count: 5, + reply_count: 0, + highest_post_number: 5, + image_url: null, + created_at: "2020-04-27T22:15:49.424Z", + last_posted_at: "2020-04-27T23:51:06.249Z", + bumped: true, + bumped_at: "2020-04-27T22:15:49.424Z", + archetype: "regular", + unseen: false, + pinned: false, + unpinned: null, + visible: true, + closed: false, + archived: false, + bookmarked: null, + liked: null, + tags: [], + views: 1, + like_count: 0, + has_summary: false, + last_poster_username: "tt1", + category_id: 5, + pinned_globally: false, + featured_link: null, + posters: [ + { + extras: "latest single", + description: "Original Poster, Most Recent Poster", + user_id: 1, + primary_group_id: null + } + ] + } + ] + } } }; diff --git a/test/javascripts/fixtures/group-fixtures.js b/test/javascripts/fixtures/group-fixtures.js index 89842f3245..b509e79cd4 100644 --- a/test/javascripts/fixtures/group-fixtures.js +++ b/test/javascripts/fixtures/group-fixtures.js @@ -9,7 +9,6 @@ export default { messageable_level: 99, visibility_level: 0, automatic_membership_email_domains: null, - automatic_membership_retroactive: false, primary_group: false, title: null, grant_trust_level: null, diff --git a/test/javascripts/fixtures/groups-fixtures.js b/test/javascripts/fixtures/groups-fixtures.js index 46d6511dd2..b6c020ee93 100644 --- a/test/javascripts/fixtures/groups-fixtures.js +++ b/test/javascripts/fixtures/groups-fixtures.js @@ -9,7 +9,6 @@ export default { alias_level: 0, visible: true, automatic_membership_email_domains: "", - automatic_membership_retroactive: false, primary_group: false, title: null, grant_trust_level: null, @@ -31,7 +30,6 @@ export default { alias_level: 99, visible: true, automatic_membership_email_domains: "", - automatic_membership_retroactive: false, primary_group: false, title: null, grant_trust_level: null, @@ -61,7 +59,6 @@ export default { alias_level: 0, visible: true, automatic_membership_email_domains: "", - automatic_membership_retroactive: false, primary_group: false, title: null, grant_trust_level: null, diff --git a/test/javascripts/fixtures/reports_bulk.js b/test/javascripts/fixtures/reports_bulk.js index a41cf34583..100648b3f4 100644 --- a/test/javascripts/fixtures/reports_bulk.js +++ b/test/javascripts/fixtures/reports_bulk.js @@ -59,7 +59,7 @@ let signups = { prev_end_date: "2018-06-17T00:00:00Z", prev30Days: null, dates_filtering: true, - report_key: 'reports:signups:start:end:[:prev_period]:50:{"group":"88"}:4', + report_key: "reports:signups:start:end:[:prev_period]:4", available_filters: [ { id: "group", type: "group", allow_any: false, choices: [], default: "88" } ], @@ -77,18 +77,29 @@ let signups = { let signups_fixture = JSON.parse(JSON.stringify(signups)); signups_fixture.type = "signups_exception"; signups_fixture.error = "exception"; +signups_fixture.report_key = + "reports:signups_exception:start:end:[:prev_period]:4"; const signups_exception = signups_fixture; signups_fixture = JSON.parse(JSON.stringify(signups)); signups_fixture.type = "signups_timeout"; signups_fixture.error = "timeout"; +signups_fixture.report_key = + "reports:signups_timeout:start:end:[:prev_period]:4"; const signups_timeout = signups_fixture; signups_fixture = JSON.parse(JSON.stringify(signups)); signups_fixture.type = "not_found"; signups_fixture.error = "not_found"; +signups_fixture.report_key = "reports:not_found:start:end:[:prev_period]:4"; const signups_not_found = signups_fixture; +signups_fixture = JSON.parse(JSON.stringify(signups)); +signups_fixture.type = "signups_with_groups"; +signups_fixture.report_key = + 'reports:signups_with_groups:start:end:[:prev_period]:50:{"group":"88"}:4'; +const signups_with_group = signups_fixture; + const startDate = moment() .locale("en") .utc() @@ -180,6 +191,7 @@ export default { "/admin/reports/bulk": { reports: [ signups, + signups_with_group, signups_not_found, signups_exception, signups_timeout, diff --git a/test/javascripts/fixtures/topic.js b/test/javascripts/fixtures/topic.js index dedf9814b8..b520532feb 100644 --- a/test/javascripts/fixtures/topic.js +++ b/test/javascripts/fixtures/topic.js @@ -4060,7 +4060,6 @@ export default { alias_level: 99, visible: true, automatic_membership_email_domains: "", - automatic_membership_retroactive: false, primary_group: false, title: null, grant_trust_level: null, diff --git a/test/javascripts/fixtures/user_fixtures.js b/test/javascripts/fixtures/user_fixtures.js index b22180109d..abf4a39037 100644 --- a/test/javascripts/fixtures/user_fixtures.js +++ b/test/javascripts/fixtures/user_fixtures.js @@ -187,6 +187,7 @@ export default { card_image_badge: "/images/avatar.png", card_image_badge_id: 120, muted_usernames: [], + can_change_location: true, ignored_usernames: [], invited_by: { id: 1, @@ -204,7 +205,6 @@ export default { alias_level: 0, visible: true, automatic_membership_email_domains: null, - automatic_membership_retroactive: false, primary_group: false, title: null }, @@ -216,7 +216,6 @@ export default { alias_level: 0, visible: true, automatic_membership_email_domains: null, - automatic_membership_retroactive: false, primary_group: false, title: null } @@ -2250,7 +2249,11 @@ export default { { extras: null, description: "Most Posts", user_id: 5460 }, { extras: null, description: "Frequent Poster", user_id: 402 }, { extras: null, description: "Frequent Poster", user_id: 5707 }, - { extras: "latest", description: "Most Recent Poster", user_id: 32 } + { + extras: "latest", + description: "Most Recent Poster", + user_id: 32 + } ] }, { @@ -2539,7 +2542,6 @@ export default { messageable_level: 0, visibility_level: 0, automatic_membership_email_domains: null, - automatic_membership_retroactive: false, primary_group: false, title: null, grant_trust_level: null, @@ -2567,7 +2569,6 @@ export default { messageable_level: 0, visibility_level: 0, automatic_membership_email_domains: null, - automatic_membership_retroactive: false, primary_group: false, title: null, grant_trust_level: null, @@ -2595,7 +2596,6 @@ export default { messageable_level: 0, visibility_level: 0, automatic_membership_email_domains: null, - automatic_membership_retroactive: false, primary_group: false, title: null, grant_trust_level: null, @@ -2623,7 +2623,6 @@ export default { messageable_level: 0, visibility_level: 0, automatic_membership_email_domains: null, - automatic_membership_retroactive: false, primary_group: false, title: null, grant_trust_level: null, diff --git a/test/javascripts/helpers/qunit-helpers.js b/test/javascripts/helpers/qunit-helpers.js index e0621c294d..0bc9eaece8 100644 --- a/test/javascripts/helpers/qunit-helpers.js +++ b/test/javascripts/helpers/qunit-helpers.js @@ -36,6 +36,11 @@ export function logIn() { User.resetCurrent(currentUser()); } +// Note: Only use if `loggedIn: true` has been used in an acceptance test +export function loggedInUser() { + return User.current(); +} + const Plugin = $.fn.modal; const Modal = Plugin.Constructor; diff --git a/test/javascripts/helpers/site-settings.js b/test/javascripts/helpers/site-settings.js index bf55374eb8..4d1181dbaf 100644 --- a/test/javascripts/helpers/site-settings.js +++ b/test/javascripts/helpers/site-settings.js @@ -13,10 +13,8 @@ Discourse.SiteSettingsOriginal = { ga_universal_tracking_code: "", ga_universal_domain_name: "auto", top_menu: "latest|new|unread|categories|top", - post_menu: - "like|share|flag|edit|bookmark|bookmarkWithReminder|delete|admin|reply", - post_menu_hidden_items: - "flag|bookmark|bookmarkWithReminder|edit|delete|admin", + post_menu: "like|share|flag|edit|bookmark|delete|admin|reply", + post_menu_hidden_items: "flag|bookmark|edit|delete|admin", share_links: "twitter|facebook|email", category_colors: "BF1E2E|F1592A|F7941D|9EB83B|3AB54A|12A89D|25AAE2|0E76BD|652D90|92278F|ED207B|8C6238|231F20|27AA5B|B3B5B4|E45735", diff --git a/test/javascripts/models/topic-tracking-state-test.js b/test/javascripts/models/topic-tracking-state-test.js index 0d958b8503..709928c932 100644 --- a/test/javascripts/models/topic-tracking-state-test.js +++ b/test/javascripts/models/topic-tracking-state-test.js @@ -2,8 +2,17 @@ import TopicTrackingState from "discourse/models/topic-tracking-state"; import createStore from "helpers/create-store"; import Category from "discourse/models/category"; import { NotificationLevels } from "discourse/lib/notification-levels"; +import User from "discourse/models/user"; -QUnit.module("model:topic-tracking-state"); +QUnit.module("model:topic-tracking-state", { + beforeEach() { + this.clock = sinon.useFakeTimers(new Date(2012, 11, 31, 12, 0).getTime()); + }, + + afterEach() { + this.clock.restore(); + } +}); QUnit.test("sync", function(assert) { const state = TopicTrackingState.create(); @@ -168,3 +177,22 @@ QUnit.test("countNew", assert => { assert.equal(state.countNew(2), 2); assert.equal(state.countNew(3), 1); }); + +QUnit.test("mute topic", function(assert) { + let currentUser = User.create({ + username: "chuck", + muted_category_ids: [] + }); + + const state = TopicTrackingState.create({ currentUser }); + + state.trackMutedTopic(1); + assert.equal(currentUser.muted_topics[0].topicId, 1); + + state.pruneOldMutedTopics(); + assert.equal(state.isMutedTopic(1), true); + + this.clock.tick(60000); + state.pruneOldMutedTopics(); + assert.equal(state.isMutedTopic(1), false); +}); diff --git a/test/javascripts/widgets/post-test.js b/test/javascripts/widgets/post-test.js index b7131fc2a5..bc12234c31 100644 --- a/test/javascripts/widgets/post-test.js +++ b/test/javascripts/widgets/post-test.js @@ -532,15 +532,12 @@ widgetTest("can't bookmark", { widgetTest("bookmark", { template: - '{{mount-widget widget="post" args=args toggleBookmarkWithReminder=(action "toggleBookmarkWithReminder")}}', + '{{mount-widget widget="post" args=args toggleBookmark=(action "toggleBookmark")}}', beforeEach() { const args = { canBookmark: true }; this.set("args", args); - this.on( - "toggleBookmarkWithReminder", - () => (args.bookmarked_with_reminder = true) - ); + this.on("toggleBookmark", () => (args.bookmarked = true)); }, async test(assert) { assert.equal(find(".post-menu-area .bookmark").length, 1); diff --git a/test/javascripts/widgets/topic-status-test.js b/test/javascripts/widgets/topic-status-test.js index 5cc6f9d437..c5888d4aa4 100644 --- a/test/javascripts/widgets/topic-status-test.js +++ b/test/javascripts/widgets/topic-status-test.js @@ -12,7 +12,7 @@ widgetTest("basics", { }); }, test(assert) { - assert.ok(find(".topic-status .d-icon-discourse-comment-slash").length); + assert.ok(find(".topic-status .d-icon-lock").length); } }); diff --git a/test/javascripts/widgets/widget-dropdown-test.js b/test/javascripts/widgets/widget-dropdown-test.js index 46625d7d7b..2bc7f94b26 100644 --- a/test/javascripts/widgets/widget-dropdown-test.js +++ b/test/javascripts/widgets/widget-dropdown-test.js @@ -302,3 +302,18 @@ widgetTest("bodyClass option", { assert.ok(body().classList.contains("and-yet-small")); } }); + +widgetTest("caret option", { + template: TEMPLATE, + + beforeEach() { + this.setProperties(DEFAULT_CONTENT); + this.set("options", { caret: true }); + }, + + test(assert) { + assert.ok( + exists("#my-dropdown .widget-dropdown-header .d-icon-caret-down") + ); + } +}); diff --git a/vendor/assets/javascripts/browser-update.js.erb b/vendor/assets/javascripts/browser-update.js.erb index b32410b8e6..be54f3bc0f 100644 --- a/vendor/assets/javascripts/browser-update.js.erb +++ b/vendor/assets/javascripts/browser-update.js.erb @@ -18,6 +18,7 @@ var $buo = function() { return; } + document.getElementsByTagName('body')[0].classList.add("crawler"); var mainElement = document.getElementById("main"); var noscriptElements = document.getElementsByTagName("noscript"); // noscriptElements[0].innerHTML contains encoded HTML @@ -34,7 +35,7 @@ var $buo = function() { // create the notification div stylesheet var sheet = document.createElement("style"); - var style = ".buorg {position:absolute; z-index:111111; width:100%; top:0px; left:0px; background:#FDF2AB; text-align:left; font-family: sans-serif; color:#000; font-size: 14px;} .buorg div {padding: 8px;} .buorg a, .buorg a:visited {color:#E25600; text-decoration: underline;}"; + var style = ".buorg {position:absolute; z-index:111111; width:100%; top:0px; left:0px; background:#FDF2AB; text-align:left; font-family: sans-serif; color:#000; font-size: 14px;} .buorg div {padding: 8px;} .buorg a, .buorg a:visited {color:#E25600; text-decoration: underline;} @media print { .buorg { display: none !important; } }"; // insert the div and stylesheet into the DOM document.body.appendChild(div); // put it last in the DOM so Googlebot doesn't include it in search excerpts diff --git a/vendor/assets/javascripts/jquery.fileupload.js b/vendor/assets/javascripts/jquery.fileupload.js index e99f3091e6..f75cf2b10a 100644 --- a/vendor/assets/javascripts/jquery.fileupload.js +++ b/vendor/assets/javascripts/jquery.fileupload.js @@ -1,1466 +1,1597 @@ /* - * jQuery File Upload Plugin 5.42.2 + * jQuery File Upload Plugin * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2010, Sebastian Tschan * https://blueimp.net * * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT + * https://opensource.org/licenses/MIT */ -/* jshint nomen:false */ -/* global define, require, window, document, location, Blob, FormData */ +/* global define, require */ +/* eslint-disable new-cap */ (function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define([ - 'jquery', - 'jquery.ui.widget' - ], factory); - } else if (typeof exports === 'object') { - // Node/CommonJS: - factory( - require('jquery'), - require('./vendor/jquery.ui.widget') - ); - } else { - // Browser globals: - factory(window.jQuery); - } -}(function ($) { - 'use strict'; + 'use strict'; + if (typeof define === 'function' && define.amd) { + // Register as an anonymous AMD module: + define(['jquery', 'jquery-ui/ui/widget'], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS: + factory(require('jquery'), require('./vendor/jquery.ui.widget')); + } else { + // Browser globals: + factory(window.jQuery); + } +})(function ($) { + 'use strict'; - // Detect file input support, based on - // http://viljamis.com/blog/2012/file-upload-support-on-mobile/ - $.support.fileInput = !(new RegExp( - // Handle devices which give false positives for the feature detection: - '(Android (1\\.[0156]|2\\.[01]))' + - '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' + - '|(w(eb)?OSBrowser)|(webOS)' + - '|(Kindle/(1\\.0|2\\.[05]|3\\.0))' + // Detect file input support, based on + // https://viljamis.com/2012/file-upload-support-on-mobile/ + $.support.fileInput = !( + new RegExp( + // Handle devices which give false positives for the feature detection: + '(Android (1\\.[0156]|2\\.[01]))' + + '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' + + '|(w(eb)?OSBrowser)|(webOS)' + + '|(Kindle/(1\\.0|2\\.[05]|3\\.0))' ).test(window.navigator.userAgent) || - // Feature detection for all other devices: - $('').prop('disabled')); + // Feature detection for all other devices: + $('').prop('disabled') + ); - // The FileReader API is not actually used, but works as feature detection, - // as some Safari versions (5?) support XHR file uploads via the FormData API, - // but not non-multipart XHR file uploads. - // window.XMLHttpRequestUpload is not available on IE10, so we check for - // window.ProgressEvent instead to detect XHR2 file upload capability: - $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader); - $.support.xhrFormDataFileUpload = !!window.FormData; + // The FileReader API is not actually used, but works as feature detection, + // as some Safari versions (5?) support XHR file uploads via the FormData API, + // but not non-multipart XHR file uploads. + // window.XMLHttpRequestUpload is not available on IE10, so we check for + // window.ProgressEvent instead to detect XHR2 file upload capability: + $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader); + $.support.xhrFormDataFileUpload = !!window.FormData; - // Detect support for Blob slicing (required for chunked uploads): - $.support.blobSlice = window.Blob && (Blob.prototype.slice || - Blob.prototype.webkitSlice || Blob.prototype.mozSlice); + // Detect support for Blob slicing (required for chunked uploads): + $.support.blobSlice = + window.Blob && + (Blob.prototype.slice || + Blob.prototype.webkitSlice || + Blob.prototype.mozSlice); - // Helper function to create drag handlers for dragover/dragenter/dragleave: - function getDragHandler(type) { - var isDragOver = type === 'dragover'; - return function (e) { - e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer; - var dataTransfer = e.dataTransfer; - if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 && - this._trigger( - type, - $.Event(type, {delegatedEvent: e}) - ) !== false) { - e.preventDefault(); - if (isDragOver) { - dataTransfer.dropEffect = 'copy'; - } - } + /** + * Helper function to create drag handlers for dragover/dragenter/dragleave + * + * @param {string} type Event type + * @returns {Function} Drag handler + */ + function getDragHandler(type) { + var isDragOver = type === 'dragover'; + return function (e) { + e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer; + var dataTransfer = e.dataTransfer; + if ( + dataTransfer && + $.inArray('Files', dataTransfer.types) !== -1 && + this._trigger(type, $.Event(type, { delegatedEvent: e })) !== false + ) { + e.preventDefault(); + if (isDragOver) { + dataTransfer.dropEffect = 'copy'; + } + } + }; + } + + // The fileupload widget listens for change events on file input fields defined + // via fileInput setting and paste or drop events of the given dropZone. + // In addition to the default jQuery Widget methods, the fileupload widget + // exposes the "add" and "send" methods, to add or directly send files using + // the fileupload API. + // By default, files added via file input selection, paste, drag & drop or + // "add" method are uploaded immediately, but it is possible to override + // the "add" callback option to queue file uploads. + $.widget('blueimp.fileupload', { + options: { + // The drop target element(s), by the default the complete document. + // Set to null to disable drag & drop support: + dropZone: $(document), + // The paste target element(s), by the default undefined. + // Set to a DOM node or jQuery object to enable file pasting: + pasteZone: undefined, + // The file input field(s), that are listened to for change events. + // If undefined, it is set to the file input fields inside + // of the widget element on plugin initialization. + // Set to null to disable the change listener. + fileInput: undefined, + // By default, the file input field is replaced with a clone after + // each input field change event. This is required for iframe transport + // queues and allows change events to be fired for the same file + // selection, but can be disabled by setting the following option to false: + replaceFileInput: true, + // The parameter name for the file form data (the request argument name). + // If undefined or empty, the name property of the file input field is + // used, or "files[]" if the file input name property is also empty, + // can be a string or an array of strings: + paramName: undefined, + // By default, each file of a selection is uploaded using an individual + // request for XHR type uploads. Set to false to upload file + // selections in one request each: + singleFileUploads: true, + // To limit the number of files uploaded with one XHR request, + // set the following option to an integer greater than 0: + limitMultiFileUploads: undefined, + // The following option limits the number of files uploaded with one + // XHR request to keep the request size under or equal to the defined + // limit in bytes: + limitMultiFileUploadSize: undefined, + // Multipart file uploads add a number of bytes to each uploaded file, + // therefore the following option adds an overhead for each file used + // in the limitMultiFileUploadSize configuration: + limitMultiFileUploadSizeOverhead: 512, + // Set the following option to true to issue all file upload requests + // in a sequential order: + sequentialUploads: false, + // To limit the number of concurrent uploads, + // set the following option to an integer greater than 0: + limitConcurrentUploads: undefined, + // Set the following option to true to force iframe transport uploads: + forceIframeTransport: false, + // Set the following option to the location of a redirect url on the + // origin server, for cross-domain iframe transport uploads: + redirect: undefined, + // The parameter name for the redirect url, sent as part of the form + // data and set to 'redirect' if this option is empty: + redirectParamName: undefined, + // Set the following option to the location of a postMessage window, + // to enable postMessage transport uploads: + postMessage: undefined, + // By default, XHR file uploads are sent as multipart/form-data. + // The iframe transport is always using multipart/form-data. + // Set to false to enable non-multipart XHR uploads: + multipart: true, + // To upload large files in smaller chunks, set the following option + // to a preferred maximum chunk size. If set to 0, null or undefined, + // or the browser does not support the required Blob API, files will + // be uploaded as a whole. + maxChunkSize: undefined, + // When a non-multipart upload or a chunked multipart upload has been + // aborted, this option can be used to resume the upload by setting + // it to the size of the already uploaded bytes. This option is most + // useful when modifying the options object inside of the "add" or + // "send" callbacks, as the options are cloned for each file upload. + uploadedBytes: undefined, + // By default, failed (abort or error) file uploads are removed from the + // global progress calculation. Set the following option to false to + // prevent recalculating the global progress data: + recalculateProgress: true, + // Interval in milliseconds to calculate and trigger progress events: + progressInterval: 100, + // Interval in milliseconds to calculate progress bitrate: + bitrateInterval: 500, + // By default, uploads are started automatically when adding files: + autoUpload: true, + // By default, duplicate file names are expected to be handled on + // the server-side. If this is not possible (e.g. when uploading + // files directly to Amazon S3), the following option can be set to + // an empty object or an object mapping existing filenames, e.g.: + // { "image.jpg": true, "image (1).jpg": true } + // If it is set, all files will be uploaded with unique filenames, + // adding increasing number suffixes if necessary, e.g.: + // "image (2).jpg" + uniqueFilenames: undefined, + + // Error and info messages: + messages: { + uploadedBytes: 'Uploaded bytes exceed file size' + }, + + // Translation function, gets the message key to be translated + // and an object with context specific data as arguments: + i18n: function (message, context) { + // eslint-disable-next-line no-param-reassign + message = this.messages[message] || message.toString(); + if (context) { + $.each(context, function (key, value) { + // eslint-disable-next-line no-param-reassign + message = message.replace('{' + key + '}', value); + }); + } + return message; + }, + + // Additional form data to be sent along with the file uploads can be set + // using this option, which accepts an array of objects with name and + // value properties, a function returning such an array, a FormData + // object (for XHR file uploads), or a simple object. + // The form of the first fileInput is given as parameter to the function: + formData: function (form) { + return form.serializeArray(); + }, + + // The add callback is invoked as soon as files are added to the fileupload + // widget (via file input selection, drag & drop, paste or add API call). + // If the singleFileUploads option is enabled, this callback will be + // called once for each file in the selection for XHR file uploads, else + // once for each file selection. + // + // The upload starts when the submit method is invoked on the data parameter. + // The data object contains a files property holding the added files + // and allows you to override plugin options as well as define ajax settings. + // + // Listeners for this callback can also be bound the following way: + // .on('fileuploadadd', func); + // + // data.submit() returns a Promise object and allows to attach additional + // handlers using jQuery's Deferred callbacks: + // data.submit().done(func).fail(func).always(func); + add: function (e, data) { + if (e.isDefaultPrevented()) { + return false; + } + if ( + data.autoUpload || + (data.autoUpload !== false && + $(this).fileupload('option', 'autoUpload')) + ) { + data.process().done(function () { + data.submit(); + }); + } + }, + + // Other callbacks: + + // Callback for the submit event of each file upload: + // submit: function (e, data) {}, // .on('fileuploadsubmit', func); + + // Callback for the start of each file upload request: + // send: function (e, data) {}, // .on('fileuploadsend', func); + + // Callback for successful uploads: + // done: function (e, data) {}, // .on('fileuploaddone', func); + + // Callback for failed (abort or error) uploads: + // fail: function (e, data) {}, // .on('fileuploadfail', func); + + // Callback for completed (success, abort or error) requests: + // always: function (e, data) {}, // .on('fileuploadalways', func); + + // Callback for upload progress events: + // progress: function (e, data) {}, // .on('fileuploadprogress', func); + + // Callback for global upload progress events: + // progressall: function (e, data) {}, // .on('fileuploadprogressall', func); + + // Callback for uploads start, equivalent to the global ajaxStart event: + // start: function (e) {}, // .on('fileuploadstart', func); + + // Callback for uploads stop, equivalent to the global ajaxStop event: + // stop: function (e) {}, // .on('fileuploadstop', func); + + // Callback for change events of the fileInput(s): + // change: function (e, data) {}, // .on('fileuploadchange', func); + + // Callback for paste events to the pasteZone(s): + // paste: function (e, data) {}, // .on('fileuploadpaste', func); + + // Callback for drop events of the dropZone(s): + // drop: function (e, data) {}, // .on('fileuploaddrop', func); + + // Callback for dragover events of the dropZone(s): + // dragover: function (e) {}, // .on('fileuploaddragover', func); + + // Callback before the start of each chunk upload request (before form data initialization): + // chunkbeforesend: function (e, data) {}, // .on('fileuploadchunkbeforesend', func); + + // Callback for the start of each chunk upload request: + // chunksend: function (e, data) {}, // .on('fileuploadchunksend', func); + + // Callback for successful chunk uploads: + // chunkdone: function (e, data) {}, // .on('fileuploadchunkdone', func); + + // Callback for failed (abort or error) chunk uploads: + // chunkfail: function (e, data) {}, // .on('fileuploadchunkfail', func); + + // Callback for completed (success, abort or error) chunk upload requests: + // chunkalways: function (e, data) {}, // .on('fileuploadchunkalways', func); + + // The plugin options are used as settings object for the ajax calls. + // The following are jQuery ajax settings required for the file uploads: + processData: false, + contentType: false, + cache: false, + timeout: 0 + }, + + // A list of options that require reinitializing event listeners and/or + // special initialization code: + _specialOptions: [ + 'fileInput', + 'dropZone', + 'pasteZone', + 'multipart', + 'forceIframeTransport' + ], + + _blobSlice: + $.support.blobSlice && + function () { + var slice = this.slice || this.webkitSlice || this.mozSlice; + return slice.apply(this, arguments); + }, + + _BitrateTimer: function () { + this.timestamp = Date.now ? Date.now() : new Date().getTime(); + this.loaded = 0; + this.bitrate = 0; + this.getBitrate = function (now, loaded, interval) { + var timeDiff = now - this.timestamp; + if (!this.bitrate || !interval || timeDiff > interval) { + this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8; + this.loaded = loaded; + this.timestamp = now; + } + return this.bitrate; + }; + }, + + _isXHRUpload: function (options) { + return ( + !options.forceIframeTransport && + ((!options.multipart && $.support.xhrFileUpload) || + $.support.xhrFormDataFileUpload) + ); + }, + + _getFormData: function (options) { + var formData; + if ($.type(options.formData) === 'function') { + return options.formData(options.form); + } + if ($.isArray(options.formData)) { + return options.formData; + } + if ($.type(options.formData) === 'object') { + formData = []; + $.each(options.formData, function (name, value) { + formData.push({ name: name, value: value }); + }); + return formData; + } + return []; + }, + + _getTotal: function (files) { + var total = 0; + $.each(files, function (index, file) { + total += file.size || 1; + }); + return total; + }, + + _initProgressObject: function (obj) { + var progress = { + loaded: 0, + total: 0, + bitrate: 0 + }; + if (obj._progress) { + $.extend(obj._progress, progress); + } else { + obj._progress = progress; + } + }, + + _initResponseObject: function (obj) { + var prop; + if (obj._response) { + for (prop in obj._response) { + if (Object.prototype.hasOwnProperty.call(obj._response, prop)) { + delete obj._response[prop]; + } + } + } else { + obj._response = {}; + } + }, + + _onProgress: function (e, data) { + if (e.lengthComputable) { + var now = Date.now ? Date.now() : new Date().getTime(), + loaded; + if ( + data._time && + data.progressInterval && + now - data._time < data.progressInterval && + e.loaded !== e.total + ) { + return; + } + data._time = now; + loaded = + Math.floor( + (e.loaded / e.total) * (data.chunkSize || data._progress.total) + ) + (data.uploadedBytes || 0); + // Add the difference from the previously loaded state + // to the global loaded counter: + this._progress.loaded += loaded - data._progress.loaded; + this._progress.bitrate = this._bitrateTimer.getBitrate( + now, + this._progress.loaded, + data.bitrateInterval + ); + data._progress.loaded = data.loaded = loaded; + data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate( + now, + loaded, + data.bitrateInterval + ); + // Trigger a custom progress event with a total data property set + // to the file size(s) of the current upload and a loaded data + // property calculated accordingly: + this._trigger( + 'progress', + $.Event('progress', { delegatedEvent: e }), + data + ); + // Trigger a global progress event for all current file uploads, + // including ajax calls queued for sequential file uploads: + this._trigger( + 'progressall', + $.Event('progressall', { delegatedEvent: e }), + this._progress + ); + } + }, + + _initProgressListener: function (options) { + var that = this, + xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr(); + // Accesss to the native XHR object is required to add event listeners + // for the upload progress event: + if (xhr.upload) { + $(xhr.upload).on('progress', function (e) { + var oe = e.originalEvent; + // Make sure the progress event properties get copied over: + e.lengthComputable = oe.lengthComputable; + e.loaded = oe.loaded; + e.total = oe.total; + that._onProgress(e, options); + }); + options.xhr = function () { + return xhr; }; - } + } + }, - // The fileupload widget listens for change events on file input fields defined - // via fileInput setting and paste or drop events of the given dropZone. - // In addition to the default jQuery Widget methods, the fileupload widget - // exposes the "add" and "send" methods, to add or directly send files using - // the fileupload API. - // By default, files added via file input selection, paste, drag & drop or - // "add" method are uploaded immediately, but it is possible to override - // the "add" callback option to queue file uploads. - $.widget('blueimp.fileupload', { + _deinitProgressListener: function (options) { + var xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr(); + if (xhr.upload) { + $(xhr.upload).off('progress'); + } + }, - options: { - // The drop target element(s), by the default the complete document. - // Set to null to disable drag & drop support: - dropZone: $(document), - // The paste target element(s), by the default undefined. - // Set to a DOM node or jQuery object to enable file pasting: - pasteZone: undefined, - // The file input field(s), that are listened to for change events. - // If undefined, it is set to the file input fields inside - // of the widget element on plugin initialization. - // Set to null to disable the change listener. - fileInput: undefined, - // By default, the file input field is replaced with a clone after - // each input field change event. This is required for iframe transport - // queues and allows change events to be fired for the same file - // selection, but can be disabled by setting the following option to false: - replaceFileInput: true, - // The parameter name for the file form data (the request argument name). - // If undefined or empty, the name property of the file input field is - // used, or "files[]" if the file input name property is also empty, - // can be a string or an array of strings: - paramName: undefined, - // By default, each file of a selection is uploaded using an individual - // request for XHR type uploads. Set to false to upload file - // selections in one request each: - singleFileUploads: true, - // To limit the number of files uploaded with one XHR request, - // set the following option to an integer greater than 0: - limitMultiFileUploads: undefined, - // The following option limits the number of files uploaded with one - // XHR request to keep the request size under or equal to the defined - // limit in bytes: - limitMultiFileUploadSize: undefined, - // Multipart file uploads add a number of bytes to each uploaded file, - // therefore the following option adds an overhead for each file used - // in the limitMultiFileUploadSize configuration: - limitMultiFileUploadSizeOverhead: 512, - // Set the following option to true to issue all file upload requests - // in a sequential order: - sequentialUploads: false, - // To limit the number of concurrent uploads, - // set the following option to an integer greater than 0: - limitConcurrentUploads: undefined, - // Set the following option to true to force iframe transport uploads: - forceIframeTransport: false, - // Set the following option to the location of a redirect url on the - // origin server, for cross-domain iframe transport uploads: - redirect: undefined, - // The parameter name for the redirect url, sent as part of the form - // data and set to 'redirect' if this option is empty: - redirectParamName: undefined, - // Set the following option to the location of a postMessage window, - // to enable postMessage transport uploads: - postMessage: undefined, - // By default, XHR file uploads are sent as multipart/form-data. - // The iframe transport is always using multipart/form-data. - // Set to false to enable non-multipart XHR uploads: - multipart: true, - // To upload large files in smaller chunks, set the following option - // to a preferred maximum chunk size. If set to 0, null or undefined, - // or the browser does not support the required Blob API, files will - // be uploaded as a whole. - maxChunkSize: undefined, - // When a non-multipart upload or a chunked multipart upload has been - // aborted, this option can be used to resume the upload by setting - // it to the size of the already uploaded bytes. This option is most - // useful when modifying the options object inside of the "add" or - // "send" callbacks, as the options are cloned for each file upload. - uploadedBytes: undefined, - // By default, failed (abort or error) file uploads are removed from the - // global progress calculation. Set the following option to false to - // prevent recalculating the global progress data: - recalculateProgress: true, - // Interval in milliseconds to calculate and trigger progress events: - progressInterval: 100, - // Interval in milliseconds to calculate progress bitrate: - bitrateInterval: 500, - // By default, uploads are started automatically when adding files: - autoUpload: true, + _isInstanceOf: function (type, obj) { + // Cross-frame instanceof check + return Object.prototype.toString.call(obj) === '[object ' + type + ']'; + }, - // Error and info messages: - messages: { - uploadedBytes: 'Uploaded bytes exceed file size' - }, + _getUniqueFilename: function (name, map) { + // eslint-disable-next-line no-param-reassign + name = String(name); + if (map[name]) { + // eslint-disable-next-line no-param-reassign + name = name.replace(/(?: \(([\d]+)\))?(\.[^.]+)?$/, function ( + _, + p1, + p2 + ) { + var index = p1 ? Number(p1) + 1 : 1; + var ext = p2 || ''; + return ' (' + index + ')' + ext; + }); + return this._getUniqueFilename(name, map); + } + map[name] = true; + return name; + }, - // Translation function, gets the message key to be translated - // and an object with context specific data as arguments: - i18n: function (message, context) { - message = this.messages[message] || message.toString(); - if (context) { - $.each(context, function (key, value) { - message = message.replace('{' + key + '}', value); - }); - } - return message; - }, - - // Additional form data to be sent along with the file uploads can be set - // using this option, which accepts an array of objects with name and - // value properties, a function returning such an array, a FormData - // object (for XHR file uploads), or a simple object. - // The form of the first fileInput is given as parameter to the function: - formData: function (form) { - return form.serializeArray(); - }, - - // The add callback is invoked as soon as files are added to the fileupload - // widget (via file input selection, drag & drop, paste or add API call). - // If the singleFileUploads option is enabled, this callback will be - // called once for each file in the selection for XHR file uploads, else - // once for each file selection. - // - // The upload starts when the submit method is invoked on the data parameter. - // The data object contains a files property holding the added files - // and allows you to override plugin options as well as define ajax settings. - // - // Listeners for this callback can also be bound the following way: - // .bind('fileuploadadd', func); - // - // data.submit() returns a Promise object and allows to attach additional - // handlers using jQuery's Deferred callbacks: - // data.submit().done(func).fail(func).always(func); - add: function (e, data) { - if (e.isDefaultPrevented()) { - return false; - } - if (data.autoUpload || (data.autoUpload !== false && - $(this).fileupload('option', 'autoUpload'))) { - data.process().done(function () { - data.submit(); - }); - } - }, - - // Other callbacks: - - // Callback for the submit event of each file upload: - // submit: function (e, data) {}, // .bind('fileuploadsubmit', func); - - // Callback for the start of each file upload request: - // send: function (e, data) {}, // .bind('fileuploadsend', func); - - // Callback for successful uploads: - // done: function (e, data) {}, // .bind('fileuploaddone', func); - - // Callback for failed (abort or error) uploads: - // fail: function (e, data) {}, // .bind('fileuploadfail', func); - - // Callback for completed (success, abort or error) requests: - // always: function (e, data) {}, // .bind('fileuploadalways', func); - - // Callback for upload progress events: - // progress: function (e, data) {}, // .bind('fileuploadprogress', func); - - // Callback for global upload progress events: - // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func); - - // Callback for uploads start, equivalent to the global ajaxStart event: - // start: function (e) {}, // .bind('fileuploadstart', func); - - // Callback for uploads stop, equivalent to the global ajaxStop event: - // stop: function (e) {}, // .bind('fileuploadstop', func); - - // Callback for change events of the fileInput(s): - // change: function (e, data) {}, // .bind('fileuploadchange', func); - - // Callback for paste events to the pasteZone(s): - // paste: function (e, data) {}, // .bind('fileuploadpaste', func); - - // Callback for drop events of the dropZone(s): - // drop: function (e, data) {}, // .bind('fileuploaddrop', func); - - // Callback for dragover events of the dropZone(s): - // dragover: function (e) {}, // .bind('fileuploaddragover', func); - - // Callback for the start of each chunk upload request: - // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func); - - // Callback for successful chunk uploads: - // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func); - - // Callback for failed (abort or error) chunk uploads: - // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func); - - // Callback for completed (success, abort or error) chunk upload requests: - // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func); - - // The plugin options are used as settings object for the ajax calls. - // The following are jQuery ajax settings required for the file uploads: - processData: false, - contentType: false, - cache: false - }, - - // A list of options that require reinitializing event listeners and/or - // special initialization code: - _specialOptions: [ - 'fileInput', - 'dropZone', - 'pasteZone', - 'multipart', - 'forceIframeTransport' - ], - - _blobSlice: $.support.blobSlice && function () { - var slice = this.slice || this.webkitSlice || this.mozSlice; - return slice.apply(this, arguments); - }, - - _BitrateTimer: function () { - this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime()); - this.loaded = 0; - this.bitrate = 0; - this.getBitrate = function (now, loaded, interval) { - var timeDiff = now - this.timestamp; - if (!this.bitrate || !interval || timeDiff > interval) { - this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8; - this.loaded = loaded; - this.timestamp = now; - } - return this.bitrate; - }; - }, - - _isXHRUpload: function (options) { - return !options.forceIframeTransport && - ((!options.multipart && $.support.xhrFileUpload) || - $.support.xhrFormDataFileUpload); - }, - - _getFormData: function (options) { - var formData; - if ($.type(options.formData) === 'function') { - return options.formData(options.form); - } - if ($.isArray(options.formData)) { - return options.formData; - } - if ($.type(options.formData) === 'object') { - formData = []; - $.each(options.formData, function (name, value) { - formData.push({name: name, value: value}); - }); - return formData; - } - return []; - }, - - _getTotal: function (files) { - var total = 0; - $.each(files, function (index, file) { - total += file.size || 1; + _initXHRData: function (options) { + var that = this, + formData, + file = options.files[0], + // Ignore non-multipart setting if not supported: + multipart = options.multipart || !$.support.xhrFileUpload, + paramName = + $.type(options.paramName) === 'array' + ? options.paramName[0] + : options.paramName; + options.headers = $.extend({}, options.headers); + if (options.contentRange) { + options.headers['Content-Range'] = options.contentRange; + } + if (!multipart || options.blob || !this._isInstanceOf('File', file)) { + options.headers['Content-Disposition'] = + 'attachment; filename="' + + encodeURI(file.uploadName || file.name) + + '"'; + } + if (!multipart) { + options.contentType = file.type || 'application/octet-stream'; + options.data = options.blob || file; + } else if ($.support.xhrFormDataFileUpload) { + if (options.postMessage) { + // window.postMessage does not allow sending FormData + // objects, so we just add the File/Blob objects to + // the formData array and let the postMessage window + // create the FormData object out of this array: + formData = this._getFormData(options); + if (options.blob) { + formData.push({ + name: paramName, + value: options.blob }); - return total; - }, + } else { + $.each(options.files, function (index, file) { + formData.push({ + name: + ($.type(options.paramName) === 'array' && + options.paramName[index]) || + paramName, + value: file + }); + }); + } + } else { + if (that._isInstanceOf('FormData', options.formData)) { + formData = options.formData; + } else { + formData = new FormData(); + $.each(this._getFormData(options), function (index, field) { + formData.append(field.name, field.value); + }); + } + if (options.blob) { + formData.append( + paramName, + options.blob, + file.uploadName || file.name + ); + } else { + $.each(options.files, function (index, file) { + // This check allows the tests to run with + // dummy objects: + if ( + that._isInstanceOf('File', file) || + that._isInstanceOf('Blob', file) + ) { + var fileName = file.uploadName || file.name; + if (options.uniqueFilenames) { + fileName = that._getUniqueFilename( + fileName, + options.uniqueFilenames + ); + } + formData.append( + ($.type(options.paramName) === 'array' && + options.paramName[index]) || + paramName, + file, + fileName + ); + } + }); + } + } + options.data = formData; + } + // Blob reference is not needed anymore, free memory: + options.blob = null; + }, - _initProgressObject: function (obj) { - var progress = { - loaded: 0, - total: 0, - bitrate: 0 - }; - if (obj._progress) { - $.extend(obj._progress, progress); + _initIframeSettings: function (options) { + var targetHost = $('').prop('href', options.url).prop('host'); + // Setting the dataType to iframe enables the iframe transport: + options.dataType = 'iframe ' + (options.dataType || ''); + // The iframe transport accepts a serialized array as form data: + options.formData = this._getFormData(options); + // Add redirect url to form data on cross-domain uploads: + if (options.redirect && targetHost && targetHost !== location.host) { + options.formData.push({ + name: options.redirectParamName || 'redirect', + value: options.redirect + }); + } + }, + + _initDataSettings: function (options) { + if (this._isXHRUpload(options)) { + if (!this._chunkedUpload(options, true)) { + if (!options.data) { + this._initXHRData(options); + } + this._initProgressListener(options); + } + if (options.postMessage) { + // Setting the dataType to postmessage enables the + // postMessage transport: + options.dataType = 'postmessage ' + (options.dataType || ''); + } + } else { + this._initIframeSettings(options); + } + }, + + _getParamName: function (options) { + var fileInput = $(options.fileInput), + paramName = options.paramName; + if (!paramName) { + paramName = []; + fileInput.each(function () { + var input = $(this), + name = input.prop('name') || 'files[]', + i = (input.prop('files') || [1]).length; + while (i) { + paramName.push(name); + i -= 1; + } + }); + if (!paramName.length) { + paramName = [fileInput.prop('name') || 'files[]']; + } + } else if (!$.isArray(paramName)) { + paramName = [paramName]; + } + return paramName; + }, + + _initFormSettings: function (options) { + // Retrieve missing options from the input field and the + // associated form, if available: + if (!options.form || !options.form.length) { + options.form = $(options.fileInput.prop('form')); + // If the given file input doesn't have an associated form, + // use the default widget file input's form: + if (!options.form.length) { + options.form = $(this.options.fileInput.prop('form')); + } + } + options.paramName = this._getParamName(options); + if (!options.url) { + options.url = options.form.prop('action') || location.href; + } + // The HTTP request method must be "POST" or "PUT": + options.type = ( + options.type || + ($.type(options.form.prop('method')) === 'string' && + options.form.prop('method')) || + '' + ).toUpperCase(); + if ( + options.type !== 'POST' && + options.type !== 'PUT' && + options.type !== 'PATCH' + ) { + options.type = 'POST'; + } + if (!options.formAcceptCharset) { + options.formAcceptCharset = options.form.attr('accept-charset'); + } + }, + + _getAJAXSettings: function (data) { + var options = $.extend({}, this.options, data); + this._initFormSettings(options); + this._initDataSettings(options); + return options; + }, + + // jQuery 1.6 doesn't provide .state(), + // while jQuery 1.8+ removed .isRejected() and .isResolved(): + _getDeferredState: function (deferred) { + if (deferred.state) { + return deferred.state(); + } + if (deferred.isResolved()) { + return 'resolved'; + } + if (deferred.isRejected()) { + return 'rejected'; + } + return 'pending'; + }, + + // Maps jqXHR callbacks to the equivalent + // methods of the given Promise object: + _enhancePromise: function (promise) { + promise.success = promise.done; + promise.error = promise.fail; + promise.complete = promise.always; + return promise; + }, + + // Creates and returns a Promise object enhanced with + // the jqXHR methods abort, success, error and complete: + _getXHRPromise: function (resolveOrReject, context, args) { + var dfd = $.Deferred(), + promise = dfd.promise(); + // eslint-disable-next-line no-param-reassign + context = context || this.options.context || promise; + if (resolveOrReject === true) { + dfd.resolveWith(context, args); + } else if (resolveOrReject === false) { + dfd.rejectWith(context, args); + } + promise.abort = dfd.promise; + return this._enhancePromise(promise); + }, + + // Adds convenience methods to the data callback argument: + _addConvenienceMethods: function (e, data) { + var that = this, + getPromise = function (args) { + return $.Deferred().resolveWith(that, args).promise(); + }; + data.process = function (resolveFunc, rejectFunc) { + if (resolveFunc || rejectFunc) { + data._processQueue = this._processQueue = ( + this._processQueue || getPromise([this]) + ) + .then(function () { + if (data.errorThrown) { + return $.Deferred().rejectWith(that, [data]).promise(); + } + return getPromise(arguments); + }) + .then(resolveFunc, rejectFunc); + } + return this._processQueue || getPromise([this]); + }; + data.submit = function () { + if (this.state() !== 'pending') { + data.jqXHR = this.jqXHR = + that._trigger( + 'submit', + $.Event('submit', { delegatedEvent: e }), + this + ) !== false && that._onSend(e, this); + } + return this.jqXHR || that._getXHRPromise(); + }; + data.abort = function () { + if (this.jqXHR) { + return this.jqXHR.abort(); + } + this.errorThrown = 'abort'; + that._trigger('fail', null, this); + return that._getXHRPromise(false); + }; + data.state = function () { + if (this.jqXHR) { + return that._getDeferredState(this.jqXHR); + } + if (this._processQueue) { + return that._getDeferredState(this._processQueue); + } + }; + data.processing = function () { + return ( + !this.jqXHR && + this._processQueue && + that._getDeferredState(this._processQueue) === 'pending' + ); + }; + data.progress = function () { + return this._progress; + }; + data.response = function () { + return this._response; + }; + }, + + // Parses the Range header from the server response + // and returns the uploaded bytes: + _getUploadedBytes: function (jqXHR) { + var range = jqXHR.getResponseHeader('Range'), + parts = range && range.split('-'), + upperBytesPos = parts && parts.length > 1 && parseInt(parts[1], 10); + return upperBytesPos && upperBytesPos + 1; + }, + + // Uploads a file in multiple, sequential requests + // by splitting the file up in multiple blob chunks. + // If the second parameter is true, only tests if the file + // should be uploaded in chunks, but does not invoke any + // upload requests: + _chunkedUpload: function (options, testOnly) { + options.uploadedBytes = options.uploadedBytes || 0; + var that = this, + file = options.files[0], + fs = file.size, + ub = options.uploadedBytes, + mcs = options.maxChunkSize || fs, + slice = this._blobSlice, + dfd = $.Deferred(), + promise = dfd.promise(), + jqXHR, + upload; + if ( + !( + this._isXHRUpload(options) && + slice && + (ub || ($.type(mcs) === 'function' ? mcs(options) : mcs) < fs) + ) || + options.data + ) { + return false; + } + if (testOnly) { + return true; + } + if (ub >= fs) { + file.error = options.i18n('uploadedBytes'); + return this._getXHRPromise(false, options.context, [ + null, + 'error', + file.error + ]); + } + // The chunk upload method: + upload = function () { + // Clone the options object for each chunk upload: + var o = $.extend({}, options), + currentLoaded = o._progress.loaded; + o.blob = slice.call( + file, + ub, + ub + ($.type(mcs) === 'function' ? mcs(o) : mcs), + file.type + ); + // Store the current chunk size, as the blob itself + // will be dereferenced after data processing: + o.chunkSize = o.blob.size; + // Expose the chunk bytes position range: + o.contentRange = + 'bytes ' + ub + '-' + (ub + o.chunkSize - 1) + '/' + fs; + // Trigger chunkbeforesend to allow form data to be updated for this chunk + that._trigger('chunkbeforesend', null, o); + // Process the upload data (the blob and potential form data): + that._initXHRData(o); + // Add progress listeners for this chunk upload: + that._initProgressListener(o); + jqXHR = ( + (that._trigger('chunksend', null, o) !== false && $.ajax(o)) || + that._getXHRPromise(false, o.context) + ) + .done(function (result, textStatus, jqXHR) { + ub = that._getUploadedBytes(jqXHR) || ub + o.chunkSize; + // Create a progress event if no final progress event + // with loaded equaling total has been triggered + // for this chunk: + if (currentLoaded + o.chunkSize - o._progress.loaded) { + that._onProgress( + $.Event('progress', { + lengthComputable: true, + loaded: ub - o.uploadedBytes, + total: ub - o.uploadedBytes + }), + o + ); + } + options.uploadedBytes = o.uploadedBytes = ub; + o.result = result; + o.textStatus = textStatus; + o.jqXHR = jqXHR; + that._trigger('chunkdone', null, o); + that._trigger('chunkalways', null, o); + if (ub < fs) { + // File upload not yet complete, + // continue with the next chunk: + upload(); } else { - obj._progress = progress; + dfd.resolveWith(o.context, [result, textStatus, jqXHR]); } - }, + }) + .fail(function (jqXHR, textStatus, errorThrown) { + o.jqXHR = jqXHR; + o.textStatus = textStatus; + o.errorThrown = errorThrown; + that._trigger('chunkfail', null, o); + that._trigger('chunkalways', null, o); + dfd.rejectWith(o.context, [jqXHR, textStatus, errorThrown]); + }) + .always(function () { + that._deinitProgressListener(o); + }); + }; + this._enhancePromise(promise); + promise.abort = function () { + return jqXHR.abort(); + }; + upload(); + return promise; + }, - _initResponseObject: function (obj) { - var prop; - if (obj._response) { - for (prop in obj._response) { - if (obj._response.hasOwnProperty(prop)) { - delete obj._response[prop]; - } - } - } else { - obj._response = {}; - } - }, + _beforeSend: function (e, data) { + if (this._active === 0) { + // the start callback is triggered when an upload starts + // and no other uploads are currently running, + // equivalent to the global ajaxStart event: + this._trigger('start'); + // Set timer for global bitrate progress calculation: + this._bitrateTimer = new this._BitrateTimer(); + // Reset the global progress values: + this._progress.loaded = this._progress.total = 0; + this._progress.bitrate = 0; + } + // Make sure the container objects for the .response() and + // .progress() methods on the data object are available + // and reset to their initial state: + this._initResponseObject(data); + this._initProgressObject(data); + data._progress.loaded = data.loaded = data.uploadedBytes || 0; + data._progress.total = data.total = this._getTotal(data.files) || 1; + data._progress.bitrate = data.bitrate = 0; + this._active += 1; + // Initialize the global progress values: + this._progress.loaded += data.loaded; + this._progress.total += data.total; + }, - _onProgress: function (e, data) { - if (e.lengthComputable) { - var now = ((Date.now) ? Date.now() : (new Date()).getTime()), - loaded; - if (data._time && data.progressInterval && - (now - data._time < data.progressInterval) && - e.loaded !== e.total) { - return; - } - data._time = now; - loaded = Math.floor( - e.loaded / e.total * (data.chunkSize || data._progress.total) - ) + (data.uploadedBytes || 0); - // Add the difference from the previously loaded state - // to the global loaded counter: - this._progress.loaded += (loaded - data._progress.loaded); - this._progress.bitrate = this._bitrateTimer.getBitrate( - now, - this._progress.loaded, - data.bitrateInterval + _onDone: function (result, textStatus, jqXHR, options) { + var total = options._progress.total, + response = options._response; + if (options._progress.loaded < total) { + // Create a progress event if no final progress event + // with loaded equaling total has been triggered: + this._onProgress( + $.Event('progress', { + lengthComputable: true, + loaded: total, + total: total + }), + options + ); + } + response.result = options.result = result; + response.textStatus = options.textStatus = textStatus; + response.jqXHR = options.jqXHR = jqXHR; + this._trigger('done', null, options); + }, + + _onFail: function (jqXHR, textStatus, errorThrown, options) { + var response = options._response; + if (options.recalculateProgress) { + // Remove the failed (error or abort) file upload from + // the global progress calculation: + this._progress.loaded -= options._progress.loaded; + this._progress.total -= options._progress.total; + } + response.jqXHR = options.jqXHR = jqXHR; + response.textStatus = options.textStatus = textStatus; + response.errorThrown = options.errorThrown = errorThrown; + this._trigger('fail', null, options); + }, + + _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) { + // jqXHRorResult, textStatus and jqXHRorError are added to the + // options object via done and fail callbacks + this._trigger('always', null, options); + }, + + _onSend: function (e, data) { + if (!data.submit) { + this._addConvenienceMethods(e, data); + } + var that = this, + jqXHR, + aborted, + slot, + pipe, + options = that._getAJAXSettings(data), + send = function () { + that._sending += 1; + // Set timer for bitrate progress calculation: + options._bitrateTimer = new that._BitrateTimer(); + jqXHR = + jqXHR || + ( + ((aborted || + that._trigger( + 'send', + $.Event('send', { delegatedEvent: e }), + options + ) === false) && + that._getXHRPromise(false, options.context, aborted)) || + that._chunkedUpload(options) || + $.ajax(options) + ) + .done(function (result, textStatus, jqXHR) { + that._onDone(result, textStatus, jqXHR, options); + }) + .fail(function (jqXHR, textStatus, errorThrown) { + that._onFail(jqXHR, textStatus, errorThrown, options); + }) + .always(function (jqXHRorResult, textStatus, jqXHRorError) { + that._deinitProgressListener(options); + that._onAlways( + jqXHRorResult, + textStatus, + jqXHRorError, + options ); - data._progress.loaded = data.loaded = loaded; - data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate( - now, - loaded, - data.bitrateInterval - ); - // Trigger a custom progress event with a total data property set - // to the file size(s) of the current upload and a loaded data - // property calculated accordingly: - this._trigger( - 'progress', - $.Event('progress', {delegatedEvent: e}), - data - ); - // Trigger a global progress event for all current file uploads, - // including ajax calls queued for sequential file uploads: - this._trigger( - 'progressall', - $.Event('progressall', {delegatedEvent: e}), - this._progress - ); - } - }, - - _initProgressListener: function (options) { - var that = this, - xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr(); - // Accesss to the native XHR object is required to add event listeners - // for the upload progress event: - if (xhr.upload) { - $(xhr.upload).bind('progress', function (e) { - var oe = e.originalEvent; - // Make sure the progress event properties get copied over: - e.lengthComputable = oe.lengthComputable; - e.loaded = oe.loaded; - e.total = oe.total; - that._onProgress(e, options); - }); - options.xhr = function () { - return xhr; - }; - } - }, - - _isInstanceOf: function (type, obj) { - // Cross-frame instanceof check - return Object.prototype.toString.call(obj) === '[object ' + type + ']'; - }, - - _initXHRData: function (options) { - var that = this, - formData, - file = options.files[0], - // Ignore non-multipart setting if not supported: - multipart = options.multipart || !$.support.xhrFileUpload, - paramName = $.type(options.paramName) === 'array' ? - options.paramName[0] : options.paramName; - options.headers = $.extend({}, options.headers); - if (options.contentRange) { - options.headers['Content-Range'] = options.contentRange; - } - if (!multipart || options.blob || !this._isInstanceOf('File', file)) { - options.headers['Content-Disposition'] = 'attachment; filename="' + - encodeURI(file.name) + '"'; - } - if (!multipart) { - options.contentType = file.type || 'application/octet-stream'; - options.data = options.blob || file; - } else if ($.support.xhrFormDataFileUpload) { - if (options.postMessage) { - // window.postMessage does not allow sending FormData - // objects, so we just add the File/Blob objects to - // the formData array and let the postMessage window - // create the FormData object out of this array: - formData = this._getFormData(options); - if (options.blob) { - formData.push({ - name: paramName, - value: options.blob - }); - } else { - $.each(options.files, function (index, file) { - formData.push({ - name: ($.type(options.paramName) === 'array' && - options.paramName[index]) || paramName, - value: file - }); - }); - } - } else { - if (that._isInstanceOf('FormData', options.formData)) { - formData = options.formData; - } else { - formData = new FormData(); - $.each(this._getFormData(options), function (index, field) { - formData.append(field.name, field.value); - }); - } - if (options.blob) { - formData.append(paramName, options.blob, file.name); - } else { - $.each(options.files, function (index, file) { - // This check allows the tests to run with - // dummy objects: - if (that._isInstanceOf('File', file) || - that._isInstanceOf('Blob', file)) { - formData.append( - ($.type(options.paramName) === 'array' && - options.paramName[index]) || paramName, - file, - file.uploadName || file.name - ); - } - }); + that._sending -= 1; + that._active -= 1; + if ( + options.limitConcurrentUploads && + options.limitConcurrentUploads > that._sending + ) { + // Start the next queued upload, + // that has not been aborted: + var nextSlot = that._slots.shift(); + while (nextSlot) { + if (that._getDeferredState(nextSlot) === 'pending') { + nextSlot.resolve(); + break; } + nextSlot = that._slots.shift(); + } } - options.data = formData; - } - // Blob reference is not needed anymore, free memory: - options.blob = null; - }, - - _initIframeSettings: function (options) { - var targetHost = $('').prop('href', options.url).prop('host'); - // Setting the dataType to iframe enables the iframe transport: - options.dataType = 'iframe ' + (options.dataType || ''); - // The iframe transport accepts a serialized array as form data: - options.formData = this._getFormData(options); - // Add redirect url to form data on cross-domain uploads: - if (options.redirect && targetHost && targetHost !== location.host) { - options.formData.push({ - name: options.redirectParamName || 'redirect', - value: options.redirect - }); - } - }, - - _initDataSettings: function (options) { - if (this._isXHRUpload(options)) { - if (!this._chunkedUpload(options, true)) { - if (!options.data) { - this._initXHRData(options); - } - this._initProgressListener(options); + if (that._active === 0) { + // The stop callback is triggered when all uploads have + // been completed, equivalent to the global ajaxStop event: + that._trigger('stop'); } - if (options.postMessage) { - // Setting the dataType to postmessage enables the - // postMessage transport: - options.dataType = 'postmessage ' + (options.dataType || ''); - } - } else { - this._initIframeSettings(options); - } - }, - - _getParamName: function (options) { - var fileInput = $(options.fileInput), - paramName = options.paramName; - if (!paramName) { - paramName = []; - fileInput.each(function () { - var input = $(this), - name = input.prop('name') || 'files[]', - i = (input.prop('files') || [1]).length; - while (i) { - paramName.push(name); - i -= 1; - } - }); - if (!paramName.length) { - paramName = [fileInput.prop('name') || 'files[]']; - } - } else if (!$.isArray(paramName)) { - paramName = [paramName]; - } - return paramName; - }, - - _initFormSettings: function (options) { - // Retrieve missing options from the input field and the - // associated form, if available: - if (!options.form || !options.form.length) { - options.form = $(options.fileInput.prop('form')); - // If the given file input doesn't have an associated form, - // use the default widget file input's form: - if (!options.form.length) { - options.form = $(this.options.fileInput.prop('form')); - } - } - options.paramName = this._getParamName(options); - if (!options.url) { - options.url = options.form.prop('action') || location.href; - } - // The HTTP request method must be "POST" or "PUT": - options.type = (options.type || - ($.type(options.form.prop('method')) === 'string' && - options.form.prop('method')) || '' - ).toUpperCase(); - if (options.type !== 'POST' && options.type !== 'PUT' && - options.type !== 'PATCH') { - options.type = 'POST'; - } - if (!options.formAcceptCharset) { - options.formAcceptCharset = options.form.attr('accept-charset'); - } - }, - - _getAJAXSettings: function (data) { - var options = $.extend({}, this.options, data); - this._initFormSettings(options); - this._initDataSettings(options); - return options; - }, - - // jQuery 1.6 doesn't provide .state(), - // while jQuery 1.8+ removed .isRejected() and .isResolved(): - _getDeferredState: function (deferred) { - if (deferred.state) { - return deferred.state(); - } - if (deferred.isResolved()) { - return 'resolved'; - } - if (deferred.isRejected()) { - return 'rejected'; - } - return 'pending'; - }, - - // Maps jqXHR callbacks to the equivalent - // methods of the given Promise object: - _enhancePromise: function (promise) { - promise.success = promise.done; - promise.error = promise.fail; - promise.complete = promise.always; - return promise; - }, - - // Creates and returns a Promise object enhanced with - // the jqXHR methods abort, success, error and complete: - _getXHRPromise: function (resolveOrReject, context, args) { - var dfd = $.Deferred(), - promise = dfd.promise(); - context = context || this.options.context || promise; - if (resolveOrReject === true) { - dfd.resolveWith(context, args); - } else if (resolveOrReject === false) { - dfd.rejectWith(context, args); - } - promise.abort = dfd.promise; - return this._enhancePromise(promise); - }, - - // Adds convenience methods to the data callback argument: - _addConvenienceMethods: function (e, data) { - var that = this, - getPromise = function (args) { - return $.Deferred().resolveWith(that, args).promise(); - }; - data.process = function (resolveFunc, rejectFunc) { - if (resolveFunc || rejectFunc) { - data._processQueue = this._processQueue = - (this._processQueue || getPromise([this])).pipe( - function () { - if (data.errorThrown) { - return $.Deferred() - .rejectWith(that, [data]).promise(); - } - return getPromise(arguments); - } - ).pipe(resolveFunc, rejectFunc); - } - return this._processQueue || getPromise([this]); - }; - data.submit = function () { - if (this.state() !== 'pending') { - data.jqXHR = this.jqXHR = - (that._trigger( - 'submit', - $.Event('submit', {delegatedEvent: e}), - this - ) !== false) && that._onSend(e, this); - } - return this.jqXHR || that._getXHRPromise(); - }; - data.abort = function () { - if (this.jqXHR) { - return this.jqXHR.abort(); - } - this.errorThrown = 'abort'; - that._trigger('fail', null, this); - return that._getXHRPromise(false); - }; - data.state = function () { - if (this.jqXHR) { - return that._getDeferredState(this.jqXHR); - } - if (this._processQueue) { - return that._getDeferredState(this._processQueue); - } - }; - data.processing = function () { - return !this.jqXHR && this._processQueue && that - ._getDeferredState(this._processQueue) === 'pending'; - }; - data.progress = function () { - return this._progress; - }; - data.response = function () { - return this._response; - }; - }, - - // Parses the Range header from the server response - // and returns the uploaded bytes: - _getUploadedBytes: function (jqXHR) { - var range = jqXHR.getResponseHeader('Range'), - parts = range && range.split('-'), - upperBytesPos = parts && parts.length > 1 && - parseInt(parts[1], 10); - return upperBytesPos && upperBytesPos + 1; - }, - - // Uploads a file in multiple, sequential requests - // by splitting the file up in multiple blob chunks. - // If the second parameter is true, only tests if the file - // should be uploaded in chunks, but does not invoke any - // upload requests: - _chunkedUpload: function (options, testOnly) { - options.uploadedBytes = options.uploadedBytes || 0; - var that = this, - file = options.files[0], - fs = file.size, - ub = options.uploadedBytes, - mcs = options.maxChunkSize || fs, - slice = this._blobSlice, - dfd = $.Deferred(), - promise = dfd.promise(), - jqXHR, - upload; - if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) || - options.data) { - return false; - } - if (testOnly) { - return true; - } - if (ub >= fs) { - file.error = options.i18n('uploadedBytes'); - return this._getXHRPromise( - false, - options.context, - [null, 'error', file.error] - ); - } - // The chunk upload method: - upload = function () { - // Clone the options object for each chunk upload: - var o = $.extend({}, options), - currentLoaded = o._progress.loaded; - o.blob = slice.call( - file, - ub, - ub + mcs, - file.type - ); - // Store the current chunk size, as the blob itself - // will be dereferenced after data processing: - o.chunkSize = o.blob.size; - // Expose the chunk bytes position range: - o.contentRange = 'bytes ' + ub + '-' + - (ub + o.chunkSize - 1) + '/' + fs; - // Process the upload data (the blob and potential form data): - that._initXHRData(o); - // Add progress listeners for this chunk upload: - that._initProgressListener(o); - jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) || - that._getXHRPromise(false, o.context)) - .done(function (result, textStatus, jqXHR) { - ub = that._getUploadedBytes(jqXHR) || - (ub + o.chunkSize); - // Create a progress event if no final progress event - // with loaded equaling total has been triggered - // for this chunk: - if (currentLoaded + o.chunkSize - o._progress.loaded) { - that._onProgress($.Event('progress', { - lengthComputable: true, - loaded: ub - o.uploadedBytes, - total: ub - o.uploadedBytes - }), o); - } - options.uploadedBytes = o.uploadedBytes = ub; - o.result = result; - o.textStatus = textStatus; - o.jqXHR = jqXHR; - that._trigger('chunkdone', null, o); - that._trigger('chunkalways', null, o); - if (ub < fs) { - // File upload not yet complete, - // continue with the next chunk: - upload(); - } else { - dfd.resolveWith( - o.context, - [result, textStatus, jqXHR] - ); - } - }) - .fail(function (jqXHR, textStatus, errorThrown) { - o.jqXHR = jqXHR; - o.textStatus = textStatus; - o.errorThrown = errorThrown; - that._trigger('chunkfail', null, o); - that._trigger('chunkalways', null, o); - dfd.rejectWith( - o.context, - [jqXHR, textStatus, errorThrown] - ); - }); - }; - this._enhancePromise(promise); - promise.abort = function () { - return jqXHR.abort(); - }; - upload(); - return promise; - }, - - _beforeSend: function (e, data) { - if (this._active === 0) { - // the start callback is triggered when an upload starts - // and no other uploads are currently running, - // equivalent to the global ajaxStart event: - this._trigger('start'); - // Set timer for global bitrate progress calculation: - this._bitrateTimer = new this._BitrateTimer(); - // Reset the global progress values: - this._progress.loaded = this._progress.total = 0; - this._progress.bitrate = 0; - } - // Make sure the container objects for the .response() and - // .progress() methods on the data object are available - // and reset to their initial state: - this._initResponseObject(data); - this._initProgressObject(data); - data._progress.loaded = data.loaded = data.uploadedBytes || 0; - data._progress.total = data.total = this._getTotal(data.files) || 1; - data._progress.bitrate = data.bitrate = 0; - this._active += 1; - // Initialize the global progress values: - this._progress.loaded += data.loaded; - this._progress.total += data.total; - }, - - _onDone: function (result, textStatus, jqXHR, options) { - var total = options._progress.total, - response = options._response; - if (options._progress.loaded < total) { - // Create a progress event if no final progress event - // with loaded equaling total has been triggered: - this._onProgress($.Event('progress', { - lengthComputable: true, - loaded: total, - total: total - }), options); - } - response.result = options.result = result; - response.textStatus = options.textStatus = textStatus; - response.jqXHR = options.jqXHR = jqXHR; - this._trigger('done', null, options); - }, - - _onFail: function (jqXHR, textStatus, errorThrown, options) { - var response = options._response; - if (options.recalculateProgress) { - // Remove the failed (error or abort) file upload from - // the global progress calculation: - this._progress.loaded -= options._progress.loaded; - this._progress.total -= options._progress.total; - } - response.jqXHR = options.jqXHR = jqXHR; - response.textStatus = options.textStatus = textStatus; - response.errorThrown = options.errorThrown = errorThrown; - this._trigger('fail', null, options); - }, - - _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) { - // jqXHRorResult, textStatus and jqXHRorError are added to the - // options object via done and fail callbacks - this._trigger('always', null, options); - }, - - _onSend: function (e, data) { - if (!data.submit) { - this._addConvenienceMethods(e, data); - } - var that = this, - jqXHR, - aborted, - slot, - pipe, - options = that._getAJAXSettings(data), - send = function () { - that._sending += 1; - // Set timer for bitrate progress calculation: - options._bitrateTimer = new that._BitrateTimer(); - jqXHR = jqXHR || ( - ((aborted || that._trigger( - 'send', - $.Event('send', {delegatedEvent: e}), - options - ) === false) && - that._getXHRPromise(false, options.context, aborted)) || - that._chunkedUpload(options) || $.ajax(options) - ).done(function (result, textStatus, jqXHR) { - that._onDone(result, textStatus, jqXHR, options); - }).fail(function (jqXHR, textStatus, errorThrown) { - that._onFail(jqXHR, textStatus, errorThrown, options); - }).always(function (jqXHRorResult, textStatus, jqXHRorError) { - that._onAlways( - jqXHRorResult, - textStatus, - jqXHRorError, - options - ); - that._sending -= 1; - that._active -= 1; - if (options.limitConcurrentUploads && - options.limitConcurrentUploads > that._sending) { - // Start the next queued upload, - // that has not been aborted: - var nextSlot = that._slots.shift(); - while (nextSlot) { - if (that._getDeferredState(nextSlot) === 'pending') { - nextSlot.resolve(); - break; - } - nextSlot = that._slots.shift(); - } - } - if (that._active === 0) { - // The stop callback is triggered when all uploads have - // been completed, equivalent to the global ajaxStop event: - that._trigger('stop'); - } - }); - return jqXHR; - }; - this._beforeSend(e, options); - if (this.options.sequentialUploads || - (this.options.limitConcurrentUploads && - this.options.limitConcurrentUploads <= this._sending)) { - if (this.options.limitConcurrentUploads > 1) { - slot = $.Deferred(); - this._slots.push(slot); - pipe = slot.pipe(send); - } else { - this._sequence = this._sequence.pipe(send, send); - pipe = this._sequence; - } - // Return the piped Promise object, enhanced with an abort method, - // which is delegated to the jqXHR object of the current upload, - // and jqXHR callbacks mapped to the equivalent Promise methods: - pipe.abort = function () { - aborted = [undefined, 'abort', 'abort']; - if (!jqXHR) { - if (slot) { - slot.rejectWith(options.context, aborted); - } - return send(); - } - return jqXHR.abort(); - }; - return this._enhancePromise(pipe); + }); + return jqXHR; + }; + this._beforeSend(e, options); + if ( + this.options.sequentialUploads || + (this.options.limitConcurrentUploads && + this.options.limitConcurrentUploads <= this._sending) + ) { + if (this.options.limitConcurrentUploads > 1) { + slot = $.Deferred(); + this._slots.push(slot); + pipe = slot.then(send); + } else { + this._sequence = this._sequence.then(send, send); + pipe = this._sequence; + } + // Return the piped Promise object, enhanced with an abort method, + // which is delegated to the jqXHR object of the current upload, + // and jqXHR callbacks mapped to the equivalent Promise methods: + pipe.abort = function () { + aborted = [undefined, 'abort', 'abort']; + if (!jqXHR) { + if (slot) { + slot.rejectWith(options.context, aborted); } return send(); - }, + } + return jqXHR.abort(); + }; + return this._enhancePromise(pipe); + } + return send(); + }, - _onAdd: function (e, data) { - var that = this, - result = true, - options = $.extend({}, this.options, data), - files = data.files, - filesLength = files.length, - limit = options.limitMultiFileUploads, - limitSize = options.limitMultiFileUploadSize, - overhead = options.limitMultiFileUploadSizeOverhead, - batchSize = 0, - paramName = this._getParamName(options), - paramNameSet, - paramNameSlice, - fileSet, - i, - j = 0; - if (limitSize && (!filesLength || files[0].size === undefined)) { - limitSize = undefined; - } - if (!(options.singleFileUploads || limit || limitSize) || - !this._isXHRUpload(options)) { - fileSet = [files]; - paramNameSet = [paramName]; - } else if (!(options.singleFileUploads || limitSize) && limit) { - fileSet = []; - paramNameSet = []; - for (i = 0; i < filesLength; i += limit) { - fileSet.push(files.slice(i, i + limit)); - paramNameSlice = paramName.slice(i, i + limit); - if (!paramNameSlice.length) { - paramNameSlice = paramName; - } - paramNameSet.push(paramNameSlice); - } - } else if (!options.singleFileUploads && limitSize) { - fileSet = []; - paramNameSet = []; - for (i = 0; i < filesLength; i = i + 1) { - batchSize += files[i].size + overhead; - if (i + 1 === filesLength || - ((batchSize + files[i + 1].size + overhead) > limitSize) || - (limit && i + 1 - j >= limit)) { - fileSet.push(files.slice(j, i + 1)); - paramNameSlice = paramName.slice(j, i + 1); - if (!paramNameSlice.length) { - paramNameSlice = paramName; - } - paramNameSet.push(paramNameSlice); - j = i + 1; - batchSize = 0; - } - } - } else { - paramNameSet = paramName; - } - data.originalFiles = files; - $.each(fileSet || files, function (index, element) { - var newData = $.extend({}, data); - newData.files = fileSet ? element : [element]; - newData.paramName = paramNameSet[index]; - that._initResponseObject(newData); - that._initProgressObject(newData); - that._addConvenienceMethods(e, newData); - result = that._trigger( - 'add', - $.Event('add', {delegatedEvent: e}), - newData - ); - return result; - }); - return result; - }, - - _replaceFileInput: function (data) { - var input = data.fileInput, - inputClone = input.clone(true); - // Add a reference for the new cloned file input to the data argument: - data.fileInputClone = inputClone; - $('
').append(inputClone)[0].reset(); - // Detaching allows to insert the fileInput on another form - // without loosing the file input value: - input.after(inputClone).detach(); - // Avoid memory leaks with the detached file input: - $.cleanData(input.unbind('remove')); - // Replace the original file input element in the fileInput - // elements set with the clone, which has been copied including - // event handlers: - this.options.fileInput = this.options.fileInput.map(function (i, el) { - if (el === input[0]) { - return inputClone[0]; - } - return el; - }); - // If the widget has been initialized on the file input itself, - // override this.element with the file input clone: - if (input[0] === this.element[0]) { - this.element = inputClone; - } - }, - - _handleFileTreeEntry: function (entry, path) { - var that = this, - dfd = $.Deferred(), - errorHandler = function (e) { - if (e && !e.entry) { - e.entry = entry; - } - // Since $.when returns immediately if one - // Deferred is rejected, we use resolve instead. - // This allows valid files and invalid items - // to be returned together in one set: - dfd.resolve([e]); - }, - successHandler = function (entries) { - that._handleFileTreeEntries( - entries, - path + entry.name + '/' - ).done(function (files) { - dfd.resolve(files); - }).fail(errorHandler); - }, - readEntries = function () { - dirReader.readEntries(function (results) { - if (!results.length) { - successHandler(entries); - } else { - entries = entries.concat(results); - readEntries(); - } - }, errorHandler); - }, - dirReader, entries = []; - path = path || ''; - if (entry.isFile) { - if (entry._file) { - // Workaround for Chrome bug #149735 - entry._file.relativePath = path; - dfd.resolve(entry._file); - } else { - entry.file(function (file) { - file.relativePath = path; - dfd.resolve(file); - }, errorHandler); - } - } else if (entry.isDirectory) { - dirReader = entry.createReader(); - readEntries(); - } else { - // Return an empy list for file system items - // other than files or directories: - dfd.resolve([]); - } - return dfd.promise(); - }, - - _handleFileTreeEntries: function (entries, path) { - var that = this; - return $.when.apply( - $, - $.map(entries, function (entry) { - return that._handleFileTreeEntry(entry, path); - }) - ).pipe(function () { - return Array.prototype.concat.apply( - [], - arguments - ); - }); - }, - - _getDroppedFiles: function (dataTransfer) { - dataTransfer = dataTransfer || {}; - var items = dataTransfer.items; - if (items && items.length && (items[0].webkitGetAsEntry || - items[0].getAsEntry)) { - return this._handleFileTreeEntries( - $.map(items, function (item) { - var entry; - if (item.webkitGetAsEntry) { - entry = item.webkitGetAsEntry(); - if (entry) { - // Workaround for Chrome bug #149735: - entry._file = item.getAsFile(); - } - return entry; - } - return item.getAsEntry(); - }) - ); - } - return $.Deferred().resolve( - $.makeArray(dataTransfer.files) - ).promise(); - }, - - _getSingleFileInputFiles: function (fileInput) { - fileInput = $(fileInput); - var entries = fileInput.prop('webkitEntries') || - fileInput.prop('entries'), - files, - value; - if (entries && entries.length) { - return this._handleFileTreeEntries(entries); - } - files = $.makeArray(fileInput.prop('files')); - if (!files.length) { - value = fileInput.prop('value'); - if (!value) { - return $.Deferred().resolve([]).promise(); - } - // If the files property is not available, the browser does not - // support the File API and we add a pseudo File object with - // the input value as name with path information removed: - files = [{name: value.replace(/^.*\\/, '')}]; - } else if (files[0].name === undefined && files[0].fileName) { - // File normalization for Safari 4 and Firefox 3: - $.each(files, function (index, file) { - file.name = file.fileName; - file.size = file.fileSize; - }); - } - return $.Deferred().resolve(files).promise(); - }, - - _getFileInputFiles: function (fileInput) { - if (!(fileInput instanceof $) || fileInput.length === 1) { - return this._getSingleFileInputFiles(fileInput); - } - return $.when.apply( - $, - $.map(fileInput, this._getSingleFileInputFiles) - ).pipe(function () { - return Array.prototype.concat.apply( - [], - arguments - ); - }); - }, - - _onChange: function (e) { - var that = this, - data = { - fileInput: $(e.target), - form: $(e.target.form) - }; - this._getFileInputFiles(data.fileInput).always(function (files) { - data.files = files; - if (that.options.replaceFileInput) { - that._replaceFileInput(data); - } - if (that._trigger( - 'change', - $.Event('change', {delegatedEvent: e}), - data - ) !== false) { - that._onAdd(e, data); - } - }); - }, - - _onPaste: function (e) { - var items = e.originalEvent && e.originalEvent.clipboardData && - e.originalEvent.clipboardData.items, - data = {files: []}; - if (items && items.length) { - $.each(items, function (index, item) { - var file = item.getAsFile && item.getAsFile(); - if (file) { - data.files.push(file); - } - }); - if (this._trigger( - 'paste', - $.Event('paste', {delegatedEvent: e}), - data - ) !== false) { - this._onAdd(e, data); - } - } - }, - - _onDrop: function (e) { - e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer; - var that = this, - dataTransfer = e.dataTransfer, - data = {}; - if (dataTransfer && dataTransfer.files && dataTransfer.files.length) { - e.preventDefault(); - this._getDroppedFiles(dataTransfer).always(function (files) { - data.files = files; - if (that._trigger( - 'drop', - $.Event('drop', {delegatedEvent: e}), - data - ) !== false) { - that._onAdd(e, data); - } - }); - } - }, - - _onDragOver: getDragHandler('dragover'), - - _onDragEnter: getDragHandler('dragenter'), - - _onDragLeave: getDragHandler('dragleave'), - - _initEventHandlers: function () { - if (this._isXHRUpload(this.options)) { - this._on(this.options.dropZone, { - dragover: this._onDragOver, - drop: this._onDrop, - // event.preventDefault() on dragenter is required for IE10+: - dragenter: this._onDragEnter, - // dragleave is not required, but added for completeness: - dragleave: this._onDragLeave - }); - this._on(this.options.pasteZone, { - paste: this._onPaste - }); - } - if ($.support.fileInput) { - this._on(this.options.fileInput, { - change: this._onChange - }); - } - }, - - _destroyEventHandlers: function () { - this._off(this.options.dropZone, 'dragenter dragleave dragover drop'); - this._off(this.options.pasteZone, 'paste'); - this._off(this.options.fileInput, 'change'); - }, - - _setOption: function (key, value) { - var reinit = $.inArray(key, this._specialOptions) !== -1; - if (reinit) { - this._destroyEventHandlers(); - } - this._super(key, value); - if (reinit) { - this._initSpecialOptions(); - this._initEventHandlers(); - } - }, - - _initSpecialOptions: function () { - var options = this.options; - if (options.fileInput === undefined) { - options.fileInput = this.element.is('input[type="file"]') ? - this.element : this.element.find('input[type="file"]'); - } else if (!(options.fileInput instanceof $)) { - options.fileInput = $(options.fileInput); - } - if (!(options.dropZone instanceof $)) { - options.dropZone = $(options.dropZone); - } - if (!(options.pasteZone instanceof $)) { - options.pasteZone = $(options.pasteZone); - } - }, - - _getRegExp: function (str) { - var parts = str.split('/'), - modifiers = parts.pop(); - parts.shift(); - return new RegExp(parts.join('/'), modifiers); - }, - - _isRegExpOption: function (key, value) { - return key !== 'url' && $.type(value) === 'string' && - /^\/.*\/[igm]{0,3}$/.test(value); - }, - - _initDataAttributes: function () { - var that = this, - options = this.options, - clone = $(this.element[0].cloneNode(false)), - data = clone.data(); - // Avoid memory leaks: - clone.remove(); - // Initialize options set via HTML5 data-attributes: - $.each( - data, - function (key, value) { - var dataAttributeName = 'data-' + - // Convert camelCase to hyphen-ated key: - key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); - if (clone.attr(dataAttributeName)) { - if (that._isRegExpOption(key, value)) { - value = that._getRegExp(value); - } - options[key] = value; - } - } - ); - }, - - _create: function () { - this._initDataAttributes(); - this._initSpecialOptions(); - this._slots = []; - this._sequence = this._getXHRPromise(true); - this._sending = this._active = 0; - this._initProgressObject(this); - this._initEventHandlers(); - }, - - // This method is exposed to the widget API and allows to query - // the number of active uploads: - active: function () { - return this._active; - }, - - // This method is exposed to the widget API and allows to query - // the widget upload progress. - // It returns an object with loaded, total and bitrate properties - // for the running uploads: - progress: function () { - return this._progress; - }, - - // This method is exposed to the widget API and allows adding files - // using the fileupload API. The data parameter accepts an object which - // must have a files property and can contain additional options: - // .fileupload('add', {files: filesList}); - add: function (data) { - var that = this; - if (!data || this.options.disabled) { - return; - } - if (data.fileInput && !data.files) { - this._getFileInputFiles(data.fileInput).always(function (files) { - data.files = files; - that._onAdd(null, data); - }); - } else { - data.files = $.makeArray(data.files); - this._onAdd(null, data); - } - }, - - // This method is exposed to the widget API and allows sending files - // using the fileupload API. The data parameter accepts an object which - // must have a files or fileInput property and can contain additional options: - // .fileupload('send', {files: filesList}); - // The method returns a Promise object for the file upload call. - send: function (data) { - if (data && !this.options.disabled) { - if (data.fileInput && !data.files) { - var that = this, - dfd = $.Deferred(), - promise = dfd.promise(), - jqXHR, - aborted; - promise.abort = function () { - aborted = true; - if (jqXHR) { - return jqXHR.abort(); - } - dfd.reject(null, 'abort', 'abort'); - return promise; - }; - this._getFileInputFiles(data.fileInput).always( - function (files) { - if (aborted) { - return; - } - if (!files.length) { - dfd.reject(); - return; - } - data.files = files; - jqXHR = that._onSend(null, data); - jqXHR.then( - function (result, textStatus, jqXHR) { - dfd.resolve(result, textStatus, jqXHR); - }, - function (jqXHR, textStatus, errorThrown) { - dfd.reject(jqXHR, textStatus, errorThrown); - } - ); - } - ); - return this._enhancePromise(promise); - } - data.files = $.makeArray(data.files); - if (data.files.length) { - return this._onSend(null, data); - } - } - return this._getXHRPromise(false, data && data.context); + _onAdd: function (e, data) { + var that = this, + result = true, + options = $.extend({}, this.options, data), + files = data.files, + filesLength = files.length, + limit = options.limitMultiFileUploads, + limitSize = options.limitMultiFileUploadSize, + overhead = options.limitMultiFileUploadSizeOverhead, + batchSize = 0, + paramName = this._getParamName(options), + paramNameSet, + paramNameSlice, + fileSet, + i, + j = 0; + if (!filesLength) { + return false; + } + if (limitSize && files[0].size === undefined) { + limitSize = undefined; + } + if ( + !(options.singleFileUploads || limit || limitSize) || + !this._isXHRUpload(options) + ) { + fileSet = [files]; + paramNameSet = [paramName]; + } else if (!(options.singleFileUploads || limitSize) && limit) { + fileSet = []; + paramNameSet = []; + for (i = 0; i < filesLength; i += limit) { + fileSet.push(files.slice(i, i + limit)); + paramNameSlice = paramName.slice(i, i + limit); + if (!paramNameSlice.length) { + paramNameSlice = paramName; + } + paramNameSet.push(paramNameSlice); } + } else if (!options.singleFileUploads && limitSize) { + fileSet = []; + paramNameSet = []; + for (i = 0; i < filesLength; i = i + 1) { + batchSize += files[i].size + overhead; + if ( + i + 1 === filesLength || + batchSize + files[i + 1].size + overhead > limitSize || + (limit && i + 1 - j >= limit) + ) { + fileSet.push(files.slice(j, i + 1)); + paramNameSlice = paramName.slice(j, i + 1); + if (!paramNameSlice.length) { + paramNameSlice = paramName; + } + paramNameSet.push(paramNameSlice); + j = i + 1; + batchSize = 0; + } + } + } else { + paramNameSet = paramName; + } + data.originalFiles = files; + $.each(fileSet || files, function (index, element) { + var newData = $.extend({}, data); + newData.files = fileSet ? element : [element]; + newData.paramName = paramNameSet[index]; + that._initResponseObject(newData); + that._initProgressObject(newData); + that._addConvenienceMethods(e, newData); + result = that._trigger( + 'add', + $.Event('add', { delegatedEvent: e }), + newData + ); + return result; + }); + return result; + }, - }); + _replaceFileInput: function (data) { + var input = data.fileInput, + inputClone = input.clone(true), + restoreFocus = input.is(document.activeElement); + // Add a reference for the new cloned file input to the data argument: + data.fileInputClone = inputClone; + $('
').append(inputClone)[0].reset(); + // Detaching allows to insert the fileInput on another form + // without loosing the file input value: + input.after(inputClone).detach(); + // If the fileInput had focus before it was detached, + // restore focus to the inputClone. + if (restoreFocus) { + inputClone.focus(); + } + // Avoid memory leaks with the detached file input: + $.cleanData(input.off('remove')); + // Replace the original file input element in the fileInput + // elements set with the clone, which has been copied including + // event handlers: + this.options.fileInput = this.options.fileInput.map(function (i, el) { + if (el === input[0]) { + return inputClone[0]; + } + return el; + }); + // If the widget has been initialized on the file input itself, + // override this.element with the file input clone: + if (input[0] === this.element[0]) { + this.element = inputClone; + } + }, -})); + _handleFileTreeEntry: function (entry, path) { + var that = this, + dfd = $.Deferred(), + entries = [], + dirReader, + errorHandler = function (e) { + if (e && !e.entry) { + e.entry = entry; + } + // Since $.when returns immediately if one + // Deferred is rejected, we use resolve instead. + // This allows valid files and invalid items + // to be returned together in one set: + dfd.resolve([e]); + }, + successHandler = function (entries) { + that + ._handleFileTreeEntries(entries, path + entry.name + '/') + .done(function (files) { + dfd.resolve(files); + }) + .fail(errorHandler); + }, + readEntries = function () { + dirReader.readEntries(function (results) { + if (!results.length) { + successHandler(entries); + } else { + entries = entries.concat(results); + readEntries(); + } + }, errorHandler); + }; + // eslint-disable-next-line no-param-reassign + path = path || ''; + if (entry.isFile) { + if (entry._file) { + // Workaround for Chrome bug #149735 + entry._file.relativePath = path; + dfd.resolve(entry._file); + } else { + entry.file(function (file) { + file.relativePath = path; + dfd.resolve(file); + }, errorHandler); + } + } else if (entry.isDirectory) { + dirReader = entry.createReader(); + readEntries(); + } else { + // Return an empty list for file system items + // other than files or directories: + dfd.resolve([]); + } + return dfd.promise(); + }, + + _handleFileTreeEntries: function (entries, path) { + var that = this; + return $.when + .apply( + $, + $.map(entries, function (entry) { + return that._handleFileTreeEntry(entry, path); + }) + ) + .then(function () { + return Array.prototype.concat.apply([], arguments); + }); + }, + + _getDroppedFiles: function (dataTransfer) { + // eslint-disable-next-line no-param-reassign + dataTransfer = dataTransfer || {}; + var items = dataTransfer.items; + if ( + items && + items.length && + (items[0].webkitGetAsEntry || items[0].getAsEntry) + ) { + return this._handleFileTreeEntries( + $.map(items, function (item) { + var entry; + if (item.webkitGetAsEntry) { + entry = item.webkitGetAsEntry(); + if (entry) { + // Workaround for Chrome bug #149735: + entry._file = item.getAsFile(); + } + return entry; + } + return item.getAsEntry(); + }) + ); + } + return $.Deferred().resolve($.makeArray(dataTransfer.files)).promise(); + }, + + _getSingleFileInputFiles: function (fileInput) { + // eslint-disable-next-line no-param-reassign + fileInput = $(fileInput); + var entries = + fileInput.prop('webkitEntries') || fileInput.prop('entries'), + files, + value; + if (entries && entries.length) { + return this._handleFileTreeEntries(entries); + } + files = $.makeArray(fileInput.prop('files')); + if (!files.length) { + value = fileInput.prop('value'); + if (!value) { + return $.Deferred().resolve([]).promise(); + } + // If the files property is not available, the browser does not + // support the File API and we add a pseudo File object with + // the input value as name with path information removed: + files = [{ name: value.replace(/^.*\\/, '') }]; + } else if (files[0].name === undefined && files[0].fileName) { + // File normalization for Safari 4 and Firefox 3: + $.each(files, function (index, file) { + file.name = file.fileName; + file.size = file.fileSize; + }); + } + return $.Deferred().resolve(files).promise(); + }, + + _getFileInputFiles: function (fileInput) { + if (!(fileInput instanceof $) || fileInput.length === 1) { + return this._getSingleFileInputFiles(fileInput); + } + return $.when + .apply($, $.map(fileInput, this._getSingleFileInputFiles)) + .then(function () { + return Array.prototype.concat.apply([], arguments); + }); + }, + + _onChange: function (e) { + var that = this, + data = { + fileInput: $(e.target), + form: $(e.target.form) + }; + this._getFileInputFiles(data.fileInput).always(function (files) { + data.files = files; + if (that.options.replaceFileInput) { + that._replaceFileInput(data); + } + if ( + that._trigger( + 'change', + $.Event('change', { delegatedEvent: e }), + data + ) !== false + ) { + that._onAdd(e, data); + } + }); + }, + + _onPaste: function (e) { + var items = + e.originalEvent && + e.originalEvent.clipboardData && + e.originalEvent.clipboardData.items, + data = { files: [] }; + if (items && items.length) { + $.each(items, function (index, item) { + var file = item.getAsFile && item.getAsFile(); + if (file) { + data.files.push(file); + } + }); + if ( + this._trigger( + 'paste', + $.Event('paste', { delegatedEvent: e }), + data + ) !== false + ) { + this._onAdd(e, data); + } + } + }, + + _onDrop: function (e) { + e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer; + var that = this, + dataTransfer = e.dataTransfer, + data = {}; + if (dataTransfer && dataTransfer.files && dataTransfer.files.length) { + e.preventDefault(); + this._getDroppedFiles(dataTransfer).always(function (files) { + data.files = files; + if ( + that._trigger( + 'drop', + $.Event('drop', { delegatedEvent: e }), + data + ) !== false + ) { + that._onAdd(e, data); + } + }); + } + }, + + _onDragOver: getDragHandler('dragover'), + + _onDragEnter: getDragHandler('dragenter'), + + _onDragLeave: getDragHandler('dragleave'), + + _initEventHandlers: function () { + if (this._isXHRUpload(this.options)) { + this._on(this.options.dropZone, { + dragover: this._onDragOver, + drop: this._onDrop, + // event.preventDefault() on dragenter is required for IE10+: + dragenter: this._onDragEnter, + // dragleave is not required, but added for completeness: + dragleave: this._onDragLeave + }); + this._on(this.options.pasteZone, { + paste: this._onPaste + }); + } + if ($.support.fileInput) { + this._on(this.options.fileInput, { + change: this._onChange + }); + } + }, + + _destroyEventHandlers: function () { + this._off(this.options.dropZone, 'dragenter dragleave dragover drop'); + this._off(this.options.pasteZone, 'paste'); + this._off(this.options.fileInput, 'change'); + }, + + _destroy: function () { + this._destroyEventHandlers(); + }, + + _setOption: function (key, value) { + var reinit = $.inArray(key, this._specialOptions) !== -1; + if (reinit) { + this._destroyEventHandlers(); + } + this._super(key, value); + if (reinit) { + this._initSpecialOptions(); + this._initEventHandlers(); + } + }, + + _initSpecialOptions: function () { + var options = this.options; + if (options.fileInput === undefined) { + options.fileInput = this.element.is('input[type="file"]') + ? this.element + : this.element.find('input[type="file"]'); + } else if (!(options.fileInput instanceof $)) { + options.fileInput = $(options.fileInput); + } + if (!(options.dropZone instanceof $)) { + options.dropZone = $(options.dropZone); + } + if (!(options.pasteZone instanceof $)) { + options.pasteZone = $(options.pasteZone); + } + }, + + _getRegExp: function (str) { + var parts = str.split('/'), + modifiers = parts.pop(); + parts.shift(); + return new RegExp(parts.join('/'), modifiers); + }, + + _isRegExpOption: function (key, value) { + return ( + key !== 'url' && + $.type(value) === 'string' && + /^\/.*\/[igm]{0,3}$/.test(value) + ); + }, + + _initDataAttributes: function () { + var that = this, + options = this.options, + data = this.element.data(); + // Initialize options set via HTML5 data-attributes: + $.each(this.element[0].attributes, function (index, attr) { + var key = attr.name.toLowerCase(), + value; + if (/^data-/.test(key)) { + // Convert hyphen-ated key to camelCase: + key = key.slice(5).replace(/-[a-z]/g, function (str) { + return str.charAt(1).toUpperCase(); + }); + value = data[key]; + if (that._isRegExpOption(key, value)) { + value = that._getRegExp(value); + } + options[key] = value; + } + }); + }, + + _create: function () { + this._initDataAttributes(); + this._initSpecialOptions(); + this._slots = []; + this._sequence = this._getXHRPromise(true); + this._sending = this._active = 0; + this._initProgressObject(this); + this._initEventHandlers(); + }, + + // This method is exposed to the widget API and allows to query + // the number of active uploads: + active: function () { + return this._active; + }, + + // This method is exposed to the widget API and allows to query + // the widget upload progress. + // It returns an object with loaded, total and bitrate properties + // for the running uploads: + progress: function () { + return this._progress; + }, + + // This method is exposed to the widget API and allows adding files + // using the fileupload API. The data parameter accepts an object which + // must have a files property and can contain additional options: + // .fileupload('add', {files: filesList}); + add: function (data) { + var that = this; + if (!data || this.options.disabled) { + return; + } + if (data.fileInput && !data.files) { + this._getFileInputFiles(data.fileInput).always(function (files) { + data.files = files; + that._onAdd(null, data); + }); + } else { + data.files = $.makeArray(data.files); + this._onAdd(null, data); + } + }, + + // This method is exposed to the widget API and allows sending files + // using the fileupload API. The data parameter accepts an object which + // must have a files or fileInput property and can contain additional options: + // .fileupload('send', {files: filesList}); + // The method returns a Promise object for the file upload call. + send: function (data) { + if (data && !this.options.disabled) { + if (data.fileInput && !data.files) { + var that = this, + dfd = $.Deferred(), + promise = dfd.promise(), + jqXHR, + aborted; + promise.abort = function () { + aborted = true; + if (jqXHR) { + return jqXHR.abort(); + } + dfd.reject(null, 'abort', 'abort'); + return promise; + }; + this._getFileInputFiles(data.fileInput).always(function (files) { + if (aborted) { + return; + } + if (!files.length) { + dfd.reject(); + return; + } + data.files = files; + jqXHR = that._onSend(null, data); + jqXHR.then( + function (result, textStatus, jqXHR) { + dfd.resolve(result, textStatus, jqXHR); + }, + function (jqXHR, textStatus, errorThrown) { + dfd.reject(jqXHR, textStatus, errorThrown); + } + ); + }); + return this._enhancePromise(promise); + } + data.files = $.makeArray(data.files); + if (data.files.length) { + return this._onSend(null, data); + } + } + return this._getXHRPromise(false, data && data.context); + } + }); +}); diff --git a/vendor/assets/javascripts/jquery.iframe-transport.js b/vendor/assets/javascripts/jquery.iframe-transport.js index b7581f23f4..29cdeaa907 100644 --- a/vendor/assets/javascripts/jquery.iframe-transport.js +++ b/vendor/assets/javascripts/jquery.iframe-transport.js @@ -1,217 +1,221 @@ /* - * jQuery Iframe Transport Plugin 1.8.3 + * jQuery Iframe Transport Plugin * https://github.com/blueimp/jQuery-File-Upload * * Copyright 2011, Sebastian Tschan * https://blueimp.net * * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT + * https://opensource.org/licenses/MIT */ -/* global define, require, window, document */ +/* global define, require */ (function (factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - // Register as an anonymous AMD module: - define(['jquery'], factory); - } else if (typeof exports === 'object') { - // Node/CommonJS: - factory(require('jquery')); - } else { - // Browser globals: - factory(window.jQuery); - } -}(function ($) { - 'use strict'; + 'use strict'; + if (typeof define === 'function' && define.amd) { + // Register as an anonymous AMD module: + define(['jquery'], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS: + factory(require('jquery')); + } else { + // Browser globals: + factory(window.jQuery); + } +})(function ($) { + 'use strict'; - // Helper variable to create unique names for the transport iframes: - var counter = 0; + // Helper variable to create unique names for the transport iframes: + var counter = 0, + jsonAPI = $, + jsonParse = 'parseJSON'; - // The iframe transport accepts four additional options: - // options.fileInput: a jQuery collection of file input fields - // options.paramName: the parameter name for the file form data, - // overrides the name property of the file input field(s), - // can be a string or an array of strings. - // options.formData: an array of objects with name and value properties, - // equivalent to the return data of .serializeArray(), e.g.: - // [{name: 'a', value: 1}, {name: 'b', value: 2}] - // options.initialIframeSrc: the URL of the initial iframe src, - // by default set to "javascript:false;" - $.ajaxTransport('iframe', function (options) { - if (options.async) { - // javascript:false as initial iframe src - // prevents warning popups on HTTPS in IE6: - /*jshint scripturl: true */ - var initialIframeSrc = options.initialIframeSrc || 'javascript:false;', - /*jshint scripturl: false */ - form, - iframe, - addParamChar; - return { - send: function (_, completeCallback) { - form = $('
'); - form.attr('accept-charset', options.formAcceptCharset); - addParamChar = /\?/.test(options.url) ? '&' : '?'; - // XDomainRequest only supports GET and POST: - if (options.type === 'DELETE') { - options.url = options.url + addParamChar + '_method=DELETE'; - options.type = 'POST'; - } else if (options.type === 'PUT') { - options.url = options.url + addParamChar + '_method=PUT'; - options.type = 'POST'; - } else if (options.type === 'PATCH') { - options.url = options.url + addParamChar + '_method=PATCH'; - options.type = 'POST'; - } - // IE versions below IE8 cannot set the name property of - // elements that have already been added to the DOM, - // so we set the name along with the iframe HTML markup: - counter += 1; - iframe = $( - '' - ).bind('load', function () { - var fileInputClones, - paramNames = $.isArray(options.paramName) ? - options.paramName : [options.paramName]; - iframe - .unbind('load') - .bind('load', function () { - var response; - // Wrap in a try/catch block to catch exceptions thrown - // when trying to access cross-domain iframe contents: - try { - response = iframe.contents(); - // Google Chrome and Firefox do not throw an - // exception when calling iframe.contents() on - // cross-domain requests, so we unify the response: - if (!response.length || !response[0].firstChild) { - throw new Error(); - } - } catch (e) { - response = undefined; - } - // The complete callback returns the - // iframe content document as response object: - completeCallback( - 200, - 'success', - {'iframe': response} - ); - // Fix for IE endless progress bar activity bug - // (happens on form submits to iframe targets): - $('') - .appendTo(form); - window.setTimeout(function () { - // Removing the form in a setTimeout call - // allows Chrome's developer tools to display - // the response result - form.remove(); - }, 0); - }); - form - .prop('target', iframe.prop('name')) - .prop('action', options.url) - .prop('method', options.type); - if (options.formData) { - $.each(options.formData, function (index, field) { - $('') - .prop('name', field.name) - .val(field.value) - .appendTo(form); - }); - } - if (options.fileInput && options.fileInput.length && - options.type === 'POST') { - fileInputClones = options.fileInput.clone(); - // Insert a clone for each file input field: - options.fileInput.after(function (index) { - return fileInputClones[index]; - }); - if (options.paramName) { - options.fileInput.each(function (index) { - $(this).prop( - 'name', - paramNames[index] || options.paramName - ); - }); - } - // Appending the file input fields to the hidden form - // removes them from their original location: - form - .append(options.fileInput) - .prop('enctype', 'multipart/form-data') - // enctype must be set as encoding for IE: - .prop('encoding', 'multipart/form-data'); - // Remove the HTML5 form attribute from the input(s): - options.fileInput.removeAttr('form'); - } - form.submit(); - // Insert the file input fields at their original location - // by replacing the clones with the originals: - if (fileInputClones && fileInputClones.length) { - options.fileInput.each(function (index, input) { - var clone = $(fileInputClones[index]); - // Restore the original name and form properties: - $(input) - .prop('name', clone.prop('name')) - .attr('form', clone.attr('form')); - clone.replaceWith(input); - }); - } - }); - form.append(iframe).appendTo(document.body); - }, - abort: function () { - if (iframe) { - // javascript:false as iframe src aborts the request - // and prevents warning popups on HTTPS in IE6. - // concat is used to avoid the "Script URL" JSLint error: - iframe - .unbind('load') - .prop('src', initialIframeSrc); - } - if (form) { - form.remove(); - } + if ('JSON' in window && 'parse' in JSON) { + jsonAPI = JSON; + jsonParse = 'parse'; + } + + // The iframe transport accepts four additional options: + // options.fileInput: a jQuery collection of file input fields + // options.paramName: the parameter name for the file form data, + // overrides the name property of the file input field(s), + // can be a string or an array of strings. + // options.formData: an array of objects with name and value properties, + // equivalent to the return data of .serializeArray(), e.g.: + // [{name: 'a', value: 1}, {name: 'b', value: 2}] + // options.initialIframeSrc: the URL of the initial iframe src, + // by default set to "javascript:false;" + $.ajaxTransport('iframe', function (options) { + if (options.async) { + // javascript:false as initial iframe src + // prevents warning popups on HTTPS in IE6: + // eslint-disable-next-line no-script-url + var initialIframeSrc = options.initialIframeSrc || 'javascript:false;', + form, + iframe, + addParamChar; + return { + send: function (_, completeCallback) { + form = $('
'); + form.attr('accept-charset', options.formAcceptCharset); + addParamChar = /\?/.test(options.url) ? '&' : '?'; + // XDomainRequest only supports GET and POST: + if (options.type === 'DELETE') { + options.url = options.url + addParamChar + '_method=DELETE'; + options.type = 'POST'; + } else if (options.type === 'PUT') { + options.url = options.url + addParamChar + '_method=PUT'; + options.type = 'POST'; + } else if (options.type === 'PATCH') { + options.url = options.url + addParamChar + '_method=PATCH'; + options.type = 'POST'; + } + // IE versions below IE8 cannot set the name property of + // elements that have already been added to the DOM, + // so we set the name along with the iframe HTML markup: + counter += 1; + iframe = $( + '' + ).on('load', function () { + var fileInputClones, + paramNames = $.isArray(options.paramName) + ? options.paramName + : [options.paramName]; + iframe.off('load').on('load', function () { + var response; + // Wrap in a try/catch block to catch exceptions thrown + // when trying to access cross-domain iframe contents: + try { + response = iframe.contents(); + // Google Chrome and Firefox do not throw an + // exception when calling iframe.contents() on + // cross-domain requests, so we unify the response: + if (!response.length || !response[0].firstChild) { + throw new Error(); } - }; - } - }); - - // The iframe transport returns the iframe content document as response. - // The following adds converters from iframe to text, json, html, xml - // and script. - // Please note that the Content-Type for JSON responses has to be text/plain - // or text/html, if the browser doesn't include application/json in the - // Accept header, else IE will show a download dialog. - // The Content-Type for XML responses on the other hand has to be always - // application/xml or text/xml, so IE properly parses the XML response. - // See also - // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation - $.ajaxSetup({ - converters: { - 'iframe text': function (iframe) { - return iframe && $(iframe[0].body).text(); - }, - 'iframe json': function (iframe) { - return iframe && $.parseJSON($(iframe[0].body).text()); - }, - 'iframe html': function (iframe) { - return iframe && $(iframe[0].body).html(); - }, - 'iframe xml': function (iframe) { - var xmlDoc = iframe && iframe[0]; - return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc : - $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) || - $(xmlDoc.body).html()); - }, - 'iframe script': function (iframe) { - return iframe && $.globalEval($(iframe[0].body).text()); + } catch (e) { + response = undefined; + } + // The complete callback returns the + // iframe content document as response object: + completeCallback(200, 'success', { iframe: response }); + // Fix for IE endless progress bar activity bug + // (happens on form submits to iframe targets): + $('').appendTo( + form + ); + window.setTimeout(function () { + // Removing the form in a setTimeout call + // allows Chrome's developer tools to display + // the response result + form.remove(); + }, 0); + }); + form + .prop('target', iframe.prop('name')) + .prop('action', options.url) + .prop('method', options.type); + if (options.formData) { + $.each(options.formData, function (index, field) { + $('') + .prop('name', field.name) + .val(field.value) + .appendTo(form); + }); } + if ( + options.fileInput && + options.fileInput.length && + options.type === 'POST' + ) { + fileInputClones = options.fileInput.clone(); + // Insert a clone for each file input field: + options.fileInput.after(function (index) { + return fileInputClones[index]; + }); + if (options.paramName) { + options.fileInput.each(function (index) { + $(this).prop('name', paramNames[index] || options.paramName); + }); + } + // Appending the file input fields to the hidden form + // removes them from their original location: + form + .append(options.fileInput) + .prop('enctype', 'multipart/form-data') + // enctype must be set as encoding for IE: + .prop('encoding', 'multipart/form-data'); + // Remove the HTML5 form attribute from the input(s): + options.fileInput.removeAttr('form'); + } + form.submit(); + // Insert the file input fields at their original location + // by replacing the clones with the originals: + if (fileInputClones && fileInputClones.length) { + options.fileInput.each(function (index, input) { + var clone = $(fileInputClones[index]); + // Restore the original name and form properties: + $(input) + .prop('name', clone.prop('name')) + .attr('form', clone.attr('form')); + clone.replaceWith(input); + }); + } + }); + form.append(iframe).appendTo(document.body); + }, + abort: function () { + if (iframe) { + // javascript:false as iframe src aborts the request + // and prevents warning popups on HTTPS in IE6. + iframe.off('load').prop('src', initialIframeSrc); + } + if (form) { + form.remove(); + } } - }); + }; + } + }); -})); + // The iframe transport returns the iframe content document as response. + // The following adds converters from iframe to text, json, html, xml + // and script. + // Please note that the Content-Type for JSON responses has to be text/plain + // or text/html, if the browser doesn't include application/json in the + // Accept header, else IE will show a download dialog. + // The Content-Type for XML responses on the other hand has to be always + // application/xml or text/xml, so IE properly parses the XML response. + // See also + // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation + $.ajaxSetup({ + converters: { + 'iframe text': function (iframe) { + return iframe && $(iframe[0].body).text(); + }, + 'iframe json': function (iframe) { + return iframe && jsonAPI[jsonParse]($(iframe[0].body).text()); + }, + 'iframe html': function (iframe) { + return iframe && $(iframe[0].body).html(); + }, + 'iframe xml': function (iframe) { + var xmlDoc = iframe && iframe[0]; + return xmlDoc && $.isXMLDoc(xmlDoc) + ? xmlDoc + : $.parseXML( + (xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) || + $(xmlDoc.body).html() + ); + }, + 'iframe script': function (iframe) { + return iframe && $.globalEval($(iframe[0].body).text()); + } + } + }); +}); diff --git a/vendor/assets/javascripts/jquery.ui.widget.js b/vendor/assets/javascripts/jquery.ui.widget.js index 5ac2ed5a57..69096aaa35 100644 --- a/vendor/assets/javascripts/jquery.ui.widget.js +++ b/vendor/assets/javascripts/jquery.ui.widget.js @@ -1,563 +1,808 @@ -/*! jQuery UI - v1.11.1+CommonJS - 2014-09-17 -* http://jqueryui.com -* Includes: widget.js -* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ - -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "jquery" ], factory ); - - } else if (typeof exports === "object") { - // Node/CommonJS: - factory(require("jquery")); - - } else { - - // Browser globals - factory( jQuery ); - } -}(function( $ ) { -/*! - * jQuery UI Widget 1.11.1 +/*! jQuery UI - v1.12.1+0b7246b6eeadfa9e2696e22f3230f6452f8129dc - 2020-02-20 * http://jqueryui.com - * - * Copyright 2014 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/jQuery.widget/ - */ + * Includes: widget.js + * Copyright jQuery Foundation and other contributors; Licensed MIT */ +/* global define, require */ +/* eslint-disable no-param-reassign, new-cap, jsdoc/require-jsdoc */ -var widget_uuid = 0, - widget_slice = Array.prototype.slice; +(function (factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS + factory(require('jquery')); + } else { + // Browser globals + factory(window.jQuery); + } +})(function ($) { + ('use strict'); -$.cleanData = (function( orig ) { - return function( elems ) { - var events, elem, i; - for ( i = 0; (elem = elems[i]) != null; i++ ) { - try { + $.ui = $.ui || {}; - // Only trigger remove when necessary to save time - events = $._data( elem, "events" ); - if ( events && events.remove ) { - $( elem ).triggerHandler( "remove" ); - } + $.ui.version = '1.12.1'; - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} - } - orig( elems ); - }; -})( $.cleanData ); + /*! + * jQuery UI Widget 1.12.1 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ -$.widget = function( name, base, prototype ) { - var fullName, existingConstructor, constructor, basePrototype, - // proxiedPrototype allows the provided prototype to remain unmodified - // so that it can be used as a mixin for multiple widgets (#8876) - proxiedPrototype = {}, - namespace = name.split( "." )[ 0 ]; + //>>label: Widget + //>>group: Core + //>>description: Provides a factory for creating stateful widgets with a common API. + //>>docs: http://api.jqueryui.com/jQuery.widget/ + //>>demos: http://jqueryui.com/widget/ - name = name.split( "." )[ 1 ]; - fullName = namespace + "-" + name; + // Support: jQuery 1.9.x or older + // $.expr[ ":" ] is deprecated. + if (!$.expr.pseudos) { + $.expr.pseudos = $.expr[':']; + } - if ( !prototype ) { - prototype = base; - base = $.Widget; - } + // Support: jQuery 1.11.x or older + // $.unique has been renamed to $.uniqueSort + if (!$.uniqueSort) { + $.uniqueSort = $.unique; + } - // create selector for plugin - $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { - return !!$.data( elem, fullName ); - }; + var widgetUuid = 0; + var widgetHasOwnProperty = Array.prototype.hasOwnProperty; + var widgetSlice = Array.prototype.slice; - $[ namespace ] = $[ namespace ] || {}; - existingConstructor = $[ namespace ][ name ]; - constructor = $[ namespace ][ name ] = function( options, element ) { - // allow instantiation without "new" keyword - if ( !this._createWidget ) { - return new constructor( options, element ); - } + $.cleanData = (function (orig) { + return function (elems) { + var events, elem, i; + // eslint-disable-next-line eqeqeq + for (i = 0; (elem = elems[i]) != null; i++) { + // Only trigger remove when necessary to save time + events = $._data(elem, 'events'); + if (events && events.remove) { + $(elem).triggerHandler('remove'); + } + } + orig(elems); + }; + })($.cleanData); - // allow instantiation without initializing for simple inheritance - // must use "new" keyword (the code above always passes args) - if ( arguments.length ) { - this._createWidget( options, element ); - } - }; - // extend with the existing constructor to carry over any static properties - $.extend( constructor, existingConstructor, { - version: prototype.version, - // copy the object used to create the prototype in case we need to - // redefine the widget later - _proto: $.extend( {}, prototype ), - // track widgets that inherit from this widget in case this widget is - // redefined after a widget inherits from it - _childConstructors: [] - }); + $.widget = function (name, base, prototype) { + var existingConstructor, constructor, basePrototype; - basePrototype = new base(); - // we need to make the options hash a property directly on the new instance - // otherwise we'll modify the options hash on the prototype that we're - // inheriting from - basePrototype.options = $.widget.extend( {}, basePrototype.options ); - $.each( prototype, function( prop, value ) { - if ( !$.isFunction( value ) ) { - proxiedPrototype[ prop ] = value; - return; - } - proxiedPrototype[ prop ] = (function() { - var _super = function() { - return base.prototype[ prop ].apply( this, arguments ); - }, - _superApply = function( args ) { - return base.prototype[ prop ].apply( this, args ); - }; - return function() { - var __super = this._super, - __superApply = this._superApply, - returnValue; + // ProxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + var proxiedPrototype = {}; - this._super = _super; - this._superApply = _superApply; + var namespace = name.split('.')[0]; + name = name.split('.')[1]; + var fullName = namespace + '-' + name; - returnValue = value.apply( this, arguments ); + if (!prototype) { + prototype = base; + base = $.Widget; + } - this._super = __super; - this._superApply = __superApply; + if ($.isArray(prototype)) { + prototype = $.extend.apply(null, [{}].concat(prototype)); + } - return returnValue; - }; - })(); - }); - constructor.prototype = $.widget.extend( basePrototype, { - // TODO: remove support for widgetEventPrefix - // always use the name + a colon as the prefix, e.g., draggable:start - // don't prefix for widgets that aren't DOM-based - widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name - }, proxiedPrototype, { - constructor: constructor, - namespace: namespace, - widgetName: name, - widgetFullName: fullName - }); + // Create selector for plugin + $.expr.pseudos[fullName.toLowerCase()] = function (elem) { + return !!$.data(elem, fullName); + }; - // If this widget is being redefined then we need to find all widgets that - // are inheriting from it and redefine all of them so that they inherit from - // the new version of this widget. We're essentially trying to replace one - // level in the prototype chain. - if ( existingConstructor ) { - $.each( existingConstructor._childConstructors, function( i, child ) { - var childPrototype = child.prototype; + $[namespace] = $[namespace] || {}; + existingConstructor = $[namespace][name]; + constructor = $[namespace][name] = function (options, element) { + // Allow instantiation without "new" keyword + if (!this._createWidget) { + return new constructor(options, element); + } - // redefine the child widget using the same prototype that was - // originally used, but inherit from the new version of the base - $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); - }); - // remove the list of existing child constructors from the old constructor - // so the old child constructors can be garbage collected - delete existingConstructor._childConstructors; - } else { - base._childConstructors.push( constructor ); - } + // Allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if (arguments.length) { + this._createWidget(options, element); + } + }; - $.widget.bridge( name, constructor ); + // Extend with the existing constructor to carry over any static properties + $.extend(constructor, existingConstructor, { + version: prototype.version, - return constructor; -}; + // Copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend({}, prototype), -$.widget.extend = function( target ) { - var input = widget_slice.call( arguments, 1 ), - inputIndex = 0, - inputLength = input.length, - key, - value; - for ( ; inputIndex < inputLength; inputIndex++ ) { - for ( key in input[ inputIndex ] ) { - value = input[ inputIndex ][ key ]; - if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { - // Clone objects - if ( $.isPlainObject( value ) ) { - target[ key ] = $.isPlainObject( target[ key ] ) ? - $.widget.extend( {}, target[ key ], value ) : - // Don't extend strings, arrays, etc. with objects - $.widget.extend( {}, value ); - // Copy everything else by reference - } else { - target[ key ] = value; - } - } - } - } - return target; -}; + // Track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + }); -$.widget.bridge = function( name, object ) { - var fullName = object.prototype.widgetFullName || name; - $.fn[ name ] = function( options ) { - var isMethodCall = typeof options === "string", - args = widget_slice.call( arguments, 1 ), - returnValue = this; + basePrototype = new base(); - // allow multiple hashes to be passed on init - options = !isMethodCall && args.length ? - $.widget.extend.apply( null, [ options ].concat(args) ) : - options; + // We need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from + basePrototype.options = $.widget.extend({}, basePrototype.options); + $.each(prototype, function (prop, value) { + if (!$.isFunction(value)) { + proxiedPrototype[prop] = value; + return; + } + proxiedPrototype[prop] = (function () { + function _super() { + return base.prototype[prop].apply(this, arguments); + } - if ( isMethodCall ) { - this.each(function() { - var methodValue, - instance = $.data( this, fullName ); - if ( options === "instance" ) { - returnValue = instance; - return false; - } - if ( !instance ) { - return $.error( "cannot call methods on " + name + " prior to initialization; " + - "attempted to call method '" + options + "'" ); - } - if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { - return $.error( "no such method '" + options + "' for " + name + " widget instance" ); - } - methodValue = instance[ options ].apply( instance, args ); - if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue && methodValue.jquery ? - returnValue.pushStack( methodValue.get() ) : - methodValue; - return false; - } - }); - } else { - this.each(function() { - var instance = $.data( this, fullName ); - if ( instance ) { - instance.option( options || {} ); - if ( instance._init ) { - instance._init(); - } - } else { - $.data( this, fullName, new object( options, this ) ); - } - }); - } + function _superApply(args) { + return base.prototype[prop].apply(this, args); + } - return returnValue; - }; -}; + return function () { + var __super = this._super; + var __superApply = this._superApply; + var returnValue; -$.Widget = function( /* options, element */ ) {}; -$.Widget._childConstructors = []; + this._super = _super; + this._superApply = _superApply; -$.Widget.prototype = { - widgetName: "widget", - widgetEventPrefix: "", - defaultElement: "
", - options: { - disabled: false, + returnValue = value.apply(this, arguments); - // callbacks - create: null - }, - _createWidget: function( options, element ) { - element = $( element || this.defaultElement || this )[ 0 ]; - this.element = $( element ); - this.uuid = widget_uuid++; - this.eventNamespace = "." + this.widgetName + this.uuid; - this.options = $.widget.extend( {}, - this.options, - this._getCreateOptions(), - options ); + this._super = __super; + this._superApply = __superApply; - this.bindings = $(); - this.hoverable = $(); - this.focusable = $(); + return returnValue; + }; + })(); + }); + constructor.prototype = $.widget.extend( + basePrototype, + { + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: existingConstructor + ? basePrototype.widgetEventPrefix || name + : name + }, + proxiedPrototype, + { + constructor: constructor, + namespace: namespace, + widgetName: name, + widgetFullName: fullName + } + ); - if ( element !== this ) { - $.data( element, this.widgetFullName, this ); - this._on( true, this.element, { - remove: function( event ) { - if ( event.target === element ) { - this.destroy(); - } - } - }); - this.document = $( element.style ? - // element within the document - element.ownerDocument : - // element is window or document - element.document || element ); - this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); - } + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if (existingConstructor) { + $.each(existingConstructor._childConstructors, function (i, child) { + var childPrototype = child.prototype; - this._create(); - this._trigger( "create", null, this._getCreateEventData() ); - this._init(); - }, - _getCreateOptions: $.noop, - _getCreateEventData: $.noop, - _create: $.noop, - _init: $.noop, + // Redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( + childPrototype.namespace + '.' + childPrototype.widgetName, + constructor, + child._proto + ); + }); - destroy: function() { - this._destroy(); - // we can probably remove the unbind calls in 2.0 - // all event bindings should go through this._on() - this.element - .unbind( this.eventNamespace ) - .removeData( this.widgetFullName ) - // support: jquery <1.6.3 - // http://bugs.jquery.com/ticket/9413 - .removeData( $.camelCase( this.widgetFullName ) ); - this.widget() - .unbind( this.eventNamespace ) - .removeAttr( "aria-disabled" ) - .removeClass( - this.widgetFullName + "-disabled " + - "ui-state-disabled" ); + // Remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push(constructor); + } - // clean up events and states - this.bindings.unbind( this.eventNamespace ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - }, - _destroy: $.noop, + $.widget.bridge(name, constructor); - widget: function() { - return this.element; - }, + return constructor; + }; - option: function( key, value ) { - var options = key, - parts, - curOption, - i; + $.widget.extend = function (target) { + var input = widgetSlice.call(arguments, 1); + var inputIndex = 0; + var inputLength = input.length; + var key; + var value; - if ( arguments.length === 0 ) { - // don't return a reference to the internal hash - return $.widget.extend( {}, this.options ); - } + for (; inputIndex < inputLength; inputIndex++) { + for (key in input[inputIndex]) { + value = input[inputIndex][key]; + if ( + widgetHasOwnProperty.call(input[inputIndex], key) && + value !== undefined + ) { + // Clone objects + if ($.isPlainObject(value)) { + target[key] = $.isPlainObject(target[key]) + ? $.widget.extend({}, target[key], value) + : // Don't extend strings, arrays, etc. with objects + $.widget.extend({}, value); - if ( typeof key === "string" ) { - // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } - options = {}; - parts = key.split( "." ); - key = parts.shift(); - if ( parts.length ) { - curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); - for ( i = 0; i < parts.length - 1; i++ ) { - curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; - curOption = curOption[ parts[ i ] ]; - } - key = parts.pop(); - if ( arguments.length === 1 ) { - return curOption[ key ] === undefined ? null : curOption[ key ]; - } - curOption[ key ] = value; - } else { - if ( arguments.length === 1 ) { - return this.options[ key ] === undefined ? null : this.options[ key ]; - } - options[ key ] = value; - } - } + // Copy everything else by reference + } else { + target[key] = value; + } + } + } + } + return target; + }; - this._setOptions( options ); + $.widget.bridge = function (name, object) { + var fullName = object.prototype.widgetFullName || name; + $.fn[name] = function (options) { + var isMethodCall = typeof options === 'string'; + var args = widgetSlice.call(arguments, 1); + var returnValue = this; - return this; - }, - _setOptions: function( options ) { - var key; + if (isMethodCall) { + // If this is an empty collection, we need to have the instance method + // return undefined instead of the jQuery instance + if (!this.length && options === 'instance') { + returnValue = undefined; + } else { + this.each(function () { + var methodValue; + var instance = $.data(this, fullName); - for ( key in options ) { - this._setOption( key, options[ key ] ); - } + if (options === 'instance') { + returnValue = instance; + return false; + } - return this; - }, - _setOption: function( key, value ) { - this.options[ key ] = value; + if (!instance) { + return $.error( + 'cannot call methods on ' + + name + + ' prior to initialization; ' + + "attempted to call method '" + + options + + "'" + ); + } - if ( key === "disabled" ) { - this.widget() - .toggleClass( this.widgetFullName + "-disabled", !!value ); + if (!$.isFunction(instance[options]) || options.charAt(0) === '_') { + return $.error( + "no such method '" + + options + + "' for " + + name + + ' widget instance' + ); + } - // If the widget is becoming disabled, then nothing is interactive - if ( value ) { - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - } - } + methodValue = instance[options].apply(instance, args); - return this; - }, + if (methodValue !== instance && methodValue !== undefined) { + returnValue = + methodValue && methodValue.jquery + ? returnValue.pushStack(methodValue.get()) + : methodValue; + return false; + } + }); + } + } else { + // Allow multiple hashes to be passed on init + if (args.length) { + options = $.widget.extend.apply(null, [options].concat(args)); + } - enable: function() { - return this._setOptions({ disabled: false }); - }, - disable: function() { - return this._setOptions({ disabled: true }); - }, + this.each(function () { + var instance = $.data(this, fullName); + if (instance) { + instance.option(options || {}); + if (instance._init) { + instance._init(); + } + } else { + $.data(this, fullName, new object(options, this)); + } + }); + } - _on: function( suppressDisabledCheck, element, handlers ) { - var delegateElement, - instance = this; + return returnValue; + }; + }; - // no suppressDisabledCheck flag, shuffle arguments - if ( typeof suppressDisabledCheck !== "boolean" ) { - handlers = element; - element = suppressDisabledCheck; - suppressDisabledCheck = false; - } + $.Widget = function (/* options, element */) {}; + $.Widget._childConstructors = []; - // no element argument, shuffle and use this.element - if ( !handlers ) { - handlers = element; - element = this.element; - delegateElement = this.widget(); - } else { - element = delegateElement = $( element ); - this.bindings = this.bindings.add( element ); - } + $.Widget.prototype = { + widgetName: 'widget', + widgetEventPrefix: '', + defaultElement: '
', - $.each( handlers, function( event, handler ) { - function handlerProxy() { - // allow widgets to customize the disabled handling - // - disabled as an array instead of boolean - // - disabled class as method for disabling individual parts - if ( !suppressDisabledCheck && - ( instance.options.disabled === true || - $( this ).hasClass( "ui-state-disabled" ) ) ) { - return; - } - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } + options: { + classes: {}, + disabled: false, - // copy the guid so direct unbinding works - if ( typeof handler !== "string" ) { - handlerProxy.guid = handler.guid = - handler.guid || handlerProxy.guid || $.guid++; - } + // Callbacks + create: null + }, - var match = event.match( /^([\w:-]*)\s*(.*)$/ ), - eventName = match[1] + instance.eventNamespace, - selector = match[2]; - if ( selector ) { - delegateElement.delegate( selector, eventName, handlerProxy ); - } else { - element.bind( eventName, handlerProxy ); - } - }); - }, + _createWidget: function (options, element) { + element = $(element || this.defaultElement || this)[0]; + this.element = $(element); + this.uuid = widgetUuid++; + this.eventNamespace = '.' + this.widgetName + this.uuid; - _off: function( element, eventName ) { - eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; - element.unbind( eventName ).undelegate( eventName ); - }, + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + this.classesElementLookup = {}; - _delay: function( handler, delay ) { - function handlerProxy() { - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - var instance = this; - return setTimeout( handlerProxy, delay || 0 ); - }, + if (element !== this) { + $.data(element, this.widgetFullName, this); + this._on(true, this.element, { + remove: function (event) { + if (event.target === element) { + this.destroy(); + } + } + }); + this.document = $( + element.style + ? // Element within the document + element.ownerDocument + : // Element is window or document + element.document || element + ); + this.window = $( + this.document[0].defaultView || this.document[0].parentWindow + ); + } - _hoverable: function( element ) { - this.hoverable = this.hoverable.add( element ); - this._on( element, { - mouseenter: function( event ) { - $( event.currentTarget ).addClass( "ui-state-hover" ); - }, - mouseleave: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-hover" ); - } - }); - }, + this.options = $.widget.extend( + {}, + this.options, + this._getCreateOptions(), + options + ); - _focusable: function( element ) { - this.focusable = this.focusable.add( element ); - this._on( element, { - focusin: function( event ) { - $( event.currentTarget ).addClass( "ui-state-focus" ); - }, - focusout: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-focus" ); - } - }); - }, + this._create(); - _trigger: function( type, event, data ) { - var prop, orig, - callback = this.options[ type ]; + if (this.options.disabled) { + this._setOptionDisabled(this.options.disabled); + } - data = data || {}; - event = $.Event( event ); - event.type = ( type === this.widgetEventPrefix ? - type : - this.widgetEventPrefix + type ).toLowerCase(); - // the original event may come from any element - // so we need to reset the target on the new event - event.target = this.element[ 0 ]; + this._trigger('create', null, this._getCreateEventData()); + this._init(); + }, - // copy original event properties over to the new event - orig = event.originalEvent; - if ( orig ) { - for ( prop in orig ) { - if ( !( prop in event ) ) { - event[ prop ] = orig[ prop ]; - } - } - } + _getCreateOptions: function () { + return {}; + }, - this.element.trigger( event, data ); - return !( $.isFunction( callback ) && - callback.apply( this.element[0], [ event ].concat( data ) ) === false || - event.isDefaultPrevented() ); - } -}; + _getCreateEventData: $.noop, -$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { - $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { - if ( typeof options === "string" ) { - options = { effect: options }; - } - var hasOptions, - effectName = !options ? - method : - options === true || typeof options === "number" ? - defaultEffect : - options.effect || defaultEffect; - options = options || {}; - if ( typeof options === "number" ) { - options = { duration: options }; - } - hasOptions = !$.isEmptyObject( options ); - options.complete = callback; - if ( options.delay ) { - element.delay( options.delay ); - } - if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { - element[ method ]( options ); - } else if ( effectName !== method && element[ effectName ] ) { - element[ effectName ]( options.duration, options.easing, callback ); - } else { - element.queue(function( next ) { - $( this )[ method ](); - if ( callback ) { - callback.call( element[ 0 ] ); - } - next(); - }); - } - }; + _create: $.noop, + + _init: $.noop, + + destroy: function () { + var that = this; + + this._destroy(); + $.each(this.classesElementLookup, function (key, value) { + that._removeClass(value, key); + }); + + // We can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element.off(this.eventNamespace).removeData(this.widgetFullName); + this.widget().off(this.eventNamespace).removeAttr('aria-disabled'); + + // Clean up events and states + this.bindings.off(this.eventNamespace); + }, + + _destroy: $.noop, + + widget: function () { + return this.element; + }, + + option: function (key, value) { + var options = key; + var parts; + var curOption; + var i; + + if (arguments.length === 0) { + // Don't return a reference to the internal hash + return $.widget.extend({}, this.options); + } + + if (typeof key === 'string') { + // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split('.'); + key = parts.shift(); + if (parts.length) { + curOption = options[key] = $.widget.extend({}, this.options[key]); + for (i = 0; i < parts.length - 1; i++) { + curOption[parts[i]] = curOption[parts[i]] || {}; + curOption = curOption[parts[i]]; + } + key = parts.pop(); + if (arguments.length === 1) { + return curOption[key] === undefined ? null : curOption[key]; + } + curOption[key] = value; + } else { + if (arguments.length === 1) { + return this.options[key] === undefined ? null : this.options[key]; + } + options[key] = value; + } + } + + this._setOptions(options); + + return this; + }, + + _setOptions: function (options) { + var key; + + for (key in options) { + this._setOption(key, options[key]); + } + + return this; + }, + + _setOption: function (key, value) { + if (key === 'classes') { + this._setOptionClasses(value); + } + + this.options[key] = value; + + if (key === 'disabled') { + this._setOptionDisabled(value); + } + + return this; + }, + + _setOptionClasses: function (value) { + var classKey, elements, currentElements; + + for (classKey in value) { + currentElements = this.classesElementLookup[classKey]; + if ( + value[classKey] === this.options.classes[classKey] || + !currentElements || + !currentElements.length + ) { + continue; + } + + // We are doing this to create a new jQuery object because the _removeClass() call + // on the next line is going to destroy the reference to the current elements being + // tracked. We need to save a copy of this collection so that we can add the new classes + // below. + elements = $(currentElements.get()); + this._removeClass(currentElements, classKey); + + // We don't use _addClass() here, because that uses this.options.classes + // for generating the string of classes. We want to use the value passed in from + // _setOption(), this is the new value of the classes option which was passed to + // _setOption(). We pass this value directly to _classes(). + elements.addClass( + this._classes({ + element: elements, + keys: classKey, + classes: value, + add: true + }) + ); + } + }, + + _setOptionDisabled: function (value) { + this._toggleClass( + this.widget(), + this.widgetFullName + '-disabled', + null, + !!value + ); + + // If the widget is becoming disabled, then nothing is interactive + if (value) { + this._removeClass(this.hoverable, null, 'ui-state-hover'); + this._removeClass(this.focusable, null, 'ui-state-focus'); + } + }, + + enable: function () { + return this._setOptions({ disabled: false }); + }, + + disable: function () { + return this._setOptions({ disabled: true }); + }, + + _classes: function (options) { + var full = []; + var that = this; + + options = $.extend( + { + element: this.element, + classes: this.options.classes || {} + }, + options + ); + + function bindRemoveEvent() { + options.element.each(function (_, element) { + var isTracked = $.map(that.classesElementLookup, function (elements) { + return elements; + }).some(function (elements) { + return elements.is(element); + }); + + if (!isTracked) { + that._on($(element), { + remove: '_untrackClassesElement' + }); + } + }); + } + + function processClassString(classes, checkOption) { + var current, i; + for (i = 0; i < classes.length; i++) { + current = that.classesElementLookup[classes[i]] || $(); + if (options.add) { + bindRemoveEvent(); + current = $( + $.uniqueSort(current.get().concat(options.element.get())) + ); + } else { + current = $(current.not(options.element).get()); + } + that.classesElementLookup[classes[i]] = current; + full.push(classes[i]); + if (checkOption && options.classes[classes[i]]) { + full.push(options.classes[classes[i]]); + } + } + } + + if (options.keys) { + processClassString(options.keys.match(/\S+/g) || [], true); + } + if (options.extra) { + processClassString(options.extra.match(/\S+/g) || []); + } + + return full.join(' '); + }, + + _untrackClassesElement: function (event) { + var that = this; + $.each(that.classesElementLookup, function (key, value) { + if ($.inArray(event.target, value) !== -1) { + that.classesElementLookup[key] = $(value.not(event.target).get()); + } + }); + + this._off($(event.target)); + }, + + _removeClass: function (element, keys, extra) { + return this._toggleClass(element, keys, extra, false); + }, + + _addClass: function (element, keys, extra) { + return this._toggleClass(element, keys, extra, true); + }, + + _toggleClass: function (element, keys, extra, add) { + add = typeof add === 'boolean' ? add : extra; + var shift = typeof element === 'string' || element === null, + options = { + extra: shift ? keys : extra, + keys: shift ? element : keys, + element: shift ? this.element : element, + add: add + }; + options.element.toggleClass(this._classes(options), add); + return this; + }, + + _on: function (suppressDisabledCheck, element, handlers) { + var delegateElement; + var instance = this; + + // No suppressDisabledCheck flag, shuffle arguments + if (typeof suppressDisabledCheck !== 'boolean') { + handlers = element; + element = suppressDisabledCheck; + suppressDisabledCheck = false; + } + + // No element argument, shuffle and use this.element + if (!handlers) { + handlers = element; + element = this.element; + delegateElement = this.widget(); + } else { + element = delegateElement = $(element); + this.bindings = this.bindings.add(element); + } + + $.each(handlers, function (event, handler) { + function handlerProxy() { + // Allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( + !suppressDisabledCheck && + (instance.options.disabled === true || + $(this).hasClass('ui-state-disabled')) + ) { + return; + } + return (typeof handler === 'string' + ? instance[handler] + : handler + ).apply(instance, arguments); + } + + // Copy the guid so direct unbinding works + if (typeof handler !== 'string') { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match(/^([\w:-]*)\s*(.*)$/); + var eventName = match[1] + instance.eventNamespace; + var selector = match[2]; + + if (selector) { + delegateElement.on(eventName, selector, handlerProxy); + } else { + element.on(eventName, handlerProxy); + } + }); + }, + + _off: function (element, eventName) { + eventName = + (eventName || '').split(' ').join(this.eventNamespace + ' ') + + this.eventNamespace; + element.off(eventName); + + // Clear the stack to avoid memory leaks (#10056) + this.bindings = $(this.bindings.not(element).get()); + this.focusable = $(this.focusable.not(element).get()); + this.hoverable = $(this.hoverable.not(element).get()); + }, + + _delay: function (handler, delay) { + var instance = this; + function handlerProxy() { + return (typeof handler === 'string' + ? instance[handler] + : handler + ).apply(instance, arguments); + } + return setTimeout(handlerProxy, delay || 0); + }, + + _hoverable: function (element) { + this.hoverable = this.hoverable.add(element); + this._on(element, { + mouseenter: function (event) { + this._addClass($(event.currentTarget), null, 'ui-state-hover'); + }, + mouseleave: function (event) { + this._removeClass($(event.currentTarget), null, 'ui-state-hover'); + } + }); + }, + + _focusable: function (element) { + this.focusable = this.focusable.add(element); + this._on(element, { + focusin: function (event) { + this._addClass($(event.currentTarget), null, 'ui-state-focus'); + }, + focusout: function (event) { + this._removeClass($(event.currentTarget), null, 'ui-state-focus'); + } + }); + }, + + _trigger: function (type, event, data) { + var prop, orig; + var callback = this.options[type]; + + data = data || {}; + event = $.Event(event); + event.type = (type === this.widgetEventPrefix + ? type + : this.widgetEventPrefix + type + ).toLowerCase(); + + // The original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[0]; + + // Copy original event properties over to the new event + orig = event.originalEvent; + if (orig) { + for (prop in orig) { + if (!(prop in event)) { + event[prop] = orig[prop]; + } + } + } + + this.element.trigger(event, data); + return !( + ($.isFunction(callback) && + callback.apply(this.element[0], [event].concat(data)) === false) || + event.isDefaultPrevented() + ); + } + }; + + $.each({ show: 'fadeIn', hide: 'fadeOut' }, function (method, defaultEffect) { + $.Widget.prototype['_' + method] = function (element, options, callback) { + if (typeof options === 'string') { + options = { effect: options }; + } + + var hasOptions; + var effectName = !options + ? method + : options === true || typeof options === 'number' + ? defaultEffect + : options.effect || defaultEffect; + + options = options || {}; + if (typeof options === 'number') { + options = { duration: options }; + } + + hasOptions = !$.isEmptyObject(options); + options.complete = callback; + + if (options.delay) { + element.delay(options.delay); + } + + if (hasOptions && $.effects && $.effects.effect[effectName]) { + element[method](options); + } else if (effectName !== method && element[effectName]) { + element[effectName](options.duration, options.easing, callback); + } else { + element.queue(function (next) { + $(this)[method](); + if (callback) { + callback.call(element[0]); + } + next(); + }); + } + }; + }); }); - -var widget = $.widget; - - - -})); diff --git a/vendor/assets/svg-icons/discourse-additional.svg b/vendor/assets/svg-icons/discourse-additional.svg index e3adf58e0c..343b5b6abc 100644 --- a/vendor/assets/svg-icons/discourse-additional.svg +++ b/vendor/assets/svg-icons/discourse-additional.svg @@ -27,13 +27,4 @@ Additional SVG icons - - - - - - - - - diff --git a/yarn.lock b/yarn.lock index 978b1d5d15..742a3bd36e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -415,6 +415,30 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" +blueimp-canvas-to-blob@3: + version "3.19.0" + resolved "https://registry.yarnpkg.com/blueimp-canvas-to-blob/-/blueimp-canvas-to-blob-3.19.0.tgz#842a30605c59ec12b1219bb3d8969160e27b6f8e" + integrity sha512-WlLp3GOEdpyQr5hqyPaRoFHGdzMcf6T5Wr8ZjjGl1MM4tit6+rCsJcw7psXFvgoIk69uCGEhyvZOWXU2b4bDcQ== + +blueimp-file-upload@10.13.0: + version "10.13.0" + resolved "https://registry.yarnpkg.com/blueimp-file-upload/-/blueimp-file-upload-10.13.0.tgz#3994d1606caa44197e4aa29d7f7e1cdd6f521568" + integrity sha512-N0yIt/5oR0ZioBaj6u8YuCRSp+1doaJOnNJHIYHBHZdrcWfjfc9Xq03nzodkSdbQIRfWwNin5rexUwY203V35g== + optionalDependencies: + blueimp-canvas-to-blob "3" + blueimp-load-image "3" + blueimp-tmpl "3" + +blueimp-load-image@3: + version "3.0.0" + resolved "https://registry.yarnpkg.com/blueimp-load-image/-/blueimp-load-image-3.0.0.tgz#d71c39440a7d2f1a83e3e86a625e329116a51705" + integrity sha512-Q9rFbd4ZUNvzSFmRXx9MoG0RwWwJeMjjEUbG7WIOJgUg22Jgkow0wL5b35B6qwiBscxACW9OHdrP5s2vQ3x8DQ== + +blueimp-tmpl@3: + version "3.14.0" + resolved "https://registry.yarnpkg.com/blueimp-tmpl/-/blueimp-tmpl-3.14.0.tgz#4951cf03a127521fa88922db616949d75cbbd5c3" + integrity sha512-mA8iwfEVkvpjtBXpRp25DxGqW2YOZqC9FVLLOa03Qwdsd6J4kVyL1noC04arAm0CNsu3Y0FmxkAOt+x2MoxpYA== + bootbox@3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/bootbox/-/bootbox-3.2.0.tgz#00bf643fc9edefd9ae1e7c648c6b022db4be0aee" @@ -945,10 +969,10 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -eslint-config-discourse@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-discourse/-/eslint-config-discourse-1.1.0.tgz#1f2b1ffd6064c579bc74eca63420bd3cd5732950" - integrity sha512-y2osWnbIi/CS2hDm61K6vdYA5vEuFJRetI2UFlEo8rQCx2t46XUd+FkgAvBy0nzLSm7ELBKru5qYKveKFF6eAg== +eslint-config-discourse@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/eslint-config-discourse/-/eslint-config-discourse-1.1.1.tgz#8a7f7f6f1a388b0e88f5b79145ae2a8b4a13e3d4" + integrity sha512-b3dp9DOcXYWkPQpXms/bMDy0Scb6DO/nZAAsl5I9yTNhtkx96zZMTp9QEyC8QaCXOTUpIXEE6V+Mpyjtsk3gWg== dependencies: babel-eslint "^8.2" eslint "^4.19"