-
+
+ { this.renderIntervalSelector() }
- { this.state.showCharts.map( chart => {
- return ! chart.show ? null : (
-
-
-
+ { uniqCharts.map( chart => {
+ return hiddenChartKeys.includes( chart.key ) ? null : (
+
);
} ) }
@@ -127,4 +209,22 @@ DashboardCharts.propTypes = {
query: PropTypes.object.isRequired,
};
-export default DashboardCharts;
+export default compose(
+ withSelect( select => {
+ const { getCurrentUserData } = select( 'wc-api' );
+ const userData = getCurrentUserData();
+
+ return {
+ userPrefCharts: userData.dashboard_charts,
+ userPrefChartType: userData.dashboard_chart_type,
+ userPrefChartInterval: userData.dashboard_chart_interval,
+ };
+ } ),
+ withDispatch( dispatch => {
+ const { updateCurrentUserData } = dispatch( 'wc-api' );
+
+ return {
+ updateCurrentUserData,
+ };
+ } )
+)( DashboardCharts );
diff --git a/plugins/woocommerce-admin/client/dashboard/index.js b/plugins/woocommerce-admin/client/dashboard/index.js
index dc81e1ede9e..bd200f5efdc 100644
--- a/plugins/woocommerce-admin/client/dashboard/index.js
+++ b/plugins/woocommerce-admin/client/dashboard/index.js
@@ -9,11 +9,11 @@ import { Component, Fragment } from '@wordpress/element';
* Internal dependencies
*/
import './style.scss';
-import Header from 'header';
-import StorePerformance from './store-performance';
-import TopSellingProducts from './top-selling-products';
import DashboardCharts from './dashboard-charts';
+import Header from 'header';
+import Leaderboards from './leaderboards';
import { ReportFilters } from '@woocommerce/components';
+import StorePerformance from './store-performance';
export default class Dashboard extends Component {
render() {
@@ -23,11 +23,7 @@ export default class Dashboard extends Component {
-
+
);
diff --git a/plugins/woocommerce-admin/client/dashboard/leaderboards/index.js b/plugins/woocommerce-admin/client/dashboard/leaderboards/index.js
new file mode 100644
index 00000000000..522d5fdb73a
--- /dev/null
+++ b/plugins/woocommerce-admin/client/dashboard/leaderboards/index.js
@@ -0,0 +1,165 @@
+/** @format */
+/**
+ * External dependencies
+ */
+import { __ } from '@wordpress/i18n';
+import { Component, Fragment } from '@wordpress/element';
+import { compose } from '@wordpress/compose';
+import { isEqual, xor } from 'lodash';
+import PropTypes from 'prop-types';
+import { SelectControl, ToggleControl } from '@wordpress/components';
+import { withDispatch } from '@wordpress/data';
+
+/**
+ * WooCommerce dependencies
+ */
+import { EllipsisMenu, MenuItem, MenuTitle, SectionHeader } from '@woocommerce/components';
+
+/**
+ * Internal dependencies
+ */
+import withSelect from 'wc-api/with-select';
+import TopSellingProducts from './top-selling-products';
+import './style.scss';
+
+class Leaderboards extends Component {
+ constructor( props ) {
+ super( ...arguments );
+ this.state = {
+ hiddenLeaderboardKeys: props.userPrefLeaderboards || [],
+ rowsPerTable: props.userPrefLeaderboardRows || 5,
+ };
+
+ this.toggle = this.toggle.bind( this );
+ }
+
+ componentDidUpdate( {
+ userPrefLeaderboardRows: prevUserPrefLeaderboardRows,
+ userPrefLeaderboards: prevUserPrefLeaderboards,
+ } ) {
+ const { userPrefLeaderboardRows, userPrefLeaderboards } = this.props;
+ if ( userPrefLeaderboards && ! isEqual( userPrefLeaderboards, prevUserPrefLeaderboards ) ) {
+ /* eslint-disable react/no-did-update-set-state */
+ this.setState( {
+ hiddenLeaderboardKeys: userPrefLeaderboards,
+ } );
+ /* eslint-enable react/no-did-update-set-state */
+ }
+ if (
+ userPrefLeaderboardRows &&
+ parseInt( userPrefLeaderboardRows ) !== parseInt( prevUserPrefLeaderboardRows )
+ ) {
+ /* eslint-disable react/no-did-update-set-state */
+ this.setState( {
+ rowsPerTable: parseInt( userPrefLeaderboardRows ),
+ } );
+ /* eslint-enable react/no-did-update-set-state */
+ }
+ }
+
+ toggle( key ) {
+ return () => {
+ const hiddenLeaderboardKeys = xor( this.state.hiddenLeaderboardKeys, [ key ] );
+ this.setState( { hiddenLeaderboardKeys } );
+ const userDataFields = {
+ [ 'dashboard_leaderboards' ]: hiddenLeaderboardKeys,
+ };
+ this.props.updateCurrentUserData( userDataFields );
+ };
+ }
+
+ setRowsPerTable = rows => {
+ this.setState( { rowsPerTable: parseInt( rows ) } );
+ const userDataFields = {
+ [ 'dashboard_leaderboard_rows' ]: parseInt( rows ),
+ };
+ this.props.updateCurrentUserData( userDataFields );
+ };
+
+ renderMenu() {
+ const { hiddenLeaderboardKeys, rowsPerTable } = this.state;
+ const allLeaderboards = [
+ {
+ key: 'top-products',
+ label: __( 'Top Products', 'wc-admin' ),
+ },
+ {
+ key: 'top-categories',
+ label: __( 'Top Categories', 'wc-admin' ),
+ },
+ {
+ key: 'top-coupons',
+ label: __( 'Top Coupons', 'wc-admin' ),
+ },
+ ];
+ return (
+
+
+ { __( 'Leaderboards', 'wc-admin' ) }
+ { allLeaderboards.map( leaderboard => {
+ return (
+
+ );
+ } ) }
+ { __( 'Rows Per Table', 'wc-admin' ) }
+ ( {
+ v: key + 1,
+ label: key + 1,
+ } ) ) }
+ onChange={ this.setRowsPerTable }
+ />
+
+
+ );
+ }
+
+ render() {
+ const { hiddenLeaderboardKeys, rowsPerTable } = this.state;
+ return (
+
+
+
+
+
+ { ! hiddenLeaderboardKeys.includes( 'top-products' ) && (
+
+ ) }
+
+
+
+
+ );
+ }
+}
+
+Leaderboards.propTypes = {
+ query: PropTypes.object.isRequired,
+};
+
+export default compose(
+ withSelect( select => {
+ const { getCurrentUserData } = select( 'wc-api' );
+ const userData = getCurrentUserData();
+
+ return {
+ userPrefLeaderboards: userData.dashboard_leaderboards,
+ userPrefLeaderboardRows: userData.dashboard_leaderboard_rows,
+ };
+ } ),
+ withDispatch( dispatch => {
+ const { updateCurrentUserData } = dispatch( 'wc-api' );
+
+ return {
+ updateCurrentUserData,
+ };
+ } )
+)( Leaderboards );
diff --git a/plugins/woocommerce-admin/client/dashboard/leaderboards/style.scss b/plugins/woocommerce-admin/client/dashboard/leaderboards/style.scss
new file mode 100644
index 00000000000..20c743c5647
--- /dev/null
+++ b/plugins/woocommerce-admin/client/dashboard/leaderboards/style.scss
@@ -0,0 +1,11 @@
+/** @format */
+
+.woocommerce-dashboard__dashboard-leaderboards {
+ .components-base-control__field {
+ width: 100%;
+ }
+ .components-select-control__input {
+ border: 1px solid $core-grey-light-700;
+ height: 34px;
+ }
+}
diff --git a/plugins/woocommerce-admin/client/dashboard/top-selling-products/index.js b/plugins/woocommerce-admin/client/dashboard/leaderboards/top-selling-products.js
similarity index 93%
rename from plugins/woocommerce-admin/client/dashboard/top-selling-products/index.js
rename to plugins/woocommerce-admin/client/dashboard/leaderboards/top-selling-products.js
index 5732ede5303..4deb1c280b6 100644
--- a/plugins/woocommerce-admin/client/dashboard/top-selling-products/index.js
+++ b/plugins/woocommerce-admin/client/dashboard/leaderboards/top-selling-products.js
@@ -16,7 +16,7 @@ import { getAdminLink } from '@woocommerce/navigation';
* Internal dependencies
*/
import { numberFormat } from 'lib/number';
-import Leaderboard from 'dashboard/leaderboard';
+import Leaderboard from 'analytics/components/leaderboard';
export class TopSellingProducts extends Component {
constructor( props ) {
@@ -88,10 +88,11 @@ export class TopSellingProducts extends Component {
}
render() {
+ const { query, totalRows } = this.props;
const tableQuery = {
orderby: 'items_sold',
order: 'desc',
- per_page: 5, //TODO replace with user configured leaderboard per page value.
+ per_page: totalRows,
extended_info: true,
};
@@ -100,7 +101,7 @@ export class TopSellingProducts extends Component {
endpoint="products"
getHeadersContent={ this.getHeadersContent }
getRowsContent={ this.getRowsContent }
- query={ this.props.query }
+ query={ query }
tableQuery={ tableQuery }
title={ __( 'Top Selling Products', 'wc-admin' ) }
/>
diff --git a/plugins/woocommerce-admin/client/dashboard/style.scss b/plugins/woocommerce-admin/client/dashboard/style.scss
index b55c4093a3d..1a2701f8ac1 100644
--- a/plugins/woocommerce-admin/client/dashboard/style.scss
+++ b/plugins/woocommerce-admin/client/dashboard/style.scss
@@ -2,11 +2,11 @@
.woocommerce-dashboard__columns {
display: grid;
- grid-template-columns: 1fr 1fr;
+ grid-template-columns: calc(50% - #{$gap-large/2}) calc(50% - #{$gap-large/2});
grid-column-gap: $gap-large;
@include breakpoint( '<960px' ) {
- grid-template-columns: 1fr;
+ grid-template-columns: 100%;
}
}
diff --git a/plugins/woocommerce-admin/client/header/activity-panel/activity-card/index.js b/plugins/woocommerce-admin/client/header/activity-panel/activity-card/index.js
index 010652b2463..47857ecc956 100644
--- a/plugins/woocommerce-admin/client/header/activity-panel/activity-card/index.js
+++ b/plugins/woocommerce-admin/client/header/activity-panel/activity-card/index.js
@@ -5,7 +5,7 @@
import classnames from 'classnames';
import { cloneElement, Component } from '@wordpress/element';
import Gridicon from 'gridicons';
-import { moment } from '@wordpress/date';
+import moment from 'moment';
import PropTypes from 'prop-types';
/**
diff --git a/plugins/woocommerce-admin/client/header/activity-panel/activity-card/test/index.js b/plugins/woocommerce-admin/client/header/activity-panel/activity-card/test/index.js
index b643a346fd5..72acb7c6f1d 100644
--- a/plugins/woocommerce-admin/client/header/activity-panel/activity-card/test/index.js
+++ b/plugins/woocommerce-admin/client/header/activity-panel/activity-card/test/index.js
@@ -5,6 +5,7 @@
import { Button } from '@wordpress/components';
import Gridicon from 'gridicons';
import { shallow } from 'enzyme';
+import moment from 'moment';
/**
* Internal dependencies
@@ -54,8 +55,7 @@ describe( 'ActivityCard', () => {
test( 'should render a timestamp on a card', () => {
// We're generating this via moment to ensure it's always "3 days ago".
- const threeDaysAgo = wp.date
- .moment()
+ const threeDaysAgo = moment()
.subtract( 3, 'days' )
.format();
const card = shallow(
diff --git a/plugins/woocommerce-admin/client/store/reports/test/utils.js b/plugins/woocommerce-admin/client/store/reports/test/utils.js
index 90e0b604c3c..94c83b46ce9 100644
--- a/plugins/woocommerce-admin/client/store/reports/test/utils.js
+++ b/plugins/woocommerce-admin/client/store/reports/test/utils.js
@@ -327,7 +327,7 @@ describe( 'getSummaryNumbers()', () => {
} );
setGetReportStats( ( endpoint, _query ) => {
- if ( '2018-10-10T00:00:00' === _query.after ) {
+ if ( '2018-10-10T00:00:00+00:00' === _query.after ) {
return {
data: {
totals: totals.primary,
diff --git a/plugins/woocommerce-admin/client/store/reports/utils.js b/plugins/woocommerce-admin/client/store/reports/utils.js
index a81eb662921..0cb56aecd1e 100644
--- a/plugins/woocommerce-admin/client/store/reports/utils.js
+++ b/plugins/woocommerce-admin/client/store/reports/utils.js
@@ -4,6 +4,7 @@
* External dependencies
*/
import { find, forEach, isNull } from 'lodash';
+import moment from 'moment';
/**
* WooCommerce dependencies
@@ -18,19 +19,21 @@ import { formatCurrency } from '@woocommerce/currency';
import { MAX_PER_PAGE, QUERY_DEFAULTS } from 'store/constants';
import * as categoriesConfig from 'analytics/report/categories/config';
import * as couponsConfig from 'analytics/report/coupons/config';
+import * as customersConfig from 'analytics/report/customers/config';
+import * as downloadsConfig from 'analytics/report/downloads/config';
import * as ordersConfig from 'analytics/report/orders/config';
import * as productsConfig from 'analytics/report/products/config';
import * as taxesConfig from 'analytics/report/taxes/config';
-import * as customersConfig from 'analytics/report/customers/config';
import * as reportsUtils from './utils';
const reportConfigs = {
categories: categoriesConfig,
coupons: couponsConfig,
+ customers: customersConfig,
+ downloads: downloadsConfig,
orders: ordersConfig,
products: productsConfig,
taxes: taxesConfig,
- customers: customersConfig,
};
export function getFilterQuery( endpoint, query ) {
@@ -119,15 +122,18 @@ export function isReportDataEmpty( report ) {
* @returns {Object} data request query parameters.
*/
function getRequestQuery( endpoint, dataType, query ) {
- const datesFromQuery = getCurrentDates( query, 'YYYY-MM-DDTHH:00:00' );
+ const datesFromQuery = getCurrentDates( query );
const interval = getIntervalForQuery( query );
const filterQuery = getFilterQuery( endpoint, query );
+ const end = datesFromQuery[ dataType ].before;
+ const endingTimeOfDay = end.isSame( moment(), 'day' ) ? 'now' : 'end';
+
return {
order: 'asc',
interval,
per_page: MAX_PER_PAGE,
- after: datesFromQuery[ dataType ].after,
- before: datesFromQuery[ dataType ].before,
+ after: appendTimestamp( datesFromQuery[ dataType ].after, 'start' ),
+ before: appendTimestamp( end, endingTimeOfDay ),
...filterQuery,
};
}
diff --git a/plugins/woocommerce-admin/client/stylesheets/abstracts/_variables.scss b/plugins/woocommerce-admin/client/stylesheets/abstracts/_variables.scss
index 5a534b51442..bd882140fbf 100644
--- a/plugins/woocommerce-admin/client/stylesheets/abstracts/_variables.scss
+++ b/plugins/woocommerce-admin/client/stylesheets/abstracts/_variables.scss
@@ -17,6 +17,7 @@ $gap-smallest: 4px;
$spacing: 16px;
// Gutenberg Button variables. These are temporary until Gutenberg's variables are exposed.
+$border-width: 1px;
$default-font-size: 13px;
$blue-medium-200: #bfe7f3;
$light-gray-500: $core-grey-light-500;
diff --git a/plugins/woocommerce-admin/client/wc-api/reports/items/operations.js b/plugins/woocommerce-admin/client/wc-api/reports/items/operations.js
index 9ec07af3caa..a850a119c60 100644
--- a/plugins/woocommerce-admin/client/wc-api/reports/items/operations.js
+++ b/plugins/woocommerce-admin/client/wc-api/reports/items/operations.js
@@ -14,10 +14,6 @@ import { stringifyQuery } from '@woocommerce/navigation';
*/
import { getResourceIdentifier, getResourcePrefix } from '../../utils';
import { NAMESPACE } from '../../constants';
-import { SWAGGERNAMESPACE } from 'store/constants';
-
-// TODO: Remove once swagger endpoints are phased out.
-const swaggerEndpoints = [ 'customers', 'downloads' ];
const typeEndpointMap = {
'report-items-query-orders': 'orders',
@@ -42,17 +38,11 @@ function read( resourceNames, fetch = apiFetch ) {
const prefix = getResourcePrefix( resourceName );
const endpoint = typeEndpointMap[ prefix ];
const query = getResourceIdentifier( resourceName );
-
const fetchArgs = {
parse: false,
+ path: NAMESPACE + '/reports/' + endpoint + stringifyQuery( query ),
};
- if ( swaggerEndpoints.indexOf( endpoint ) >= 0 ) {
- fetchArgs.url = SWAGGERNAMESPACE + 'reports/' + endpoint + stringifyQuery( query );
- } else {
- fetchArgs.path = NAMESPACE + '/reports/' + endpoint + stringifyQuery( query );
- }
-
try {
const response = await fetch( fetchArgs );
const report = await response.json();
diff --git a/plugins/woocommerce-admin/client/wc-api/reports/stats/operations.js b/plugins/woocommerce-admin/client/wc-api/reports/stats/operations.js
index 133fff60eac..5d0d8876be3 100644
--- a/plugins/woocommerce-admin/client/wc-api/reports/stats/operations.js
+++ b/plugins/woocommerce-admin/client/wc-api/reports/stats/operations.js
@@ -16,9 +16,9 @@ import { getResourceIdentifier, getResourcePrefix } from '../../utils';
import { NAMESPACE } from '../../constants';
import { SWAGGERNAMESPACE } from 'store/constants';
-const statEndpoints = [ 'orders', 'revenue', 'products', 'taxes', 'coupons' ];
+const statEndpoints = [ 'coupons', 'downloads', 'orders', 'products', 'revenue', 'taxes' ];
// TODO: Remove once swagger endpoints are phased out.
-const swaggerEndpoints = [ 'categories', 'downloads' ];
+const swaggerEndpoints = [ 'categories' ];
const typeEndpointMap = {
'report-stats-query-orders': 'orders',
diff --git a/plugins/woocommerce-admin/client/wc-api/user/operations.js b/plugins/woocommerce-admin/client/wc-api/user/operations.js
index 1c12e9765c0..2c036b1fadd 100644
--- a/plugins/woocommerce-admin/client/wc-api/user/operations.js
+++ b/plugins/woocommerce-admin/client/wc-api/user/operations.js
@@ -40,6 +40,11 @@ function updateCurrentUserData( resourceNames, data, fetch ) {
'revenue_report_columns',
'taxes_report_columns',
'variations_report_columns',
+ 'dashboard_charts',
+ 'dashboard_chart_type',
+ 'dashboard_chart_interval',
+ 'dashboard_leaderboards',
+ 'dashboard_leaderboard_rows',
];
if ( resourceNames.includes( resourceName ) ) {
diff --git a/plugins/woocommerce-admin/docs/components/analytics/report-chart.md b/plugins/woocommerce-admin/docs/components/analytics/report-chart.md
index d9b113c7438..efd3381b486 100644
--- a/plugins/woocommerce-admin/docs/components/analytics/report-chart.md
+++ b/plugins/woocommerce-admin/docs/components/analytics/report-chart.md
@@ -20,6 +20,14 @@ Filters available for that report.
Label describing the legend items.
+### `mode`
+
+- Type: String
+- Default: null
+
+`items-comparison` (default) or `time-comparison`, this is used to generate correct
+ARIA properties.
+
### `path`
- **Required**
diff --git a/plugins/woocommerce-admin/docs/components/analytics/report-summary.md b/plugins/woocommerce-admin/docs/components/analytics/report-summary.md
index 69ac949a780..970d86a5ab8 100644
--- a/plugins/woocommerce-admin/docs/components/analytics/report-summary.md
+++ b/plugins/woocommerce-admin/docs/components/analytics/report-summary.md
@@ -20,7 +20,10 @@ Properties of all the charts available for that report.
- Type: String
- Default: null
-The endpoint to use in API calls.
+The endpoint to use in API calls to populate the Summary Numbers.
+For example, if `taxes` is provided, data will be fetched from the report
+`taxes` endpoint (ie: `/wc/v3/reports/taxes/stats`). If the provided endpoint
+doesn't exist, an error will be shown to the user with `ReportError`.
### `query`
diff --git a/plugins/woocommerce-admin/docs/components/analytics/report-table.md b/plugins/woocommerce-admin/docs/components/analytics/report-table.md
index d8fd3744cff..6fde1e1e69e 100644
--- a/plugins/woocommerce-admin/docs/components/analytics/report-table.md
+++ b/plugins/woocommerce-admin/docs/components/analytics/report-table.md
@@ -18,7 +18,11 @@ The key for user preferences settings for column visibility.
- Type: String
- Default: null
-The endpoint to use in API calls.
+The endpoint to use in API calls to populate the table rows and summary.
+For example, if `taxes` is provided, data will be fetched from the report
+`taxes` endpoint (ie: `/wc/v3/reports/taxes` and `/wc/v3/reports/taxes/stats`).
+If the provided endpoint doesn't exist, an error will be shown to the user
+with `ReportError`.
### `extendItemsMethodNames`
diff --git a/plugins/woocommerce-admin/docs/components/packages/chart.md b/plugins/woocommerce-admin/docs/components/packages/chart.md
index e1993644997..0b699b2f7c0 100644
--- a/plugins/woocommerce-admin/docs/components/packages/chart.md
+++ b/plugins/woocommerce-admin/docs/components/packages/chart.md
@@ -85,7 +85,7 @@ A number formatting string, passed to d3Format.
### `mode`
-- Type: One of: 'item-comparison', 'time-comparison'
+- Type: One of: 'block', 'item-comparison', 'time-comparison'
- Default: `'time-comparison'`
`item-comparison` (default) or `time-comparison`, this is used to generate correct
diff --git a/plugins/woocommerce-admin/docs/components/packages/search.md b/plugins/woocommerce-admin/docs/components/packages/search.md
index 0408f6b2c8b..45c13c3fa4c 100644
--- a/plugins/woocommerce-admin/docs/components/packages/search.md
+++ b/plugins/woocommerce-admin/docs/components/packages/search.md
@@ -24,7 +24,7 @@ Function called when selected results change, passed result list.
### `type`
- **Required**
-- Type: One of: 'countries', 'coupons', 'customers', 'emails', 'orders', 'products', 'product_cats', 'taxes', 'usernames', 'variations'
+- Type: One of: 'categories', 'countries', 'coupons', 'customers', 'downloadIps', 'emails', 'orders', 'products', 'taxes', 'usernames', 'variations'
- Default: null
The object type to be used in searching.
diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-controller.php
index 645ff5e3b04..83c9628168f 100644
--- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-controller.php
+++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-controller.php
@@ -73,6 +73,10 @@ class WC_Admin_REST_Reports_Controller extends WC_REST_Reports_Controller {
public function get_items( $request ) {
$data = array();
$reports = array(
+ array(
+ 'slug' => 'performance-indicators',
+ 'description' => __( 'Batch endpoint for getting specific performance indicators from `stats` endpoints.', 'wc-admin' ),
+ ),
array(
'slug' => 'revenue/stats',
'description' => __( 'Stats about revenue.', 'wc-admin' ),
diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-coupons-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-coupons-controller.php
index c387061707d..fb6e6c05e7f 100644
--- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-coupons-controller.php
+++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-coupons-controller.php
@@ -262,6 +262,7 @@ class WC_Admin_REST_Reports_Coupons_Controller extends WC_REST_Reports_Controlle
'default' => 'coupon_id',
'enum' => array(
'coupon_id',
+ 'code',
'amount',
'orders_count',
),
diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php
index 6165b3a97f6..523fba26387 100644
--- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php
+++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php
@@ -38,26 +38,33 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
* @return array
*/
protected function prepare_reports_query( $request ) {
- $args = array();
- $args['before'] = $request['before'];
- $args['after'] = $request['after'];
- $args['page'] = $request['page'];
- $args['per_page'] = $request['per_page'];
- $args['name'] = $request['name'];
- $args['username'] = $request['username'];
- $args['email'] = $request['email'];
- $args['country'] = $request['country'];
- $args['last_active_before'] = $request['last_active_before'];
- $args['last_active_after'] = $request['last_active_after'];
- $args['order_count_min'] = $request['order_count_min'];
- $args['order_count_max'] = $request['order_count_max'];
- $args['order_count_between'] = $request['order_count_between'];
- $args['total_spend_min'] = $request['total_spend_min'];
- $args['total_spend_max'] = $request['total_spend_max'];
- $args['total_spend_between'] = $request['total_spend_between'];
- $args['avg_order_value_min'] = $request['avg_order_value_min'];
- $args['avg_order_value_max'] = $request['avg_order_value_max'];
- $args['avg_order_value_between'] = $request['avg_order_value_between'];
+ $args = array();
+ $args['registered_before'] = $request['registered_before'];
+ $args['registered_after'] = $request['registered_after'];
+ $args['page'] = $request['page'];
+ $args['per_page'] = $request['per_page'];
+ $args['order'] = $request['order'];
+ $args['orderby'] = $request['orderby'];
+ $args['match'] = $request['match'];
+ $args['name'] = $request['name'];
+ $args['username'] = $request['username'];
+ $args['email'] = $request['email'];
+ $args['country'] = $request['country'];
+ $args['last_active_before'] = $request['last_active_before'];
+ $args['last_active_after'] = $request['last_active_after'];
+ $args['orders_count_min'] = $request['orders_count_min'];
+ $args['orders_count_max'] = $request['orders_count_max'];
+ $args['total_spend_min'] = $request['total_spend_min'];
+ $args['total_spend_max'] = $request['total_spend_max'];
+ $args['avg_order_value_min'] = $request['avg_order_value_min'];
+ $args['avg_order_value_max'] = $request['avg_order_value_max'];
+ $args['last_order_before'] = $request['last_order_before'];
+ $args['last_order_after'] = $request['last_order_after'];
+
+ $between_params = array( 'orders_count', 'total_spend', 'avg_order_value' );
+ $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params );
+ $args = array_merge( $args, $normalized );
+
return $args;
}
@@ -69,19 +76,20 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
*/
public function get_items( $request ) {
$query_args = $this->prepare_reports_query( $request );
- $customers_query = new WC_Reports_Orders_Stats_Query( $query_args ); // @todo change to correct class.
+ $customers_query = new WC_Admin_Reports_Customers_Query( $query_args );
$report_data = $customers_query->get_data();
- $out_data = array(
- 'totals' => get_object_vars( $report_data->totals ),
- 'customers' => array(),
- );
- foreach ( $report_data->customers as $customer_data ) {
- $item_data = $this->prepare_item_for_response( (object) $customer_data, $request );
- $out_data['customers'][] = $item_data;
+
+ $data = array();
+
+ foreach ( $report_data->data as $customer_data ) {
+ $item = $this->prepare_item_for_response( $customer_data, $request );
+ $data[] = $this->prepare_response_for_collection( $item );
}
- $response = rest_ensure_response( $out_data );
+
+ $response = rest_ensure_response( $data );
$response->header( 'X-WP-Total', (int) $report_data->total );
$response->header( 'X-WP-TotalPages', (int) $report_data->pages );
+
$page = $report_data->page_no;
$max_pages = $report_data->pages;
$base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) );
@@ -98,21 +106,26 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
$next_link = add_query_arg( 'page', $next_page, $base );
$response->link_header( 'next', $next_link );
}
+
return $response;
}
/**
* Prepare a report object for serialization.
*
- * @param stdClass $report Report data.
+ * @param array $report Report data.
* @param WP_REST_Request $request Request object.
* @return WP_REST_Response
*/
public function prepare_item_for_response( $report, $request ) {
- $data = get_object_vars( $report );
- $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
- $data = $this->add_additional_fields_to_object( $data, $request );
- $data = $this->filter_response_by_context( $data, $context );
+ $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
+ $data = $this->add_additional_fields_to_object( $report, $request );
+ $data['date_registered_gmt'] = wc_rest_prepare_date_response( $data['date_registered'] );
+ $data['date_registered'] = wc_rest_prepare_date_response( $data['date_registered'], false );
+ $data['date_last_active_gmt'] = wc_rest_prepare_date_response( $data['date_last_active'] );
+ $data['date_last_active'] = wc_rest_prepare_date_response( $data['date_last_active'], false );
+ $data = $this->filter_response_by_context( $data, $context );
+
// Wrap the data in a response object.
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $report ) );
@@ -131,16 +144,19 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
/**
* Prepare links for the request.
*
- * @param WC_Reports_Query $object Object data.
+ * @param array $object Object data.
* @return array
*/
protected function prepare_links( $object ) {
- $links = array(
+ if ( empty( $object['user_id'] ) ) {
+ return array();
+ }
+
+ return array(
'customer' => array(
- 'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $object->customer_id ) ),
+ 'href' => rest_url( sprintf( '/%s/customers/%d', $this->namespace, $object['user_id'] ) ),
),
);
- return $links;
}
/**
@@ -154,18 +170,60 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
'title' => 'report_customers',
'type' => 'object',
'properties' => array(
- 'id' => array(
- 'description' => __( 'ID.', 'wc-admin' ),
+ 'customer_id' => array(
+ 'description' => __( 'Customer ID.', 'wc-admin' ),
'type' => 'integer',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
- 'customer_id' => array(
- 'description' => __( 'Customer ID.', 'wc-admin' ),
+ 'user_id' => array(
+ 'description' => __( 'User ID.', 'wc-admin' ),
'type' => 'integer',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
+ 'name' => array(
+ 'description' => __( 'Name.', 'wc-admin' ),
+ 'type' => 'string',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ 'username' => array(
+ 'description' => __( 'Username.', 'wc-admin' ),
+ 'type' => 'string',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ 'country' => array(
+ 'description' => __( 'Country.', 'wc-admin' ),
+ 'type' => 'string',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ 'city' => array(
+ 'description' => __( 'City.', 'wc-admin' ),
+ 'type' => 'string',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ 'postcode' => array(
+ 'description' => __( 'Postal code.', 'wc-admin' ),
+ 'type' => 'string',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ 'date_registered' => array(
+ 'description' => __( 'Date registered.', 'wc-admin' ),
+ 'type' => 'date-time',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ 'date_registered_gmt' => array(
+ 'description' => __( 'Date registered GMT.', 'wc-admin' ),
+ 'type' => 'date-time',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
'date_last_active' => array(
'description' => __( 'Date last active.', 'wc-admin' ),
'type' => 'date-time',
@@ -209,14 +267,14 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
public function get_collection_params() {
$params = array();
$params['context'] = $this->get_context_param( array( 'default' => 'view' ) );
- $params['before'] = array(
- 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'wc-admin' ),
+ $params['registered_before'] = array(
+ 'description' => __( 'Limit response to objects registered before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ),
'type' => 'string',
'format' => 'date-time',
'validate_callback' => 'rest_validate_request_arg',
);
- $params['after'] = array(
- 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'wc-admin' ),
+ $params['registered_after'] = array(
+ 'description' => __( 'Limit response to objects registered after (or at) a given ISO8601 compliant datetime.', 'wc-admin' ),
'type' => 'string',
'format' => 'date-time',
'validate_callback' => 'rest_validate_request_arg',
@@ -238,7 +296,42 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
'sanitize_callback' => 'absint',
'validate_callback' => 'rest_validate_request_arg',
);
- $params['name'] = array(
+ $params['order'] = array(
+ 'description' => __( 'Order sort attribute ascending or descending.', 'wc-admin' ),
+ 'type' => 'string',
+ 'default' => 'desc',
+ 'enum' => array( 'asc', 'desc' ),
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+ $params['orderby'] = array(
+ 'description' => __( 'Sort collection by object attribute.', 'wc-admin' ),
+ 'type' => 'string',
+ 'default' => 'date_registered',
+ 'enum' => array(
+ 'username',
+ 'name',
+ 'country',
+ 'city',
+ 'postcode',
+ 'date_registered',
+ 'date_last_active',
+ 'orders_count',
+ 'total_spend',
+ 'avg_order_value',
+ ),
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+ $params['match'] = array(
+ 'description' => __( 'Indicates whether all the conditions should be true for the resulting set, or if any one of them is sufficient. Match affects the following parameters: status_is, status_is_not, product_includes, product_excludes, coupon_includes, coupon_excludes, customer, categories', 'wc-admin' ),
+ 'type' => 'string',
+ 'default' => 'all',
+ 'enum' => array(
+ 'all',
+ 'any',
+ ),
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+ $params['name'] = array(
'description' => __( 'Limit response to objects with a specfic customer name.', 'wc-admin' ),
'type' => 'string',
'validate_callback' => 'rest_validate_request_arg',
@@ -270,22 +363,34 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
'format' => 'date-time',
'validate_callback' => 'rest_validate_request_arg',
);
- $params['order_count_min'] = array(
+ $params['registered_before'] = array(
+ 'description' => __( 'Limit response to objects registered before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ),
+ 'type' => 'string',
+ 'format' => 'date-time',
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+ $params['registered_after'] = array(
+ 'description' => __( 'Limit response to objects registered after (or at) a given ISO8601 compliant datetime.', 'wc-admin' ),
+ 'type' => 'string',
+ 'format' => 'date-time',
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+ $params['orders_count_min'] = array(
'description' => __( 'Limit response to objects with an order count greater than or equal to given integer.', 'wc-admin' ),
'type' => 'integer',
'sanitize_callback' => 'absint',
'validate_callback' => 'rest_validate_request_arg',
);
- $params['order_count_max'] = array(
+ $params['orders_count_max'] = array(
'description' => __( 'Limit response to objects with an order count less than or equal to given integer.', 'wc-admin' ),
'type' => 'integer',
'sanitize_callback' => 'absint',
'validate_callback' => 'rest_validate_request_arg',
);
- $params['order_count_between'] = array(
+ $params['orders_count_between'] = array(
'description' => __( 'Limit response to objects with an order count between two given integers.', 'wc-admin' ),
'type' => 'array',
- 'validate_callback' => 'rest_validate_request_arg',
+ 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ),
);
$params['total_spend_min'] = array(
'description' => __( 'Limit response to objects with a total order spend greater than or equal to given number.', 'wc-admin' ),
@@ -300,7 +405,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
$params['total_spend_between'] = array(
'description' => __( 'Limit response to objects with a total order spend between two given numbers.', 'wc-admin' ),
'type' => 'array',
- 'validate_callback' => 'rest_validate_request_arg',
+ 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ),
);
$params['avg_order_value_min'] = array(
'description' => __( 'Limit response to objects with an average order spend greater than or equal to given number.', 'wc-admin' ),
@@ -315,6 +420,18 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control
$params['avg_order_value_between'] = array(
'description' => __( 'Limit response to objects with an average order spend between two given numbers.', 'wc-admin' ),
'type' => 'array',
+ 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ),
+ );
+ $params['last_order_before'] = array(
+ 'description' => __( 'Limit response to objects with last order before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ),
+ 'type' => 'string',
+ 'format' => 'date-time',
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+ $params['last_order_after'] = array(
+ 'description' => __( 'Limit response to objects with last order after (or at) a given ISO8601 compliant datetime.', 'wc-admin' ),
+ 'type' => 'string',
+ 'format' => 'date-time',
'validate_callback' => 'rest_validate_request_arg',
);
return $params;
diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-downloads-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-downloads-controller.php
index 3dc6aaf8bf9..0265cc21a76 100644
--- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-downloads-controller.php
+++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-downloads-controller.php
@@ -107,8 +107,10 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_REST_Reports_Control
$product_id = intval( $data['product_id'] );
$_product = wc_get_product( $product_id );
$file_path = $_product->get_file_download_path( $data['download_id'] );
+
$filename = basename( $file_path );
$response->data['file_name'] = apply_filters( 'woocommerce_file_download_filename', $filename, $product_id );
+ $response->data['file_path'] = $file_path;
/**
* Filter a report returned from the API.
@@ -190,6 +192,12 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_REST_Reports_Control
'context' => array( 'view', 'edit' ),
'description' => __( 'File name.', 'wc-admin' ),
),
+ 'file_path' => array(
+ 'type' => 'string',
+ 'readonly' => true,
+ 'context' => array( 'view', 'edit' ),
+ 'description' => __( 'File URL.', 'wc-admin' ),
+ ),
'product_id' => array(
'type' => 'integer',
'readonly' => true,
@@ -270,6 +278,7 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_REST_Reports_Control
'default' => 'date',
'enum' => array(
'date',
+ 'product',
),
'validate_callback' => 'rest_validate_request_arg',
);
@@ -292,7 +301,6 @@ class WC_Admin_REST_Reports_Downloads_Controller extends WC_REST_Reports_Control
'default' => array(),
'sanitize_callback' => 'wp_parse_id_list',
'validate_callback' => 'rest_validate_request_arg',
-
);
$params['product_excludes'] = array(
'description' => __( 'Limit result set to items that don\'t have the specified product(s) assigned.', 'wc-admin' ),
diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-downloads-stats-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-downloads-stats-controller.php
index a1339e34806..8726c677f4f 100644
--- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-downloads-stats-controller.php
+++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-downloads-stats-controller.php
@@ -30,4 +30,340 @@ class WC_Admin_REST_Reports_Downloads_Stats_Controller extends WC_REST_Reports_C
* @var string
*/
protected $rest_base = 'reports/downloads/stats';
+
+ /**
+ * Maps query arguments from the REST request.
+ *
+ * @param array $request Request array.
+ * @return array
+ */
+ protected function prepare_reports_query( $request ) {
+ $args = array();
+ $args['before'] = $request['before'];
+ $args['after'] = $request['after'];
+ $args['interval'] = $request['interval'];
+ $args['page'] = $request['page'];
+ $args['per_page'] = $request['per_page'];
+ $args['orderby'] = $request['orderby'];
+ $args['order'] = $request['order'];
+ $args['match'] = $request['match'];
+ $args['product_includes'] = (array) $request['product_includes'];
+ $args['product_excludes'] = (array) $request['product_excludes'];
+ $args['order_includes'] = (array) $request['order_includes'];
+ $args['order_excludes'] = (array) $request['order_excludes'];
+ $args['ip_address_includes'] = (array) $request['ip_address_includes'];
+ $args['ip_address_excludes'] = (array) $request['ip_address_excludes'];
+
+ return $args;
+ }
+
+ /**
+ * Get all reports.
+ *
+ * @param WP_REST_Request $request Request data.
+ * @return array|WP_Error
+ */
+ public function get_items( $request ) {
+ $query_args = $this->prepare_reports_query( $request );
+ $downloads_query = new WC_Admin_Reports_Downloads_Stats_Query( $query_args );
+ $report_data = $downloads_query->get_data();
+
+ $out_data = array(
+ 'totals' => get_object_vars( $report_data->totals ),
+ 'intervals' => array(),
+ );
+
+ foreach ( $report_data->intervals as $interval_data ) {
+ $item = $this->prepare_item_for_response( $interval_data, $request );
+ $out_data['intervals'][] = $this->prepare_response_for_collection( $item );
+ }
+
+ $response = rest_ensure_response( $out_data );
+ $response->header( 'X-WP-Total', (int) $report_data->total );
+ $response->header( 'X-WP-TotalPages', (int) $report_data->pages );
+
+ $page = $report_data->page_no;
+ $max_pages = $report_data->pages;
+ $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) );
+ if ( $page > 1 ) {
+ $prev_page = $page - 1;
+ if ( $prev_page > $max_pages ) {
+ $prev_page = $max_pages;
+ }
+ $prev_link = add_query_arg( 'page', $prev_page, $base );
+ $response->link_header( 'prev', $prev_link );
+ }
+ if ( $max_pages > $page ) {
+ $next_page = $page + 1;
+ $next_link = add_query_arg( 'page', $next_page, $base );
+ $response->link_header( 'next', $next_link );
+ }
+
+ return $response;
+ }
+
+ /**
+ * Prepare a report object for serialization.
+ *
+ * @param Array $report Report data.
+ * @param WP_REST_Request $request Request object.
+ * @return WP_REST_Response
+ */
+ public function prepare_item_for_response( $report, $request ) {
+ $data = $report;
+
+ $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
+ $data = $this->add_additional_fields_to_object( $data, $request );
+ $data = $this->filter_response_by_context( $data, $context );
+
+ // Wrap the data in a response object.
+ $response = rest_ensure_response( $data );
+
+ /**
+ * Filter a report returned from the API.
+ *
+ * Allows modification of the report data right before it is returned.
+ *
+ * @param WP_REST_Response $response The response object.
+ * @param object $report The original report object.
+ * @param WP_REST_Request $request Request used to generate the response.
+ */
+ return apply_filters( 'woocommerce_rest_prepare_report_downloads_stats', $response, $report, $request );
+ }
+
+ /**
+ * Get the Report's schema, conforming to JSON Schema.
+ *
+ * @return array
+ */
+ public function get_item_schema() {
+ $totals = array(
+ 'download_count' => array(
+ 'description' => __( 'Number of downloads.', 'wc-admin' ),
+ 'type' => 'number',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ );
+
+ $schema = array(
+ '$schema' => 'http://json-schema.org/draft-04/schema#',
+ 'title' => 'report_orders_stats',
+ 'type' => 'object',
+ 'properties' => array(
+ 'totals' => array(
+ 'description' => __( 'Totals data.', 'wc-admin' ),
+ 'type' => 'object',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ 'properties' => $totals,
+ ),
+ 'intervals' => array(
+ 'description' => __( 'Reports data grouped by intervals.', 'wc-admin' ),
+ 'type' => 'array',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ 'items' => array(
+ 'type' => 'object',
+ 'properties' => array(
+ 'interval' => array(
+ 'description' => __( 'Type of interval.', 'wc-admin' ),
+ 'type' => 'string',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ 'enum' => array( 'day', 'week', 'month', 'year' ),
+ ),
+ 'date_start' => array(
+ 'description' => __( "The date the report start, in the site's timezone.", 'wc-admin' ),
+ 'type' => 'date-time',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ 'date_start_gmt' => array(
+ 'description' => __( 'The date the report start, as GMT.', 'wc-admin' ),
+ 'type' => 'date-time',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ 'date_end' => array(
+ 'description' => __( "The date the report end, in the site's timezone.", 'wc-admin' ),
+ 'type' => 'date-time',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ 'date_end_gmt' => array(
+ 'description' => __( 'The date the report end, as GMT.', 'wc-admin' ),
+ 'type' => 'date-time',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ 'subtotals' => array(
+ 'description' => __( 'Interval subtotals.', 'wc-admin' ),
+ 'type' => 'object',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ 'properties' => $totals,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+
+ return $this->add_additional_fields_schema( $schema );
+ }
+
+ /**
+ * Get the query params for collections.
+ *
+ * @return array
+ */
+ public function get_collection_params() {
+ $params = array();
+ $params['context'] = $this->get_context_param( array( 'default' => 'view' ) );
+ $params['page'] = array(
+ 'description' => __( 'Current page of the collection.', 'wc-admin' ),
+ 'type' => 'integer',
+ 'default' => 1,
+ 'sanitize_callback' => 'absint',
+ 'validate_callback' => 'rest_validate_request_arg',
+ 'minimum' => 1,
+ );
+ $params['per_page'] = array(
+ 'description' => __( 'Maximum number of items to be returned in result set.', 'wc-admin' ),
+ 'type' => 'integer',
+ 'default' => 10,
+ 'minimum' => 1,
+ 'maximum' => 100,
+ 'sanitize_callback' => 'absint',
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+ $params['after'] = array(
+ 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'wc-admin' ),
+ 'type' => 'string',
+ 'format' => 'date-time',
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+ $params['before'] = array(
+ 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'wc-admin' ),
+ 'type' => 'string',
+ 'format' => 'date-time',
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+ $params['order'] = array(
+ 'description' => __( 'Order sort attribute ascending or descending.', 'wc-admin' ),
+ 'type' => 'string',
+ 'default' => 'desc',
+ 'enum' => array( 'asc', 'desc' ),
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+ $params['orderby'] = array(
+ 'description' => __( 'Sort collection by object attribute.', 'wc-admin' ),
+ 'type' => 'string',
+ 'default' => 'date',
+ 'enum' => array(
+ 'date',
+ 'download_count',
+ ),
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+ $params['interval'] = array(
+ 'description' => __( 'Time interval to use for buckets in the returned data.', 'wc-admin' ),
+ 'type' => 'string',
+ 'default' => 'week',
+ 'enum' => array(
+ 'hour',
+ 'day',
+ 'week',
+ 'month',
+ 'quarter',
+ 'year',
+ ),
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+ $params['match'] = array(
+ 'description' => __( 'Indicates whether all the conditions should be true for the resulting set, or if any one of them is sufficient. Match affects the following parameters: status_is, status_is_not, product_includes, product_excludes, coupon_includes, coupon_excludes, customer, categories', 'wc-admin' ),
+ 'type' => 'string',
+ 'default' => 'all',
+ 'enum' => array(
+ 'all',
+ 'any',
+ ),
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+ $params['product_includes'] = array(
+ 'description' => __( 'Limit result set to items that have the specified product(s) assigned.', 'wc-admin' ),
+ 'type' => 'array',
+ 'items' => array(
+ 'type' => 'integer',
+ ),
+ 'default' => array(),
+ 'sanitize_callback' => 'wp_parse_id_list',
+
+ );
+ $params['product_excludes'] = array(
+ 'description' => __( 'Limit result set to items that don\'t have the specified product(s) assigned.', 'wc-admin' ),
+ 'type' => 'array',
+ 'items' => array(
+ 'type' => 'integer',
+ ),
+ 'default' => array(),
+ 'sanitize_callback' => 'wp_parse_id_list',
+ );
+ $params['order_includes'] = array(
+ 'description' => __( 'Limit result set to items that have the specified order ids.', 'wc-admin' ),
+ 'type' => 'array',
+ 'sanitize_callback' => 'wp_parse_id_list',
+ 'validate_callback' => 'rest_validate_request_arg',
+ 'items' => array(
+ 'type' => 'integer',
+ ),
+ );
+ $params['order_excludes'] = array(
+ 'description' => __( 'Limit result set to items that don\'t have the specified order ids.', 'wc-admin' ),
+ 'type' => 'array',
+ 'sanitize_callback' => 'wp_parse_id_list',
+ 'validate_callback' => 'rest_validate_request_arg',
+ 'items' => array(
+ 'type' => 'integer',
+ ),
+ );
+ $params['user_includes'] = array(
+ 'description' => __( 'Limit response to objects that have the specified user ids.', 'wc-admin' ),
+ 'type' => 'array',
+ 'sanitize_callback' => 'wp_parse_id_list',
+ 'validate_callback' => 'rest_validate_request_arg',
+ 'items' => array(
+ 'type' => 'integer',
+ ),
+ );
+ $params['user_excludes'] = array(
+ 'description' => __( 'Limit response to objects that don\'t have the specified user ids.', 'wc-admin' ),
+ 'type' => 'array',
+ 'sanitize_callback' => 'wp_parse_id_list',
+ 'validate_callback' => 'rest_validate_request_arg',
+ 'items' => array(
+ 'type' => 'integer',
+ ),
+ );
+ $params['ip_address_includes'] = array(
+ 'description' => __( 'Limit response to objects that have a specified ip address.', 'wc-admin' ),
+ 'type' => 'array',
+ 'validate_callback' => 'rest_validate_request_arg',
+ 'items' => array(
+ 'type' => 'string',
+ ),
+ );
+
+ $params['ip_address_excludes'] = array(
+ 'description' => __( 'Limit response to objects that don\'t have a specified ip address.', 'wc-admin' ),
+ 'type' => 'array',
+ 'validate_callback' => 'rest_validate_request_arg',
+ 'items' => array(
+ 'type' => 'string',
+ ),
+ );
+
+ return $params;
+ }
}
diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-performance-indicators-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-performance-indicators-controller.php
new file mode 100644
index 00000000000..d3e59938381
--- /dev/null
+++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-performance-indicators-controller.php
@@ -0,0 +1,287 @@
+get_data();
+ $allowed_stats = array();
+ if ( 200 !== $response->get_status() ) {
+ return new WP_Error( 'woocommerce_reports_performance_indicators_result_failed', __( 'Sorry, fetching performance indicators failed.', 'wc-admin' ) );
+ }
+
+ foreach ( $endpoints as $endpoint ) {
+ if ( '/stats' === substr( $endpoint['slug'], -6 ) ) {
+ $request = new WP_REST_Request( 'OPTIONS', '/wc/v3/reports/' . $endpoint['slug'] );
+ $response = rest_do_request( $request );
+ $data = $response->get_data();
+ $prefix = substr( $endpoint['slug'], 0, -6 );
+
+ if ( empty( $data['schema']['properties']['totals']['properties'] ) ) {
+ continue;
+ }
+
+ foreach ( $data['schema']['properties']['totals']['properties'] as $property_key => $schema_info ) {
+ $allowed_stats[] = $prefix . '/' . $property_key;
+ }
+ }
+ }
+
+ /**
+ * Filter the list of allowed stats that can be returned via the performance indiciator endpoint.
+ *
+ * @param array $allowed_stats The list of allowed stats.
+ */
+ return apply_filters( 'woocommerce_admin_performance_indicators_allowed_stats', $allowed_stats );
+ }
+
+ /**
+ * Get all reports.
+ *
+ * @param WP_REST_Request $request Request data.
+ * @return array|WP_Error
+ */
+ public function get_items( $request ) {
+ $allowed_stats = $this->get_allowed_stats();
+
+ if ( is_wp_error( $allowed_stats ) ) {
+ return $allowed_stats;
+ }
+
+ $query_args = $this->prepare_reports_query( $request );
+ if ( empty( $query_args['stats'] ) ) {
+ return new WP_Error( 'woocommerce_reports_performance_indicators_empty_query', __( 'A list of stats to query must be provided.', 'wc-admin' ), 400 );
+ }
+
+ $stats = array();
+ foreach ( $query_args['stats'] as $stat_request ) {
+ $is_error = false;
+
+ $pieces = explode( '/', $stat_request );
+ $endpoint = $pieces[0];
+ $stat = $pieces[1];
+
+ if ( ! in_array( $stat_request, $allowed_stats ) ) {
+ continue;
+ }
+
+ /**
+ * Filter the list of allowed endpoints, so that data can be loaded from extensions rather than core.
+ * These should be in the format of slug => path. Example: `bookings` => `/wc-bookings/v1/reports/bookings/stats`.
+ *
+ * @param array $endpoints The list of allowed endpoints.
+ */
+ $stats_endpoints = apply_filters( 'woocommerce_admin_performance_indicators_stats_endpoints', array() );
+ if ( ! empty( $stats_endpoints [ $endpoint ] ) ) {
+ $request_url = $stats_endpoints [ $endpoint ];
+ } else {
+ $request_url = '/wc/v3/reports/' . $endpoint . '/stats';
+ }
+
+ $request = new WP_REST_Request( 'GET', $request_url );
+ $request->set_param( 'before', $query_args['before'] );
+ $request->set_param( 'after', $query_args['after'] );
+
+ $response = rest_do_request( $request );
+ $data = $response->get_data();
+
+ if ( 200 !== $response->get_status() || empty( $data['totals'][ $stat ] ) ) {
+ $stats[] = (object) array(
+ 'stat' => $stat_request,
+ 'value' => null,
+ );
+ continue;
+ }
+
+ $stats[] = (object) array(
+ 'stat' => $stat_request,
+ 'value' => $data['totals'][ $stat ],
+ );
+ }
+
+ $objects = array();
+ foreach ( $stats as $stat ) {
+ $data = $this->prepare_item_for_response( $stat, $request );
+ $objects[] = $this->prepare_response_for_collection( $data );
+ }
+
+ $response = rest_ensure_response( $objects );
+ $response->header( 'X-WP-Total', count( $stats ) );
+ $response->header( 'X-WP-TotalPages', 1 );
+
+ $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) );
+
+ return $response;
+ }
+
+ /**
+ * Prepare a report object for serialization.
+ *
+ * @param stdClass $stat_data Report data.
+ * @param WP_REST_Request $request Request object.
+ * @return WP_REST_Response
+ */
+ public function prepare_item_for_response( $stat_data, $request ) {
+ $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
+ $data = $this->add_additional_fields_to_object( $stat_data, $request );
+ $data = $this->filter_response_by_context( $data, $context );
+
+ // Wrap the data in a response object.
+ $response = rest_ensure_response( $data );
+
+ $response->add_links( $this->prepare_links( $data ) );
+
+ /**
+ * Filter a report returned from the API.
+ *
+ * Allows modification of the report data right before it is returned.
+ *
+ * @param WP_REST_Response $response The response object.
+ * @param object $report The original report object.
+ * @param WP_REST_Request $request Request used to generate the response.
+ */
+ return apply_filters( 'woocommerce_rest_prepare_report_performance_indicators', $response, $stat_data, $request );
+ }
+
+ /**
+ * Prepare links for the request.
+ *
+ * @param WC_Admin_Reports_Query $object Object data.
+ * @return array
+ */
+ protected function prepare_links( $object ) {
+ $pieces = explode( '/', $object->stat );
+ $endpoint = $pieces[0];
+ $stat = $pieces[1];
+
+ $links = array(
+ 'report' => array(
+ 'href' => rest_url( sprintf( '/%s/reports/%s/stats', $this->namespace, $endpoint ) ),
+ ),
+ );
+
+ return $links;
+ }
+
+ /**
+ * Get the Report's schema, conforming to JSON Schema.
+ *
+ * @return array
+ */
+ public function get_item_schema() {
+ $schema = array(
+ '$schema' => 'http://json-schema.org/draft-04/schema#',
+ 'title' => 'report_performance_indicator',
+ 'type' => 'object',
+ 'properties' => array(
+ 'stat' => array(
+ 'description' => __( 'Unique identifier for the resource.', 'wc-admin' ),
+ 'type' => 'string',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ 'value' => array(
+ 'description' => __( 'Value of the stat. Returns null if the stat does not exist or cannot be loaded.', 'wc-admin' ),
+ 'type' => 'number',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ ),
+ );
+
+ return $this->add_additional_fields_schema( $schema );
+ }
+
+ /**
+ * Get the query params for collections.
+ *
+ * @return array
+ */
+ public function get_collection_params() {
+ $allowed_stats = $this->get_allowed_stats();
+ if ( is_wp_error( $allowed_stats ) ) {
+ $allowed_stats = __( 'There was an issue loading the report endpoints', 'wc-admin' );
+ } else {
+ $allowed_stats = implode( ', ', $allowed_stats );
+ }
+
+ $params = array();
+ $params['context'] = $this->get_context_param( array( 'default' => 'view' ) );
+ $params['stats'] = array(
+ 'description' => sprintf(
+ /* translators: Allowed values is a list of stat endpoints. */
+ __( 'Limit response to specific report stats. Allowed values: %s.', 'wc-admin' ),
+ $allowed_stats
+ ),
+ 'type' => 'array',
+ 'validate_callback' => 'rest_validate_request_arg',
+ 'items' => array(
+ 'type' => 'string',
+ ),
+ );
+ $params['after'] = array(
+ 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'wc-admin' ),
+ 'type' => 'string',
+ 'format' => 'date-time',
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+ $params['before'] = array(
+ 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'wc-admin' ),
+ 'type' => 'string',
+ 'format' => 'date-time',
+ 'validate_callback' => 'rest_validate_request_arg',
+ );
+ return $params;
+ }
+}
diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-products-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-products-controller.php
index 4308becd3c2..5ce54e41933 100644
--- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-products-controller.php
+++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-products-controller.php
@@ -291,6 +291,7 @@ class WC_Admin_REST_Reports_Products_Controller extends WC_REST_Reports_Controll
'orders_count',
'items_sold',
'product_name',
+ 'sku',
),
'validate_callback' => 'rest_validate_request_arg',
);
diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-stock-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-stock-controller.php
index 4262c1d7ebc..9ba7c31a655 100644
--- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-stock-controller.php
+++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-stock-controller.php
@@ -58,8 +58,9 @@ class WC_Admin_REST_Reports_Stock_Controller extends WC_REST_Reports_Controller
$args['orderby'] = 'post__in';
} elseif ( 'id' === $args['orderby'] ) {
$args['orderby'] = 'ID'; // ID must be capitalized.
- } elseif ( 'slug' === $args['orderby'] ) {
- $args['orderby'] = 'name';
+ } elseif ( 'sku' === $args['orderby'] ) {
+ $args['meta_key'] = '_sku'; // WPCS: slow query ok.
+ $args['orderby'] = 'meta_value';
}
$args['post_type'] = array( 'product', 'product_variation' );
@@ -359,7 +360,7 @@ class WC_Admin_REST_Reports_Stock_Controller extends WC_REST_Reports_Controller
'id',
'include',
'title',
- 'slug',
+ 'sku',
),
'validate_callback' => 'rest_validate_request_arg',
);
diff --git a/plugins/woocommerce-admin/includes/class-wc-admin-api-init.php b/plugins/woocommerce-admin/includes/class-wc-admin-api-init.php
index 82ebad4ba7a..0761df4c61c 100644
--- a/plugins/woocommerce-admin/includes/class-wc-admin-api-init.php
+++ b/plugins/woocommerce-admin/includes/class-wc-admin-api-init.php
@@ -29,6 +29,10 @@ class WC_Admin_Api_Init {
// Initialize Orders data store class's static vars.
add_action( 'woocommerce_after_register_post_type', array( 'WC_Admin_Api_Init', 'orders_data_store_init' ), 20 );
+ // Initialize Customers Report data store sync hooks.
+ // Note: we need to hook into 'wp' before `wc_current_user_is_active`.
+ // See: https://github.com/woocommerce/woocommerce/blob/942615101ba00c939c107c3a4820c3d466864872/includes/wc-user-functions.php#L749.
+ add_action( 'wp', array( 'WC_Admin_Api_Init', 'customers_report_data_store_init' ), 9 );
}
/**
@@ -54,6 +58,8 @@ class WC_Admin_Api_Init {
require_once dirname( __FILE__ ) . '/class-wc-admin-reports-coupons-query.php';
require_once dirname( __FILE__ ) . '/class-wc-admin-reports-coupons-stats-query.php';
require_once dirname( __FILE__ ) . '/class-wc-admin-reports-downloads-query.php';
+ require_once dirname( __FILE__ ) . '/class-wc-admin-reports-downloads-stats-query.php';
+ require_once dirname( __FILE__ ) . '/class-wc-admin-reports-customers-query.php';
// Data stores.
require_once dirname( __FILE__ ) . '/data-stores/class-wc-admin-reports-data-store.php';
@@ -67,6 +73,8 @@ class WC_Admin_Api_Init {
require_once dirname( __FILE__ ) . '/data-stores/class-wc-admin-reports-coupons-data-store.php';
require_once dirname( __FILE__ ) . '/data-stores/class-wc-admin-reports-coupons-stats-data-store.php';
require_once dirname( __FILE__ ) . '/data-stores/class-wc-admin-reports-downloads-data-store.php';
+ require_once dirname( __FILE__ ) . '/data-stores/class-wc-admin-reports-downloads-stats-data-store.php';
+ require_once dirname( __FILE__ ) . '/data-stores/class-wc-admin-reports-customers-data-store.php';
// Data triggers.
require_once dirname( __FILE__ ) . '/data-stores/class-wc-admin-notes-data-store.php';
@@ -100,36 +108,44 @@ class WC_Admin_Api_Init {
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-products-controller.php';
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-variations-controller.php';
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-products-stats-controller.php';
+ require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-performance-indicators-controller.php';
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-revenue-stats-controller.php';
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-taxes-controller.php';
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-taxes-stats-controller.php';
require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-stock-controller.php';
- require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-downloads-controller.php';
- $controllers = array(
- 'WC_Admin_REST_Admin_Notes_Controller',
- 'WC_Admin_REST_Customers_Controller',
- 'WC_Admin_REST_Data_Controller',
- 'WC_Admin_REST_Data_Download_Ips_Controller',
- 'WC_Admin_REST_Orders_Controller',
- 'WC_Admin_REST_Products_Controller',
- 'WC_Admin_REST_Product_Reviews_Controller',
- 'WC_Admin_REST_Reports_Controller',
- 'WC_Admin_REST_System_Status_Tools_Controller',
- 'WC_Admin_REST_Reports_Products_Controller',
- 'WC_Admin_REST_Reports_Variations_Controller',
- 'WC_Admin_REST_Reports_Products_Stats_Controller',
- 'WC_Admin_REST_Reports_Revenue_Stats_Controller',
- 'WC_Admin_REST_Reports_Orders_Stats_Controller',
- 'WC_Admin_REST_Reports_Categories_Controller',
- 'WC_Admin_REST_Reports_Taxes_Controller',
- 'WC_Admin_REST_Reports_Taxes_Stats_Controller',
- 'WC_Admin_REST_Reports_Coupons_Controller',
- 'WC_Admin_REST_Reports_Coupons_Stats_Controller',
- 'WC_Admin_REST_Reports_Stock_Controller',
- 'WC_Admin_REST_Reports_Downloads_Controller',
+ $controllers = apply_filters(
+ 'woocommerce_admin_rest_controllers',
+ array(
+ 'WC_Admin_REST_Admin_Notes_Controller',
+ 'WC_Admin_REST_Customers_Controller',
+ 'WC_Admin_REST_Data_Controller',
+ 'WC_Admin_REST_Data_Download_Ips_Controller',
+ 'WC_Admin_REST_Orders_Controller',
+ 'WC_Admin_REST_Products_Controller',
+ 'WC_Admin_REST_Product_Reviews_Controller',
+ 'WC_Admin_REST_Reports_Controller',
+ 'WC_Admin_REST_System_Status_Tools_Controller',
+ 'WC_Admin_REST_Reports_Products_Controller',
+ 'WC_Admin_REST_Reports_Variations_Controller',
+ 'WC_Admin_REST_Reports_Products_Stats_Controller',
+ 'WC_Admin_REST_Reports_Revenue_Stats_Controller',
+ 'WC_Admin_REST_Reports_Orders_Stats_Controller',
+ 'WC_Admin_REST_Reports_Categories_Controller',
+ 'WC_Admin_REST_Reports_Taxes_Controller',
+ 'WC_Admin_REST_Reports_Taxes_Stats_Controller',
+ 'WC_Admin_REST_Reports_Coupons_Controller',
+ 'WC_Admin_REST_Reports_Coupons_Stats_Controller',
+ 'WC_Admin_REST_Reports_Stock_Controller',
+ 'WC_Admin_REST_Reports_Downloads_Controller',
+ 'WC_Admin_REST_Reports_Downloads_Stats_Controller',
+ 'WC_Admin_REST_Reports_Customers_Controller',
+ )
);
+ // The performance indicators controller must be registered last, after other /stats endpoints have been registered.
+ $controllers[] = 'WC_Admin_REST_Reports_Performance_Indicators_Controller';
+
foreach ( $controllers as $controller ) {
$this->$controller = new $controller();
$this->$controller->register_routes();
@@ -258,6 +274,9 @@ class WC_Admin_Api_Init {
* Regenerate data for reports.
*/
public static function regenerate_report_data() {
+ // Add registered customers to the lookup table before updating order stats
+ // so that the orders can be associated with the `customer_id` column.
+ self::customer_lookup_store_init();
WC_Admin_Reports_Orders_Data_Store::queue_order_stats_repopulate_database();
self::order_product_lookup_store_init();
}
@@ -328,6 +347,59 @@ class WC_Admin_Api_Init {
return true;
}
+ /**
+ * Init customers report data store.
+ */
+ public static function customers_report_data_store_init() {
+ WC_Admin_Reports_Customers_Data_Store::init();
+ }
+
+ /**
+ * Init customer lookup store.
+ *
+ * @param WC_Background_Updater|null $updater Updater instance.
+ * @return bool
+ */
+ public static function customer_lookup_store_init( $updater = null ) {
+ // TODO: this needs to be updated a bit, as it no longer runs as a part of WC_Install, there is no bg updater.
+ global $wpdb;
+
+ // Backfill customer lookup table with registered customers.
+ $customer_ids = get_transient( 'wc_update_350_all_customers' );
+
+ if ( false === $customer_ids ) {
+ $customer_query = new WP_User_Query(
+ array(
+ 'fields' => 'ID',
+ 'role' => 'customer',
+ 'number' => -1,
+ )
+ );
+
+ $customer_ids = $customer_query->get_results();
+
+ set_transient( 'wc_update_350_all_customers', $customer_ids, DAY_IN_SECONDS );
+ }
+
+ // Process customers until close to running out of memory timeouts on large sites then requeue.
+ foreach ( $customer_ids as $customer_id ) {
+ $result = WC_Admin_Reports_Customers_Data_Store::update_registered_customer( $customer_id );
+
+ if ( $result ) {
+ // Pop the customer ID from the array for updating the transient later should we near memory exhaustion.
+ unset( $customer_ids[ $customer_id ] );
+ }
+
+ if ( $updater instanceof WC_Background_Updater && $updater->is_memory_exceeded() ) {
+ // Update the transient for the next run to avoid processing the same orders again.
+ set_transient( 'wc_update_350_all_customers', $customer_ids, DAY_IN_SECONDS );
+ return true;
+ }
+ }
+
+ return true;
+ }
+
/**
* Adds data stores.
*
@@ -338,18 +410,20 @@ class WC_Admin_Api_Init {
return array_merge(
$data_stores,
array(
- 'report-revenue-stats' => 'WC_Admin_Reports_Orders_Data_Store',
- 'report-orders-stats' => 'WC_Admin_Reports_Orders_Data_Store',
- 'report-products' => 'WC_Admin_Reports_Products_Data_Store',
- 'report-variations' => 'WC_Admin_Reports_Variations_Data_Store',
- 'report-products-stats' => 'WC_Admin_Reports_Products_Stats_Data_Store',
- 'report-categories' => 'WC_Admin_Reports_Categories_Data_Store',
- 'report-taxes' => 'WC_Admin_Reports_Taxes_Data_Store',
- 'report-taxes-stats' => 'WC_Admin_Reports_Taxes_Stats_Data_Store',
- 'report-coupons' => 'WC_Admin_Reports_Coupons_Data_Store',
- 'report-coupons-stats' => 'WC_Admin_Reports_Coupons_Stats_Data_Store',
- 'report-downloads' => 'WC_Admin_Reports_Downloads_Data_Store',
- 'admin-note' => 'WC_Admin_Notes_Data_Store',
+ 'report-revenue-stats' => 'WC_Admin_Reports_Orders_Data_Store',
+ 'report-orders-stats' => 'WC_Admin_Reports_Orders_Data_Store',
+ 'report-products' => 'WC_Admin_Reports_Products_Data_Store',
+ 'report-variations' => 'WC_Admin_Reports_Variations_Data_Store',
+ 'report-products-stats' => 'WC_Admin_Reports_Products_Stats_Data_Store',
+ 'report-categories' => 'WC_Admin_Reports_Categories_Data_Store',
+ 'report-taxes' => 'WC_Admin_Reports_Taxes_Data_Store',
+ 'report-taxes-stats' => 'WC_Admin_Reports_Taxes_Stats_Data_Store',
+ 'report-coupons' => 'WC_Admin_Reports_Coupons_Data_Store',
+ 'report-coupons-stats' => 'WC_Admin_Reports_Coupons_Stats_Data_Store',
+ 'report-downloads' => 'WC_Admin_Reports_Downloads_Data_Store',
+ 'report-downloads-stats' => 'WC_Admin_Reports_Downloads_Stats_Data_Store',
+ 'admin-note' => 'WC_Admin_Notes_Data_Store',
+ 'report-customers' => 'WC_Admin_Reports_Customers_Data_Store',
)
);
}
@@ -373,6 +447,7 @@ class WC_Admin_Api_Init {
"{$wpdb->prefix}wc_order_coupon_lookup",
"{$wpdb->prefix}woocommerce_admin_notes",
"{$wpdb->prefix}woocommerce_admin_note_actions",
+ "{$wpdb->prefix}wc_customer_lookup",
)
);
}
@@ -401,6 +476,8 @@ class WC_Admin_Api_Init {
shipping_total double DEFAULT 0 NOT NULL,
net_total double DEFAULT 0 NOT NULL,
returning_customer boolean DEFAULT 0 NOT NULL,
+ status varchar(200) NOT NULL,
+ customer_id BIGINT UNSIGNED NOT NULL,
PRIMARY KEY (order_id),
KEY date_created (date_created)
) $collate;
@@ -469,6 +546,22 @@ class WC_Admin_Api_Init {
PRIMARY KEY (action_id),
KEY note_id (note_id)
) $collate;
+ CREATE TABLE {$wpdb->prefix}wc_customer_lookup (
+ customer_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
+ user_id BIGINT UNSIGNED DEFAULT NULL,
+ username varchar(60) DEFAULT '' NOT NULL,
+ first_name varchar(255) NOT NULL,
+ last_name varchar(255) NOT NULL,
+ email varchar(100) NOT NULL,
+ date_last_active timestamp DEFAULT '0000-00-00 00:00:00' NOT NULL,
+ date_registered timestamp NULL default null,
+ country char(2) DEFAULT '' NOT NULL,
+ postcode varchar(20) DEFAULT '' NOT NULL,
+ city varchar(100) DEFAULT '' NOT NULL,
+ PRIMARY KEY (customer_id),
+ UNIQUE KEY user_id (user_id),
+ KEY email (email)
+ ) $collate;
";
return $tables;
@@ -492,17 +585,7 @@ class WC_Admin_Api_Init {
// Initialize report tables.
add_action( 'woocommerce_after_register_post_type', array( 'WC_Admin_Api_Init', 'order_product_lookup_store_init' ), 20 );
- }
-
- /**
- * Enables the WP REST API for product categories
- *
- * @param array $args Default arguments for product_cat taxonomy.
- * @return array
- */
- public static function show_product_categories_in_rest( $args ) {
- $args['show_in_rest'] = true;
- return $args;
+ add_action( 'woocommerce_after_register_post_type', array( 'WC_Admin_Api_Init', 'customer_lookup_store_init' ), 20 );
}
}
diff --git a/plugins/woocommerce-admin/includes/class-wc-admin-reports-customers-query.php b/plugins/woocommerce-admin/includes/class-wc-admin-reports-customers-query.php
new file mode 100644
index 00000000000..937a0bf7b42
--- /dev/null
+++ b/plugins/woocommerce-admin/includes/class-wc-admin-reports-customers-query.php
@@ -0,0 +1,54 @@
+ '2018-07-19 00:00:00',
+ * 'registered_after' => '2018-07-05 00:00:00',
+ * 'page' => 2,
+ * 'avg_order_value_min' => 100,
+ * 'country' => 'GB',
+ * );
+ * $report = new WC_Admin_Reports_Customers_Query( $args );
+ * $mydata = $report->get_data();
+ *
+ * @package WooCommerce Admin/Classes
+ */
+
+defined( 'ABSPATH' ) || exit;
+
+/**
+ * WC_Admin_Reports_Customers_Query
+ */
+class WC_Admin_Reports_Customers_Query extends WC_Admin_Reports_Query {
+
+ /**
+ * Valid fields for Customers report.
+ *
+ * @return array
+ */
+ protected function get_default_query_vars() {
+ return array(
+ 'per_page' => get_option( 'posts_per_page' ), // not sure if this should be the default.
+ 'page' => 1,
+ 'order' => 'DESC',
+ 'orderby' => 'date_registered',
+ 'fields' => '*',
+ );
+ }
+
+ /**
+ * Get product data based on the current query vars.
+ *
+ * @return array
+ */
+ public function get_data() {
+ $args = apply_filters( 'woocommerce_reports_customers_query_args', $this->get_query_vars() );
+
+ $data_store = WC_Data_Store::load( 'report-customers' );
+ $results = $data_store->get_data( $args );
+ return apply_filters( 'woocommerce_reports_customers_select_query', $results, $args );
+ }
+
+}
diff --git a/plugins/woocommerce-admin/includes/class-wc-admin-reports-downloads-stats-query.php b/plugins/woocommerce-admin/includes/class-wc-admin-reports-downloads-stats-query.php
new file mode 100644
index 00000000000..21ea14fc7c7
--- /dev/null
+++ b/plugins/woocommerce-admin/includes/class-wc-admin-reports-downloads-stats-query.php
@@ -0,0 +1,37 @@
+get_query_vars() );
+
+ $data_store = WC_Data_Store::load( 'report-downloads-stats' );
+ $results = $data_store->get_data( $args );
+ return apply_filters( 'woocommerce_reports_downloads_stats_select_query', $results, $args );
+ }
+
+}
diff --git a/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php b/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php
index 936186294dc..672d1906fce 100644
--- a/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php
+++ b/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php
@@ -1,6 +1,6 @@
prefix . self::TABLE_NAME;
$sql_query_params = $this->get_time_period_sql_params( $query_args, $order_product_lookup_table );
- // Limit is left out here so that the grouping in code by PHP can be applied correctly.
- $sql_query_params = array_merge( $sql_query_params, $this->get_order_by_sql_params( $query_args ) );
// join wp_order_product_lookup_table with relationships and taxonomies
// @TODO: How to handle custom product tables?
$sql_query_params['from_clause'] .= " LEFT JOIN {$wpdb->prefix}term_relationships ON {$order_product_lookup_table}.product_id = {$wpdb->prefix}term_relationships.object_id";
$sql_query_params['from_clause'] .= " LEFT JOIN {$wpdb->prefix}term_taxonomy ON {$wpdb->prefix}term_relationships.term_taxonomy_id = {$wpdb->prefix}term_taxonomy.term_taxonomy_id";
+ // Limit is left out here so that the grouping in code by PHP can be applied correctly.
+ // This also needs to be put after the term_taxonomy JOIN so that we can match the correct term name.
+ $sql_query_params = $this->get_order_by_params( $query_args, $sql_query_params );
+
$included_categories = $this->get_included_categories( $query_args );
if ( $included_categories ) {
$sql_query_params['where_clause'] .= " AND {$wpdb->prefix}term_taxonomy.term_id IN ({$included_categories})";
@@ -100,6 +102,52 @@ class WC_Admin_Reports_Categories_Data_Store extends WC_Admin_Reports_Data_Store
return $sql_query_params;
}
+ /**
+ * Fills ORDER BY clause of SQL request based on user supplied parameters.
+ *
+ * @param array $query_args Parameters supplied by the user.
+ * @param array $sql_query Current SQL query array.
+ * @return array
+ */
+ protected function get_order_by_params( $query_args, $sql_query ) {
+ global $wpdb;
+ $lookup_table = $wpdb->prefix . self::TABLE_NAME;
+
+ $sql_query['order_by_clause'] = '';
+ if ( isset( $query_args['orderby'] ) ) {
+ $sql_query['order_by_clause'] = $this->normalize_order_by( $query_args['orderby'] );
+ }
+
+ if ( false !== strpos( $sql_query['order_by_clause'], '_terms' ) ) {
+ $sql_query['from_clause'] .= " JOIN {$wpdb->prefix}terms AS _terms ON {$wpdb->prefix}term_taxonomy.term_id = _terms.term_id";
+ }
+
+ if ( isset( $query_args['order'] ) ) {
+ $sql_query['order_by_clause'] .= ' ' . $query_args['order'];
+ } else {
+ $sql_query['order_by_clause'] .= ' DESC';
+ }
+
+ return $sql_query;
+ }
+
+ /**
+ * Maps ordering specified by the user to columns in the database/fields in the data.
+ *
+ * @param string $order_by Sorting criterion.
+ * @return string
+ */
+ protected function normalize_order_by( $order_by ) {
+ if ( 'date' === $order_by ) {
+ return 'time_interval';
+ }
+ if ( 'category' === $order_by ) {
+ return '_terms.name';
+ }
+ return $order_by;
+ }
+
+
/**
* Returns comma separated ids of included categories, based on query arguments from the user.
*
@@ -115,39 +163,6 @@ class WC_Admin_Reports_Categories_Data_Store extends WC_Admin_Reports_Data_Store
return $included_categories_str;
}
- /**
- * Compares values in 2 arrays based on criterion specified when called via sort_records.
- *
- * @param array $a Array 1 to compare.
- * @param array $b Array 2 to compare.
- * @return integer|WP_Error
- */
- private function sort_callback( $a, $b ) {
- if ( '' === $this->order_by || '' === $this->order ) {
- return new WP_Error( 'woocommerce_reports_categories_sort_failed', __( 'Sorry, fetching categories data failed.', 'wc-admin' ) );
- }
- if ( $a[ $this->order_by ] === $b[ $this->order_by ] ) {
- return 0;
- } elseif ( $a[ $this->order_by ] > $b[ $this->order_by ] ) {
- return strtolower( $this->order ) === 'desc' ? -1 : 1;
- } elseif ( $a[ $this->order_by ] < $b[ $this->order_by ] ) {
- return strtolower( $this->order ) === 'desc' ? 1 : -1;
- }
- }
-
- /**
- * Sorts the data based on given sorting criterion and order.
- *
- * @param array $data Data to sort.
- * @param string $sort_by Sorting criterion, any of the column_types keys.
- * @param string $direction Sorting direction: asc/desc.
- */
- protected function sort_records( &$data, $sort_by, $direction ) {
- $this->order_by = $this->normalize_order_by( $sort_by );
- $this->order = $direction;
- usort( $data, array( $this, 'sort_callback' ) );
- }
-
/**
* Returns the page of data according to page number and items per page.
*
@@ -223,7 +238,7 @@ class WC_Admin_Reports_Categories_Data_Store extends WC_Admin_Reports_Data_Store
$categories_data = $wpdb->get_results(
"SELECT
- term_id as category_id,
+ {$wpdb->prefix}term_taxonomy.term_id as category_id,
{$selections}
FROM
{$table_name}
@@ -234,6 +249,8 @@ class WC_Admin_Reports_Categories_Data_Store extends WC_Admin_Reports_Data_Store
{$sql_query_params['where_clause']}
GROUP BY
category_id
+ ORDER BY
+ {$sql_query_params['order_by_clause']}
",
ARRAY_A
); // WPCS: cache ok, DB call ok, unprepared SQL ok.
@@ -248,11 +265,8 @@ class WC_Admin_Reports_Categories_Data_Store extends WC_Admin_Reports_Data_Store
return $data;
}
- $this->sort_records( $categories_data, $query_args['orderby'], $query_args['order'] );
$categories_data = $this->page_records( $categories_data, $query_args['page'], $query_args['per_page'] );
-
$this->include_extended_info( $categories_data, $query_args );
-
$categories_data = array_map( array( $this, 'cast_numbers' ), $categories_data );
$data = (object) array(
'data' => $categories_data,
diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-coupons-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-coupons-data-store.php
index 95111752886..ca6a036b4c2 100644
--- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-coupons-data-store.php
+++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-coupons-data-store.php
@@ -94,6 +94,52 @@ class WC_Admin_Reports_Coupons_Data_Store extends WC_Admin_Reports_Data_Store im
return $sql_query_params;
}
+
+ /**
+ * Fills ORDER BY clause of SQL request based on user supplied parameters.
+ *
+ * @param array $query_args Parameters supplied by the user.
+ * @return array
+ */
+ protected function get_order_by_sql_params( $query_args ) {
+ global $wpdb;
+ $lookup_table = $wpdb->prefix . self::TABLE_NAME;
+ $sql_query = array();
+ $sql_query['from_clause'] = '';
+ $sql_query['order_by_clause'] = '';
+ if ( isset( $query_args['orderby'] ) ) {
+ $sql_query['order_by_clause'] = $this->normalize_order_by( $query_args['orderby'] );
+ }
+
+ if ( false !== strpos( $sql_query['order_by_clause'], '_coupons' ) ) {
+ $sql_query['from_clause'] .= " JOIN {$wpdb->prefix}posts AS _coupons ON {$lookup_table}.coupon_id = _coupons.ID";
+ }
+
+ if ( isset( $query_args['order'] ) ) {
+ $sql_query['order_by_clause'] .= ' ' . $query_args['order'];
+ } else {
+ $sql_query['order_by_clause'] .= ' DESC';
+ }
+
+ return $sql_query;
+ }
+
+ /**
+ * Maps ordering specified by the user to columns in the database/fields in the data.
+ *
+ * @param string $order_by Sorting criterion.
+ * @return string
+ */
+ protected function normalize_order_by( $order_by ) {
+ if ( 'date' === $order_by ) {
+ return 'time_interval';
+ }
+ if ( 'code' === $order_by ) {
+ return '_coupons.post_title';
+ }
+ return $order_by;
+ }
+
/**
* Enriches the coupon data with extra attributes.
*
diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-data-store.php
new file mode 100644
index 00000000000..16302ada7ef
--- /dev/null
+++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-data-store.php
@@ -0,0 +1,572 @@
+ 'intval',
+ 'user_id' => 'intval',
+ 'orders_count' => 'intval',
+ 'total_spend' => 'floatval',
+ 'avg_order_value' => 'floatval',
+ );
+
+ /**
+ * SQL columns to select in the db query and their mapping to SQL code.
+ *
+ * @var array
+ */
+ protected $report_columns = array(
+ 'customer_id' => 'customer_id',
+ 'user_id' => 'user_id',
+ 'username' => 'username',
+ 'name' => "CONCAT_WS( ' ', first_name, last_name ) as name", // TODO: what does this mean for RTL?
+ 'email' => 'email',
+ 'country' => 'country',
+ 'city' => 'city',
+ 'postcode' => 'postcode',
+ 'date_registered' => 'date_registered',
+ 'date_last_active' => 'date_last_active',
+ 'orders_count' => 'COUNT( order_id ) as orders_count',
+ 'total_spend' => 'SUM( gross_total ) as total_spend',
+ 'avg_order_value' => '( SUM( gross_total ) / COUNT( order_id ) ) as avg_order_value',
+ );
+
+ /**
+ * Constructor.
+ */
+ public function __construct() {
+ global $wpdb;
+
+ // Initialize some report columns that need disambiguation.
+ $this->report_columns['customer_id'] = $wpdb->prefix . self::TABLE_NAME . '.customer_id';
+ $this->report_columns['date_last_order'] = "MAX( {$wpdb->prefix}wc_order_stats.date_created ) as date_last_order";
+ }
+
+ /**
+ * Set up all the hooks for maintaining and populating table data.
+ */
+ public static function init() {
+ add_action( 'woocommerce_new_customer', array( __CLASS__, 'update_registered_customer' ) );
+ add_action( 'woocommerce_update_customer', array( __CLASS__, 'update_registered_customer' ) );
+ add_action( 'edit_user_profile_update', array( __CLASS__, 'update_registered_customer' ) );
+ add_action( 'updated_user_meta', array( __CLASS__, 'update_registered_customer_via_last_active' ), 10, 3 );
+ }
+
+ /**
+ * Trigger a customer update if their "last active" meta value was changed.
+ * Function expects to be hooked into the `updated_user_meta` action.
+ *
+ * @param int $meta_id ID of updated metadata entry.
+ * @param int $user_id ID of the user being updated.
+ * @param string $meta_key Meta key being updated.
+ */
+ public static function update_registered_customer_via_last_active( $meta_id, $user_id, $meta_key ) {
+ if ( 'wc_last_active' === $meta_key ) {
+ self::update_registered_customer( $user_id );
+ }
+ }
+
+ /**
+ * Maps ordering specified by the user to columns in the database/fields in the data.
+ *
+ * @param string $order_by Sorting criterion.
+ * @return string
+ */
+ protected function normalize_order_by( $order_by ) {
+ if ( 'name' === $order_by ) {
+ return "CONCAT_WS( ' ', first_name, last_name )";
+ }
+
+ return $order_by;
+ }
+
+ /**
+ * Fills ORDER BY clause of SQL request based on user supplied parameters.
+ *
+ * @param array $query_args Parameters supplied by the user.
+ * @return array
+ */
+ protected function get_order_by_sql_params( $query_args ) {
+ $sql_query['order_by_clause'] = '';
+
+ if ( isset( $query_args['orderby'] ) ) {
+ $sql_query['order_by_clause'] = $this->normalize_order_by( $query_args['orderby'] );
+ }
+
+ if ( isset( $query_args['order'] ) ) {
+ $sql_query['order_by_clause'] .= ' ' . $query_args['order'];
+ } else {
+ $sql_query['order_by_clause'] .= ' DESC';
+ }
+
+ return $sql_query;
+ }
+
+ /**
+ * Fills WHERE clause of SQL request with date-related constraints.
+ *
+ * @param array $query_args Parameters supplied by the user.
+ * @param string $table_name Name of the db table relevant for the date constraint.
+ * @return array
+ */
+ protected function get_time_period_sql_params( $query_args, $table_name ) {
+ global $wpdb;
+
+ $sql_query = array(
+ 'where_time_clause' => '',
+ 'where_clause' => '',
+ 'having_clause' => '',
+ );
+ $date_param_mapping = array(
+ 'registered' => array(
+ 'clause' => 'where',
+ 'column' => $table_name . '.date_registered',
+ ),
+ 'last_active' => array(
+ 'clause' => 'where',
+ 'column' => $table_name . '.date_last_active',
+ ),
+ 'last_order' => array(
+ 'clause' => 'having',
+ 'column' => "MAX( {$wpdb->prefix}wc_order_stats.date_created )",
+ ),
+ );
+ $match_operator = $this->get_match_operator( $query_args );
+ $where_time_clauses = array();
+ $having_time_clauses = array();
+
+ foreach ( $date_param_mapping as $query_param => $param_info ) {
+ $subclauses = array();
+ $before_arg = $query_param . '_before';
+ $after_arg = $query_param . '_after';
+ $column_name = $param_info['column'];
+
+ if ( ! empty( $query_args[ $before_arg ] ) ) {
+ $datetime = new DateTime( $query_args[ $before_arg ] );
+ $datetime_str = $datetime->format( WC_Admin_Reports_Interval::$sql_datetime_format );
+ $subclauses[] = "{$column_name} <= '$datetime_str'";
+ }
+
+ if ( ! empty( $query_args[ $after_arg ] ) ) {
+ $datetime = new DateTime( $query_args[ $after_arg ] );
+ $datetime_str = $datetime->format( WC_Admin_Reports_Interval::$sql_datetime_format );
+ $subclauses[] = "{$column_name} >= '$datetime_str'";
+ }
+
+ if ( $subclauses && ( 'where' === $param_info['clause'] ) ) {
+ $where_time_clauses[] = '(' . implode( ' AND ', $subclauses ) . ')';
+ }
+
+ if ( $subclauses && ( 'having' === $param_info['clause'] ) ) {
+ $having_time_clauses[] = '(' . implode( ' AND ', $subclauses ) . ')';
+ }
+ }
+
+ if ( $where_time_clauses ) {
+ $sql_query['where_time_clause'] = ' AND ' . implode( " {$match_operator} ", $where_time_clauses );
+ }
+
+ if ( $having_time_clauses ) {
+ $sql_query['having_clause'] = ' AND ' . implode( " {$match_operator} ", $having_time_clauses );
+ }
+
+ return $sql_query;
+ }
+
+ /**
+ * Updates the database query with parameters used for Customers report: categories and order status.
+ *
+ * @param array $query_args Query arguments supplied by the user.
+ * @return array Array of parameters used for SQL query.
+ */
+ protected function get_sql_query_params( $query_args ) {
+ global $wpdb;
+ $customer_lookup_table = $wpdb->prefix . self::TABLE_NAME;
+
+ $sql_query_params = $this->get_time_period_sql_params( $query_args, $customer_lookup_table );
+ $sql_query_params = array_merge( $sql_query_params, $this->get_limit_sql_params( $query_args ) );
+ $sql_query_params = array_merge( $sql_query_params, $this->get_order_by_sql_params( $query_args ) );
+
+ $match_operator = $this->get_match_operator( $query_args );
+ $where_clauses = array();
+ $having_clauses = array();
+
+ $exact_match_params = array(
+ 'username',
+ 'email',
+ 'country',
+ );
+
+ foreach ( $exact_match_params as $exact_match_param ) {
+ if ( ! empty( $query_args[ $exact_match_param ] ) ) {
+ $where_clauses[] = $wpdb->prepare(
+ "{$customer_lookup_table}.{$exact_match_param} = %s",
+ $query_args[ $exact_match_param ]
+ ); // WPCS: unprepared SQL ok.
+ }
+ }
+
+ if ( ! empty( $query_args['name'] ) ) {
+ $where_clauses[] = $wpdb->prepare( "CONCAT_WS( ' ', first_name, last_name ) = %s", $query_args['name'] );
+ }
+
+ $numeric_params = array(
+ 'orders_count' => array(
+ 'column' => 'COUNT( order_id )',
+ 'format' => '%d',
+ ),
+ 'total_spend' => array(
+ 'column' => 'SUM( gross_total )',
+ 'format' => '%f',
+ ),
+ 'avg_order_value' => array(
+ 'column' => '( SUM( gross_total ) / COUNT( order_id ) )',
+ 'format' => '%f',
+ ),
+ );
+
+ foreach ( $numeric_params as $numeric_param => $param_info ) {
+ $subclauses = array();
+ $min_param = $numeric_param . '_min';
+ $max_param = $numeric_param . '_max';
+
+ if ( isset( $query_args[ $min_param ] ) ) {
+ $subclauses[] = $wpdb->prepare(
+ "{$param_info['column']} >= {$param_info['format']}",
+ $query_args[ $min_param ]
+ ); // WPCS: unprepared SQL ok.
+ }
+
+ if ( isset( $query_args[ $max_param ] ) ) {
+ $subclauses[] = $wpdb->prepare(
+ "{$param_info['column']} <= {$param_info['format']}",
+ $query_args[ $max_param ]
+ ); // WPCS: unprepared SQL ok.
+ }
+
+ if ( $subclauses ) {
+ $having_clauses[] = '(' . implode( ' AND ', $subclauses ) . ')';
+ }
+ }
+
+ if ( $where_clauses ) {
+ $preceding_match = empty( $sql_query_params['where_time_clause'] ) ? ' AND ' : " {$match_operator} ";
+ $sql_query_params['where_clause'] = $preceding_match . implode( " {$match_operator} ", $where_clauses );
+ }
+
+ if ( $having_clauses ) {
+ $preceding_match = empty( $sql_query_params['having_clause'] ) ? ' AND ' : " {$match_operator} ";
+ $sql_query_params['having_clause'] .= $preceding_match . implode( " {$match_operator} ", $having_clauses );
+ }
+
+ return $sql_query_params;
+ }
+
+ /**
+ * Returns the report data based on parameters supplied by the user.
+ *
+ * @param array $query_args Query parameters.
+ * @return stdClass|WP_Error Data.
+ */
+ public function get_data( $query_args ) {
+ global $wpdb;
+
+ $customers_table_name = $wpdb->prefix . self::TABLE_NAME;
+ $order_stats_table_name = $wpdb->prefix . 'wc_order_stats';
+
+ // These defaults are only partially applied when used via REST API, as that has its own defaults.
+ $defaults = array(
+ 'per_page' => get_option( 'posts_per_page' ),
+ 'page' => 1,
+ 'order' => 'DESC',
+ 'orderby' => 'date_registered',
+ 'fields' => '*',
+ );
+ $query_args = wp_parse_args( $query_args, $defaults );
+
+ $cache_key = $this->get_cache_key( $query_args );
+ $data = wp_cache_get( $cache_key, $this->cache_group );
+
+ if ( false === $data ) {
+ $data = (object) array(
+ 'data' => array(),
+ 'total' => 0,
+ 'pages' => 0,
+ 'page_no' => 0,
+ );
+
+ $selections = $this->selected_columns( $query_args );
+ $sql_query_params = $this->get_sql_query_params( $query_args );
+
+ $db_records_count = (int) $wpdb->get_var(
+ "SELECT COUNT(*) FROM (
+ SELECT {$customers_table_name}.customer_id
+ FROM
+ {$customers_table_name}
+ LEFT JOIN
+ {$order_stats_table_name}
+ ON
+ {$customers_table_name}.customer_id = {$order_stats_table_name}.customer_id
+ WHERE
+ 1=1
+ {$sql_query_params['where_time_clause']}
+ {$sql_query_params['where_clause']}
+ GROUP BY
+ {$customers_table_name}.customer_id
+ HAVING
+ 1=1
+ {$sql_query_params['having_clause']}
+ ) as tt
+ "
+ ); // WPCS: cache ok, DB call ok, unprepared SQL ok.
+
+ $total_pages = (int) ceil( $db_records_count / $sql_query_params['per_page'] );
+ if ( $query_args['page'] < 1 || $query_args['page'] > $total_pages ) {
+ return $data;
+ }
+
+ $customer_data = $wpdb->get_results(
+ "SELECT
+ {$selections}
+ FROM
+ {$customers_table_name}
+ LEFT JOIN
+ {$order_stats_table_name}
+ ON
+ {$customers_table_name}.customer_id = {$order_stats_table_name}.customer_id
+ WHERE
+ 1=1
+ {$sql_query_params['where_time_clause']}
+ {$sql_query_params['where_clause']}
+ GROUP BY
+ {$customers_table_name}.customer_id
+ HAVING
+ 1=1
+ {$sql_query_params['having_clause']}
+ ORDER BY
+ {$sql_query_params['order_by_clause']}
+ {$sql_query_params['limit']}
+ ",
+ ARRAY_A
+ ); // WPCS: cache ok, DB call ok, unprepared SQL ok.
+
+ if ( null === $customer_data ) {
+ return $data;
+ }
+
+ $customer_data = array_map( array( $this, 'cast_numbers' ), $customer_data );
+ $data = (object) array(
+ 'data' => $customer_data,
+ 'total' => $db_records_count,
+ 'pages' => $total_pages,
+ 'page_no' => (int) $query_args['page'],
+ );
+
+ wp_cache_set( $cache_key, $data, $this->cache_group );
+ }
+
+ return $data;
+ }
+
+ /**
+ * Gets the guest (no user_id) customer ID or creates a new one for
+ * the corresponding billing email in the provided WC_Order
+ *
+ * @param WC_Order $order Order to get/create guest customer data with.
+ * @return int|false The ID of the retrieved/created customer, or false on error.
+ */
+ public function get_or_create_guest_customer_from_order( $order ) {
+ global $wpdb;
+
+ $email = $order->get_billing_email( 'edit' );
+
+ if ( empty( $email ) ) {
+ return false;
+ }
+
+ $existing_guest = $this->get_guest_by_email( $email );
+
+ if ( $existing_guest ) {
+ return $existing_guest['customer_id'];
+ }
+
+ $result = $wpdb->insert(
+ $wpdb->prefix . self::TABLE_NAME,
+ array(
+ 'first_name' => $order->get_billing_first_name( 'edit' ),
+ 'last_name' => $order->get_billing_last_name( 'edit' ),
+ 'email' => $email,
+ 'city' => $order->get_billing_city( 'edit' ),
+ 'postcode' => $order->get_billing_postcode( 'edit' ),
+ 'country' => $order->get_billing_country( 'edit' ),
+ 'date_last_active' => date( 'Y-m-d H:i:s', $order->get_date_created( 'edit' )->getTimestamp() ),
+ ),
+ array(
+ '%s',
+ '%s',
+ '%s',
+ '%s',
+ '%s',
+ '%s',
+ '%s',
+ )
+ );
+
+ return $result ? $wpdb->insert_id : false;
+ }
+
+ /**
+ * Retrieve a guest (no user_id) customer row by email.
+ *
+ * @param string $email Email address.
+ * @returns false|array Customer array if found, boolean false if not.
+ */
+ public function get_guest_by_email( $email ) {
+ global $wpdb;
+
+ $table_name = $wpdb->prefix . self::TABLE_NAME;
+ $guest_row = $wpdb->get_row(
+ $wpdb->prepare(
+ "SELECT * FROM {$table_name} WHERE email = %s AND user_id IS NULL LIMIT 1",
+ $email
+ ),
+ ARRAY_A
+ ); // WPCS: unprepared SQL ok.
+
+ if ( $guest_row ) {
+ return $this->cast_numbers( $guest_row );
+ }
+
+ return false;
+ }
+
+ /**
+ * Retrieve a registered customer row by user_id.
+ *
+ * @param string|int $user_id User ID.
+ * @returns false|array Customer array if found, boolean false if not.
+ */
+ public function get_customer_by_user_id( $user_id ) {
+ global $wpdb;
+
+ $table_name = $wpdb->prefix . self::TABLE_NAME;
+ $customer = $wpdb->get_row(
+ $wpdb->prepare(
+ "SELECT * FROM {$table_name} WHERE user_id = %d LIMIT 1",
+ $user_id
+ ),
+ ARRAY_A
+ ); // WPCS: unprepared SQL ok.
+
+ if ( $customer ) {
+ return $this->cast_numbers( $customer );
+ }
+
+ return false;
+ }
+
+ /**
+ * Retrieve a registered customer row id by user_id.
+ *
+ * @param string|int $user_id User ID.
+ * @returns false|int Customer ID if found, boolean false if not.
+ */
+ public static function get_customer_id_by_user_id( $user_id ) {
+ global $wpdb;
+
+ $table_name = $wpdb->prefix . self::TABLE_NAME;
+ $customer_id = $wpdb->get_var(
+ $wpdb->prepare(
+ "SELECT customer_id FROM {$table_name} WHERE user_id = %d LIMIT 1",
+ $user_id
+ )
+ ); // WPCS: unprepared SQL ok.
+
+ return $customer_id ? (int) $customer_id : false;
+ }
+
+ /**
+ * Update the database with customer data.
+ *
+ * @param int $user_id WP User ID to update customer data for.
+ * @return int|bool|null Number or rows modified or false on failure.
+ */
+ public static function update_registered_customer( $user_id ) {
+ global $wpdb;
+
+ $customer = new WC_Customer( $user_id );
+
+ if ( $customer->get_id() != $user_id ) {
+ return false;
+ }
+
+ $last_active = $customer->get_meta( 'wc_last_active', true, 'edit' );
+ $data = array(
+ 'user_id' => $user_id,
+ 'username' => $customer->get_username( 'edit' ),
+ 'first_name' => $customer->get_first_name( 'edit' ),
+ 'last_name' => $customer->get_last_name( 'edit' ),
+ 'email' => $customer->get_email( 'edit' ),
+ 'city' => $customer->get_billing_city( 'edit' ),
+ 'postcode' => $customer->get_billing_postcode( 'edit' ),
+ 'country' => $customer->get_billing_country( 'edit' ),
+ 'date_registered' => date( 'Y-m-d H:i:s', $customer->get_date_created( 'edit' )->getTimestamp() ),
+ 'date_last_active' => $last_active ? date( 'Y-m-d H:i:s', $last_active ) : '',
+ );
+ $format = array(
+ '%d',
+ '%s',
+ '%s',
+ '%s',
+ '%s',
+ '%s',
+ '%s',
+ '%s',
+ '%s',
+ '%s',
+ );
+
+ $customer_id = self::get_customer_id_by_user_id( $user_id );
+
+ if ( $customer_id ) {
+ // Preserve customer_id for existing user_id.
+ $data['customer_id'] = $customer_id;
+ $format[] = '%d';
+ }
+
+ return $wpdb->replace( $wpdb->prefix . self::TABLE_NAME, $data, $format );
+ }
+
+ /**
+ * Returns string to be used as cache key for the data.
+ *
+ * @param array $params Query parameters.
+ * @return string
+ */
+ protected function get_cache_key( $params ) {
+ return 'woocommerce_' . self::TABLE_NAME . '_' . md5( wp_json_encode( $params ) );
+ }
+
+}
diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-data-store.php
index 83b16a19740..d44282b5d3f 100644
--- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-data-store.php
+++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-data-store.php
@@ -180,6 +180,71 @@ class WC_Admin_Reports_Data_Store {
$data->intervals = array_slice( $data->intervals, $offset, $count );
}
+ /**
+ * Returns expected number of items on the page in case of date ordering.
+ *
+ * @param int $expected_interval_count Expected number of intervals in total.
+ * @param int $items_per_page Number of items per page.
+ * @param int $page_no Page number.
+ *
+ * @return float|int
+ */
+ protected function expected_intervals_on_page( $expected_interval_count, $items_per_page, $page_no ) {
+ $total_pages = (int) ceil( $expected_interval_count / $items_per_page );
+ if ( $page_no < $total_pages ) {
+ return $items_per_page;
+ } elseif ( $page_no === $total_pages ) {
+ return $expected_interval_count - ( $page_no - 1 ) * $items_per_page;
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Returns true if there are any intervals that need to be filled in the response.
+ *
+ * @param int $expected_interval_count Expected number of intervals in total.
+ * @param int $db_records Total number of records for given period in the database.
+ * @param int $items_per_page Number of items per page.
+ * @param int $page_no Page number.
+ * @param string $order asc or desc.
+ * @param string $order_by Column by which the result will be sorted.
+ * @param int $intervals_count Number of records for given (possibly shortened) time interval.
+ *
+ * @return bool
+ */
+ protected function intervals_missing( $expected_interval_count, $db_records, $items_per_page, $page_no, $order, $order_by, $intervals_count ) {
+ if ( $expected_interval_count > $db_records ) {
+ if ( 'date' === $order_by ) {
+ $expected_intervals_on_page = $this->expected_intervals_on_page( $expected_interval_count, $items_per_page, $page_no );
+ if ( $intervals_count < $expected_intervals_on_page ) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ if ( 'desc' === $order ) {
+ if ( $page_no > floor( $db_records / $items_per_page ) ) {
+ return true;
+ } else {
+ return false;
+ }
+ } elseif ( 'asc' === $order ) {
+ if ( $page_no <= ceil( ( $expected_interval_count - $db_records ) / $items_per_page ) ) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ // Invalid ordering.
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+
/**
* Updates the LIMIT query part for Intervals query of the report.
*
@@ -346,7 +411,7 @@ class WC_Admin_Reports_Data_Store {
* @param string $status Order status.
* @return string
*/
- protected function normalize_order_status( $status ) {
+ protected static function normalize_order_status( $status ) {
$status = trim( $status );
return 'wc-' . $status;
}
@@ -709,14 +774,14 @@ class WC_Admin_Reports_Data_Store {
if ( isset( $query_args['status_is'] ) && is_array( $query_args['status_is'] ) && count( $query_args['status_is'] ) > 0 ) {
$allowed_statuses = array_map( array( $this, 'normalize_order_status' ), $query_args['status_is'] );
if ( $allowed_statuses ) {
- $subqueries[] = "{$wpdb->prefix}posts.post_status IN ( '" . implode( "','", $allowed_statuses ) . "' )";
+ $subqueries[] = "{$wpdb->prefix}wc_order_stats.status IN ( '" . implode( "','", $allowed_statuses ) . "' )";
}
}
if ( isset( $query_args['status_is_not'] ) && is_array( $query_args['status_is_not'] ) && count( $query_args['status_is_not'] ) > 0 ) {
$forbidden_statuses = array_map( array( $this, 'normalize_order_status' ), $query_args['status_is_not'] );
if ( $forbidden_statuses ) {
- $subqueries[] = "{$wpdb->prefix}posts.post_status NOT IN ( '" . implode( "','", $forbidden_statuses ) . "' )";
+ $subqueries[] = "{$wpdb->prefix}wc_order_stats.status NOT IN ( '" . implode( "','", $forbidden_statuses ) . "' )";
}
}
diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-downloads-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-downloads-data-store.php
index 86555a8b1ec..8f644b31d21 100644
--- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-downloads-data-store.php
+++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-downloads-data-store.php
@@ -73,7 +73,6 @@ class WC_Admin_Reports_Downloads_Data_Store extends WC_Admin_Reports_Data_Store
$sql_query_params = $this->get_time_period_sql_params( $query_args, $lookup_table );
$sql_query_params = array_merge( $sql_query_params, $this->get_limit_sql_params( $query_args ) );
- $sql_query_params = array_merge( $sql_query_params, $this->get_order_by_sql_params( $query_args ) );
$included_products = $this->get_included_products( $query_args );
$excluded_products = $this->get_excluded_products( $query_args );
@@ -163,6 +162,7 @@ class WC_Admin_Reports_Downloads_Data_Store extends WC_Admin_Reports_Data_Store
}
$sql_query_params['from_clause'] .= " JOIN {$wpdb->prefix}woocommerce_downloadable_product_permissions as product_permissions ON {$lookup_table}.permission_id = product_permissions.permission_id";
+ $sql_query_params = $this->get_order_by( $query_args, $sql_query_params );
return $sql_query_params;
}
@@ -240,14 +240,20 @@ class WC_Admin_Reports_Downloads_Data_Store extends WC_Admin_Reports_Data_Store
* Fills ORDER BY clause of SQL request based on user supplied parameters.
*
* @param array $query_args Parameters supplied by the user.
+ * @param array $sql_query Current SQL query array.
* @return array
*/
- protected function get_order_by_sql_params( $query_args ) {
+ protected function get_order_by( $query_args, $sql_query ) {
+ global $wpdb;
$sql_query['order_by_clause'] = '';
if ( isset( $query_args['orderby'] ) ) {
$sql_query['order_by_clause'] = $this->normalize_order_by( $query_args['orderby'] );
}
+ if ( false !== strpos( $sql_query['order_by_clause'], '_products' ) ) {
+ $sql_query['from_clause'] .= " JOIN {$wpdb->prefix}posts AS _products ON product_permissions.product_id = _products.ID";
+ }
+
if ( isset( $query_args['order'] ) ) {
$sql_query['order_by_clause'] .= ' ' . $query_args['order'];
} else {
@@ -377,6 +383,10 @@ class WC_Admin_Reports_Downloads_Data_Store extends WC_Admin_Reports_Data_Store
return $wpdb->prefix . 'wc_download_log.timestamp';
}
+ if ( 'product' === $order_by ) {
+ return '_products.post_title';
+ }
+
return $order_by;
}
diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-downloads-stats-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-downloads-stats-data-store.php
new file mode 100644
index 00000000000..c08e6bc9256
--- /dev/null
+++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-downloads-stats-data-store.php
@@ -0,0 +1,232 @@
+ 'intval',
+ );
+
+ /**
+ * SQL columns to select in the db query and their mapping to SQL code.
+ *
+ * @var array
+ */
+ protected $report_columns = array(
+ 'download_count' => 'COUNT(DISTINCT download_log_id) as download_count',
+ );
+
+ /**
+ * Constructor
+ */
+ public function __construct() {
+ global $wpdb;
+ }
+
+
+ /**
+ * Returns the report data based on parameters supplied by the user.
+ *
+ * @param array $query_args Query parameters.
+ * @return stdClass|WP_Error Data.
+ */
+ public function get_data( $query_args ) {
+ global $wpdb;
+
+ $table_name = $wpdb->prefix . self::TABLE_NAME;
+ $now = time();
+ $week_back = $now - WEEK_IN_SECONDS;
+
+ // These defaults are only partially applied when used via REST API, as that has its own defaults.
+ $defaults = array(
+ 'per_page' => get_option( 'posts_per_page' ),
+ 'page' => 1,
+ 'order' => 'DESC',
+ 'orderby' => 'date',
+ 'fields' => '*',
+ 'interval' => 'week',
+ );
+ $query_args = wp_parse_args( $query_args, $defaults );
+
+ if ( empty( $query_args['before'] ) ) {
+ $query_args['before'] = date( WC_Admin_Reports_Interval::$iso_datetime_format, $now );
+ }
+ if ( empty( $query_args['after'] ) ) {
+ $query_args['after'] = date( WC_Admin_Reports_Interval::$iso_datetime_format, $week_back );
+ }
+
+ $cache_key = $this->get_cache_key( $query_args );
+ $data = wp_cache_get( $cache_key, $this->cache_group );
+
+ if ( false === $data ) {
+ $selections = $this->selected_columns( $query_args );
+ $sql_query_params = $this->get_sql_query_params( $query_args );
+ $totals_query = array_merge( array(), $this->get_time_period_sql_params( $query_args, $table_name ) );
+ $intervals_query = array_merge( array(), $this->get_intervals_sql_params( $query_args, $table_name ) );
+
+ $totals_query['where_clause'] .= $sql_query_params['where_clause'];
+ $totals_query['from_clause'] .= $sql_query_params['from_clause'];
+ $intervals_query['where_clause'] .= $sql_query_params['where_clause'];
+ $intervals_query['from_clause'] .= $sql_query_params['from_clause'];
+ $intervals_query['select_clause'] = str_replace( 'date_created', 'timestamp', $intervals_query['select_clause'] );
+ $intervals_query['where_time_clause'] = str_replace( 'date_created', 'timestamp', $intervals_query['where_time_clause'] );
+
+ $db_intervals = $wpdb->get_col(
+ "SELECT
+ {$intervals_query['select_clause']} AS time_interval
+ FROM
+ {$table_name}
+ {$intervals_query['from_clause']}
+ WHERE
+ 1=1
+ {$intervals_query['where_time_clause']}
+ {$intervals_query['where_clause']}
+ GROUP BY
+ time_interval"
+ ); // WPCS: cache ok, DB call ok, , unprepared SQL ok.
+
+ $db_records_count = count( $db_intervals );
+
+ $expected_interval_count = WC_Admin_Reports_Interval::intervals_between( $query_args['after'], $query_args['before'], $query_args['interval'] );
+ $total_pages = (int) ceil( $expected_interval_count / $intervals_query['per_page'] );
+ if ( $query_args['page'] < 1 || $query_args['page'] > $total_pages ) {
+ return array();
+ }
+
+ $this->update_intervals_sql_params( $intervals_query, $query_args, $db_records_count, $expected_interval_count );
+ $intervals_query['where_time_clause'] = str_replace( 'date_created', 'timestamp', $intervals_query['where_time_clause'] );
+
+ $totals = $wpdb->get_results(
+ "SELECT
+ {$selections}
+ FROM
+ {$table_name}
+ {$totals_query['from_clause']}
+ WHERE
+ 1=1
+ {$totals_query['where_time_clause']}
+ {$totals_query['where_clause']}",
+ ARRAY_A
+ ); // WPCS: cache ok, DB call ok, unprepared SQL ok.
+
+ if ( null === $totals ) {
+ return new WP_Error( 'woocommerce_reports_downloads_stats_result_failed', __( 'Sorry, fetching downloads data failed.', 'wc-admin' ) );
+ }
+
+ if ( '' !== $selections ) {
+ $selections = ', ' . $selections;
+ }
+
+ $intervals = $wpdb->get_results(
+ "SELECT
+ MAX(timestamp) AS datetime_anchor,
+ {$intervals_query['select_clause']} AS time_interval
+ {$selections}
+ FROM
+ {$table_name}
+ {$intervals_query['from_clause']}
+ WHERE
+ 1=1
+ {$intervals_query['where_time_clause']}
+ {$intervals_query['where_clause']}
+ GROUP BY
+ time_interval
+ ORDER BY
+ {$intervals_query['order_by_clause']}
+ {$intervals_query['limit']}",
+ ARRAY_A
+ ); // WPCS: cache ok, DB call ok, unprepared SQL ok.
+
+ if ( null === $intervals ) {
+ return new WP_Error( 'woocommerce_reports_downloads_stats_result_failed', __( 'Sorry, fetching downloads data failed.', 'wc-admin' ) );
+ }
+
+ $totals = (object) $this->cast_numbers( $totals[0] );
+ $data = (object) array(
+ 'totals' => $totals,
+ 'intervals' => $intervals,
+ 'total' => $expected_interval_count,
+ 'pages' => $total_pages,
+ 'page_no' => (int) $query_args['page'],
+ );
+
+ if ( $this->intervals_missing( $expected_interval_count, $db_records_count, $intervals_query['per_page'], $query_args['page'], $query_args['order'], $query_args['orderby'], count( $intervals ) ) ) {
+ $this->fill_in_missing_intervals( $db_intervals, $query_args['adj_after'], $query_args['adj_before'], $query_args['interval'], $data );
+ $this->sort_intervals( $data, $query_args['orderby'], $query_args['order'] );
+ $this->remove_extra_records( $data, $query_args['page'], $intervals_query['per_page'], $db_records_count, $expected_interval_count, $query_args['orderby'] );
+ } else {
+ $this->update_interval_boundary_dates( $query_args['after'], $query_args['before'], $query_args['interval'], $data->intervals );
+ }
+ $this->create_interval_subtotals( $data->intervals );
+
+ wp_cache_set( $cache_key, $data, $this->cache_group );
+ }
+
+ return $data;
+ }
+
+ /**
+ * Returns string to be used as cache key for the data.
+ *
+ * @param array $params Query parameters.
+ * @return string
+ */
+ protected function get_cache_key( $params ) {
+ return 'woocommerce_' . self::TABLE_NAME . '_stats_' . md5( wp_json_encode( $params ) );
+ }
+
+ /**
+ * Sorts intervals according to user's request.
+ *
+ * They are pre-sorted in SQL, but after adding gaps, they need to be sorted including the added ones.
+ *
+ * @param stdClass $data Data object, must contain an array under $data->intervals.
+ * @param string $sort_by Ordering property.
+ * @param string $direction DESC/ASC.
+ */
+ protected function sort_intervals( &$data, $sort_by, $direction ) {
+ if ( 'date' === $sort_by ) {
+ $this->order_by = 'time_interval';
+ } else {
+ $this->order_by = $sort_by;
+ }
+
+ $this->order = $direction;
+ usort( $data->intervals, array( $this, 'interval_cmp' ) );
+ }
+
+ /**
+ * Compares two report data objects by pre-defined object property and ASC/DESC ordering.
+ *
+ * @param stdClass $a Object a.
+ * @param stdClass $b Object b.
+ * @return string
+ */
+ protected function interval_cmp( $a, $b ) {
+ if ( '' === $this->order_by || '' === $this->order ) {
+ return 0;
+ }
+ if ( $a[ $this->order_by ] === $b[ $this->order_by ] ) {
+ return 0;
+ } elseif ( $a[ $this->order_by ] > $b[ $this->order_by ] ) {
+ return strtolower( $this->order ) === 'desc' ? -1 : 1;
+ } elseif ( $a[ $this->order_by ] < $b[ $this->order_by ] ) {
+ return strtolower( $this->order ) === 'desc' ? 1 : -1;
+ }
+ }
+
+}
diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-orders-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-orders-data-store.php
index 92afec105c9..b467d8c4266 100644
--- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-orders-data-store.php
+++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-orders-data-store.php
@@ -171,10 +171,8 @@ class WC_Admin_Reports_Orders_Data_Store extends WC_Admin_Reports_Data_Store imp
)";
}
- // TODO: move order status to wc_order_stats so that JOIN is not necessary.
$order_status_filter = $this->get_status_subquery( $query_args, $operator );
if ( $order_status_filter ) {
- $from_clause .= " JOIN {$wpdb->prefix}posts ON {$orders_stats_table}.order_id = {$wpdb->prefix}posts.ID";
$where_filters[] = $order_status_filter;
}
@@ -1268,7 +1266,7 @@ class WC_Admin_Reports_Orders_Data_Store extends WC_Admin_Reports_Data_Store imp
return;
}
- $data = array(
+ $data = array(
'order_id' => $order->get_id(),
'date_created' => $order->get_date_created()->date( 'Y-m-d H:i:s' ),
'num_items_sold' => self::get_num_items_sold( $order ),
@@ -1279,24 +1277,48 @@ class WC_Admin_Reports_Orders_Data_Store extends WC_Admin_Reports_Data_Store imp
'shipping_total' => $order->get_shipping_total(),
'net_total' => (float) $order->get_total() - (float) $order->get_total_tax() - (float) $order->get_shipping_total(),
'returning_customer' => self::is_returning_customer( $order ),
+ 'status' => self::normalize_order_status( $order->get_status() ),
+ );
+ $format = array(
+ '%d',
+ '%s',
+ '%d',
+ '%f',
+ '%f',
+ '%f',
+ '%f',
+ '%f',
+ '%f',
+ '%d',
+ '%s',
);
+ // Ensure we're associating this order with a Customer in the lookup table.
+ $order_user_id = $order->get_customer_id();
+ $customers_data_store = new WC_Admin_Reports_Customers_Data_Store();
+
+ if ( 0 === $order_user_id ) {
+ $email = $order->get_billing_email( 'edit' );
+
+ if ( $email ) {
+ $customer_id = $customers_data_store->get_or_create_guest_customer_from_order( $order );
+
+ if ( $customer_id ) {
+ $data['customer_id'] = $customer_id;
+ $format[] = '%d';
+ }
+ }
+ } else {
+ $customer = $customers_data_store->get_customer_by_user_id( $order_user_id );
+
+ if ( $customer && $customer['customer_id'] ) {
+ $data['customer_id'] = $customer['customer_id'];
+ $format[] = '%d';
+ }
+ }
+
// Update or add the information to the DB.
- return $wpdb->replace(
- $table_name,
- $data,
- array(
- '%d',
- '%s',
- '%d',
- '%f',
- '%f',
- '%f',
- '%f',
- '%f',
- '%f',
- )
- );
+ return $wpdb->replace( $table_name, $data, $format );
}
/**
diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-products-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-products-data-store.php
index 09feb580f70..6d5e4b5cf05 100644
--- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-products-data-store.php
+++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-products-data-store.php
@@ -100,6 +100,10 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
$sql_query['from_clause'] .= " JOIN {$wpdb->prefix}posts AS _products ON {$order_product_lookup_table}.product_id = _products.ID";
}
+ if ( 'postmeta.meta_value' === $sql_query['order_by_clause'] ) {
+ $sql_query['from_clause'] .= " JOIN {$wpdb->prefix}postmeta AS postmeta ON {$order_product_lookup_table}.product_id = postmeta.post_id AND postmeta.meta_key = '_sku'";
+ }
+
if ( isset( $query_args['order'] ) ) {
$sql_query['order_by_clause'] .= ' ' . $query_args['order'];
} else {
@@ -150,7 +154,9 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
if ( 'product_name' === $order_by ) {
return '_products.post_title';
}
-
+ if ( 'sku' === $order_by ) {
+ return 'postmeta.meta_value';
+ }
return $order_by;
}
diff --git a/plugins/woocommerce-admin/lib/admin.php b/plugins/woocommerce-admin/lib/admin.php
index b44ac05158f..78b3995e82a 100644
--- a/plugins/woocommerce-admin/lib/admin.php
+++ b/plugins/woocommerce-admin/lib/admin.php
@@ -399,6 +399,11 @@ function wc_admin_get_user_data_fields() {
'revenue_report_columns',
'taxes_report_columns',
'variations_report_columns',
+ 'dashboard_charts',
+ 'dashboard_chart_type',
+ 'dashboard_chart_interval',
+ 'dashboard_leaderboards',
+ 'dashboard_leaderboard_rows',
);
return apply_filters( 'wc_admin_get_user_data_fields', $user_data_fields );
diff --git a/plugins/woocommerce-admin/lib/client-assets.php b/plugins/woocommerce-admin/lib/client-assets.php
index 8e876376ceb..c49f2209d5f 100644
--- a/plugins/woocommerce-admin/lib/client-assets.php
+++ b/plugins/woocommerce-admin/lib/client-assets.php
@@ -180,9 +180,6 @@ function wc_admin_print_script_settings() {
'embedBreadcrumbs' => wc_admin_get_embed_breadcrumbs(),
'siteLocale' => esc_attr( get_bloginfo( 'language' ) ),
'currency' => wc_admin_currency_settings(),
- 'date' => array(
- 'dow' => get_option( 'start_of_week', 0 ),
- ),
'orderStatuses' => format_order_statuses( wc_get_order_statuses() ),
'stockStatuses' => wc_get_product_stock_status_options(),
'siteTitle' => get_bloginfo( 'name' ),
diff --git a/plugins/woocommerce-admin/package-lock.json b/plugins/woocommerce-admin/package-lock.json
index 8bafe1db940..7b3be3b282e 100644
--- a/plugins/woocommerce-admin/package-lock.json
+++ b/plugins/woocommerce-admin/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "wc-admin",
- "version": "0.3.0",
+ "version": "0.4.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -71,7 +71,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
}
@@ -233,13 +233,13 @@
}
},
"@babel/helper-replace-supers": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.2.3.tgz",
- "integrity": "sha512-GyieIznGUfPXPWu0yLS6U55Mz67AZD9cUk0BfirOWlPrXlBcan9Gz+vHGz+cPfuoweZSnPzPIm67VtQM0OWZbA==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.1.0.tgz",
+ "integrity": "sha512-BvcDWYZRWVuDeXTYZWxekQNO5D4kO55aArwZOTFXw6rlLQA8ZaDicJR1sO47h+HrnCiDFiww0fSPV0d713KBGQ==",
"requires": {
"@babel/helper-member-expression-to-functions": "^7.0.0",
"@babel/helper-optimise-call-expression": "^7.0.0",
- "@babel/traverse": "^7.2.3",
+ "@babel/traverse": "^7.1.0",
"@babel/types": "^7.0.0"
}
},
@@ -293,9 +293,9 @@
}
},
"@babel/parser": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.2.3.tgz",
- "integrity": "sha512-0LyEcVlfCoFmci8mXx8A5oIkpkOgyo8dRHtxBnK9RRBwxO2+JZPNsqtVEZQ7mJFPxnXF9lfmU24mHOPI0qnlkA=="
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.2.2.tgz",
+ "integrity": "sha512-UNTmQ5cSLDeBGBl+s7JeowkqIHgmFAGBnLDdIzFmUNSuS5JF0XBcN59jsh/vJO/YjfsBqMxhMjoFGmNExmf0FA=="
},
"@babel/plugin-proposal-async-generator-functions": {
"version": "7.2.0",
@@ -648,9 +648,9 @@
}
},
"@babel/preset-env": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.2.3.tgz",
- "integrity": "sha512-AuHzW7a9rbv5WXmvGaPX7wADxFkZIqKlbBh1dmZUQp4iwiPpkE/Qnrji6SC4UQCQzvWY/cpHET29eUhXS9cLPw==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.2.0.tgz",
+ "integrity": "sha512-haGR38j5vOGVeBatrQPr3l0xHbs14505DcM57cbJy48kgMFvvHHoYEhHuRV+7vi559yyAUAVbTWzbK/B/pzJng==",
"requires": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/helper-plugin-utils": "^7.0.0",
@@ -723,15 +723,15 @@
}
},
"@babel/traverse": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz",
- "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==",
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.2.tgz",
+ "integrity": "sha512-E5Bn9FSwHpSkUhthw/XEuvFZxIgrqb9M8cX8j5EUQtrUG5DQUy6bFyl7G7iQ1D1Czudor+xkmp81JbLVVM0Sjg==",
"requires": {
"@babel/code-frame": "^7.0.0",
"@babel/generator": "^7.2.2",
"@babel/helper-function-name": "^7.1.0",
"@babel/helper-split-export-declaration": "^7.0.0",
- "@babel/parser": "^7.2.3",
+ "@babel/parser": "^7.2.2",
"@babel/types": "^7.2.2",
"debug": "^4.1.0",
"globals": "^11.1.0",
@@ -756,20 +756,15 @@
"@babel/runtime-corejs2": "^7.1.5"
}
},
- "@icons/material": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz",
- "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw=="
- },
"@lerna/add": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.7.2.tgz",
- "integrity": "sha512-/kCuyytOEmYcqpbU8MhHc2/3bPJjEx+qq7SOdb0cCDG+QcJ/oSsDCZ3xVHxhyLRYAoRlKBch3DiBmY4BeIm0Ag==",
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.8.2.tgz",
+ "integrity": "sha512-P9U5fzvrINVcslfn2CoMoRH0k+skwNTEsBTYkqjRf+ZYaaM3PvKzXvnonMfPSLBgAK3bBMnzinfb3USJnStx2w==",
"dev": true,
"requires": {
- "@lerna/bootstrap": "^3.7.2",
- "@lerna/command": "^3.7.2",
- "@lerna/filter-options": "^3.6.0",
+ "@lerna/bootstrap": "^3.8.2",
+ "@lerna/command": "^3.8.1",
+ "@lerna/filter-options": "^3.8.1",
"@lerna/npm-conf": "^3.7.0",
"@lerna/validation-error": "^3.6.0",
"dedent": "^0.7.0",
@@ -790,23 +785,23 @@
}
},
"@lerna/bootstrap": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.7.2.tgz",
- "integrity": "sha512-yVjr450UivC7gbIh3GZowJ6bzPy/xC75bduq2Zm+jdIksjM/8SA3HRXWNothaSyZWudV+WY+cy6MvwrtFe8Kbg==",
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.8.2.tgz",
+ "integrity": "sha512-/MT2krnth21mI2t3S6M1FJ4MUt+h+ycwcSfHhDMsgqfPqtb6y7awWlAFjHzgWXxf1LUOStkIOoGsJGNsxjiXWQ==",
"dev": true,
"requires": {
"@lerna/batch-packages": "^3.6.0",
- "@lerna/command": "^3.7.2",
- "@lerna/filter-options": "^3.6.0",
+ "@lerna/command": "^3.8.1",
+ "@lerna/filter-options": "^3.8.1",
"@lerna/has-npm-version": "^3.3.0",
- "@lerna/npm-install": "^3.6.0",
+ "@lerna/npm-install": "^3.8.2",
"@lerna/package-graph": "^3.6.0",
"@lerna/pulse-till-done": "^3.7.1",
"@lerna/rimraf-dir": "^3.6.0",
- "@lerna/run-lifecycle": "^3.7.1",
+ "@lerna/run-lifecycle": "^3.8.2",
"@lerna/run-parallel-batches": "^3.0.0",
"@lerna/symlink-binary": "^3.7.2",
- "@lerna/symlink-dependencies": "^3.7.2",
+ "@lerna/symlink-dependencies": "^3.8.1",
"@lerna/validation-error": "^3.6.0",
"dedent": "^0.7.0",
"get-port": "^3.2.0",
@@ -821,25 +816,25 @@
}
},
"@lerna/changed": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.8.0.tgz",
- "integrity": "sha512-IeOxB+nwGFpAuEgUi9FeP19hj6Abp1aNCeMjS9/KpOxrSGt3ejKlSKY83lwqDPbb6OnthQTRBlodWZpSiSPWqg==",
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.8.2.tgz",
+ "integrity": "sha512-NMxLftHcNVZH+kdL9qylD4c/ZYljQ7YOQdgrc97ds23dk11UhLVAkbbpRVU5DE/s+bqo03zROVHPEYT+ELQjWg==",
"dev": true,
"requires": {
- "@lerna/collect-updates": "^3.6.0",
- "@lerna/command": "^3.7.2",
+ "@lerna/collect-updates": "^3.8.1",
+ "@lerna/command": "^3.8.1",
"@lerna/listable": "^3.6.0",
"@lerna/output": "^3.6.0",
- "@lerna/version": "^3.8.0"
+ "@lerna/version": "^3.8.2"
}
},
"@lerna/check-working-tree": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-3.6.0.tgz",
- "integrity": "sha512-Ioy1t2aVasAwhY1Oi5kfpwbW9RDupxxVVu2t2c1EeBYYCu3jIt1A5ad34gidgsKyiG3HeBEVziI4Uaihnb96ZQ==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-3.8.1.tgz",
+ "integrity": "sha512-UJqyvFr3+MTDo31fVjJlV/eshmQg8u0vpQcY95Vs00B99QxzLoICSGpNdldhSBnOIpOlq6tm5H/2hflc5hANew==",
"dev": true,
"requires": {
- "@lerna/describe-ref": "^3.6.0",
+ "@lerna/describe-ref": "^3.8.1",
"@lerna/validation-error": "^3.6.0"
}
},
@@ -890,17 +885,27 @@
"requires": {
"pump": "^3.0.0"
}
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
}
}
},
"@lerna/clean": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-3.7.2.tgz",
- "integrity": "sha512-BhuPnAWQa2av6hSE8imbOhenUnveSp0VDO1X0jzC1EX+K6sBCubbowM13kYi+N0qUd2kdeatBNwmafzkBZ3LcQ==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-3.8.1.tgz",
+ "integrity": "sha512-+jxuiKdvau3tlhiMq1cQMzzdr/4b95q4Cmpt8BD5ivrEpD+X3pCJGjjMxybpi5sZzR/XWlfJn9vn9mnFpyTrTA==",
"dev": true,
"requires": {
- "@lerna/command": "^3.7.2",
- "@lerna/filter-options": "^3.6.0",
+ "@lerna/command": "^3.8.1",
+ "@lerna/filter-options": "^3.8.1",
"@lerna/prompt": "^3.6.0",
"@lerna/pulse-till-done": "^3.7.1",
"@lerna/rimraf-dir": "^3.6.0",
@@ -1044,6 +1049,16 @@
"integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==",
"dev": true
},
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
"yargs": {
"version": "12.0.5",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
@@ -1077,22 +1092,22 @@
}
},
"@lerna/collect-updates": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-3.6.0.tgz",
- "integrity": "sha512-knliEz3phY51SGnwDhhYqx6SJN6y9qh/gZrZgQ7ogqz1UgA/MyJb27gszjsyyG6jUQshimBpjsG7OMwjt8+n9A==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-3.8.1.tgz",
+ "integrity": "sha512-1ULd1FBX8j8XGe166CUx+PkNeBJrbauI6Ux9+NiVrpeyE5rF6hzrowRyaptE9n5jzAl0WtTTIP1MsdrVG7BvAA==",
"dev": true,
"requires": {
"@lerna/child-process": "^3.3.0",
- "@lerna/describe-ref": "^3.6.0",
+ "@lerna/describe-ref": "^3.8.1",
"libnpm": "^2.0.1",
"minimatch": "^3.0.4",
"slash": "^1.0.0"
}
},
"@lerna/command": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@lerna/command/-/command-3.7.2.tgz",
- "integrity": "sha512-WtBnlvQfzKmnc2i3g+GLazx7pUXwbzASiXHy4j1CoC0w90H42LUqhwJICro4VhnE8xi38BNhcH/+xFNiHX5ERA==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@lerna/command/-/command-3.8.1.tgz",
+ "integrity": "sha512-AWC1ziiSCJikuviBcQHOc9qTqGS/KwG9cy4wbk65Zxmfy373/JJEt0bg0bfo48reZ2HiJu0mBXLitd3brXpdIw==",
"dev": true,
"requires": {
"@lerna/child-process": "^3.3.0",
@@ -1143,6 +1158,16 @@
"requires": {
"pump": "^3.0.0"
}
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
}
}
},
@@ -1190,17 +1215,27 @@
"requires": {
"graceful-fs": "^4.1.6"
}
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
}
}
},
"@lerna/create": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.7.2.tgz",
- "integrity": "sha512-eE6i4mVi5CefQ8Mw4WhkX9GcgiDllfEYfMq3LDMCtBH4pdzXO9oNG2p1J7bbwKgCFqhmKB4nr5FTFhijOIMRRw==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.8.1.tgz",
+ "integrity": "sha512-+mUkK9MEwTa8w69+yf5WhGF7csxn7wJRmsBe99J7QklamOSZXTLt4O5AeBtaYKFdJ9Tf5D+oxENMYLd2EaJNSw==",
"dev": true,
"requires": {
"@lerna/child-process": "^3.3.0",
- "@lerna/command": "^3.7.2",
+ "@lerna/command": "^3.8.1",
"@lerna/npm-conf": "^3.7.0",
"@lerna/validation-error": "^3.6.0",
"camelcase": "^4.1.0",
@@ -1231,7 +1266,7 @@
},
"globby": {
"version": "8.0.1",
- "resolved": "http://registry.npmjs.org/globby/-/globby-8.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz",
"integrity": "sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw==",
"dev": true,
"requires": {
@@ -1306,9 +1341,9 @@
}
},
"@lerna/describe-ref": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-3.6.0.tgz",
- "integrity": "sha512-hVZJ2hYVbrrNiEG+dEg/Op4pYAbROkDZdiIUabAJffr0T/frcN+5es2HfmOC//4+78Cs1M9iTyQRoyC1RXS2BQ==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-3.8.1.tgz",
+ "integrity": "sha512-EPXFiZbWG0KiaDM+BT3RZahy5gwrTVyKDv8HmPkGhu2h4pr34tzsSMmYmJ8I0dLeu4IpP/G/OIBa6DkYWisiZw==",
"dev": true,
"requires": {
"@lerna/child-process": "^3.3.0",
@@ -1316,38 +1351,38 @@
}
},
"@lerna/diff": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-3.7.2.tgz",
- "integrity": "sha512-BVcceQHxwr0hIO4hZ8Udeb1Afn2opDiMXSh3dEyV7kcbYlgc66AxsviVPr4txGP/p8uRlzBUDzgHShVMplMGcg==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-3.8.1.tgz",
+ "integrity": "sha512-FrQ2c7AULUs4eYwLE5adw6YObRdS8EgCbq5dE/sLrvnqODniM2hRnMf/zsFl4R8wf9PIs5tFXdyTdMVsQfwZGg==",
"dev": true,
"requires": {
"@lerna/child-process": "^3.3.0",
- "@lerna/command": "^3.7.2",
+ "@lerna/command": "^3.8.1",
"@lerna/validation-error": "^3.6.0",
"libnpm": "^2.0.1"
}
},
"@lerna/exec": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-3.7.2.tgz",
- "integrity": "sha512-oEm3EbSxXeMguqC+ekXaBlRmo/aaJc2BcWPHrd+5+9evHhHo/7oOu/xXmbhJYCgZytGkJ6BrX3F9XhWnC+14wg==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-3.8.1.tgz",
+ "integrity": "sha512-v+AAxkq19UdTfsO0aOfmAvQs9GnDpy5TyP1q4NVOZCotLOfVnFQ16QfzVCBA4hR3a6puugs3lmaOlQnMmDoDFQ==",
"dev": true,
"requires": {
"@lerna/batch-packages": "^3.6.0",
"@lerna/child-process": "^3.3.0",
- "@lerna/command": "^3.7.2",
- "@lerna/filter-options": "^3.6.0",
+ "@lerna/command": "^3.8.1",
+ "@lerna/filter-options": "^3.8.1",
"@lerna/run-parallel-batches": "^3.0.0",
"@lerna/validation-error": "^3.6.0"
}
},
"@lerna/filter-options": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.6.0.tgz",
- "integrity": "sha512-6iUMZuvvXPL5EAF7Zo9azaZ6FxOq6tGbiSX8fUXgCdN+jlRjorvkzR+E0HS4bEGTWmV446lnLwdQLZuySfLcbQ==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.8.1.tgz",
+ "integrity": "sha512-ty4Pl+vZjPSc7jc4nhK/4YYGKpLOhcGHLw6Zu71D4V3DJW/ZDHm/veRIApmhddL7+6y9G+ZGnGYYh/8RFyT6hA==",
"dev": true,
"requires": {
- "@lerna/collect-updates": "^3.6.0",
+ "@lerna/collect-updates": "^3.8.1",
"@lerna/filter-packages": "^3.6.0",
"dedent": "^0.7.0"
}
@@ -1452,13 +1487,13 @@
}
},
"@lerna/import": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.7.2.tgz",
- "integrity": "sha512-TGTYjhzDGLEqc9imWOi/fvIbZdmVxfV71OFB6AS98N9KQE68bbpttehQqCUIPATReVuzPUzxEiF3tMnKd7iEqg==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.8.1.tgz",
+ "integrity": "sha512-4GETPwbZOd7HuSDaqiAf6UENBLzmU2ICE7RXGoe5hIyCIYODx8q+/OSBYOdpV0hHbm/4IaKDa/k0rvCrI/dUFQ==",
"dev": true,
"requires": {
"@lerna/child-process": "^3.3.0",
- "@lerna/command": "^3.7.2",
+ "@lerna/command": "^3.8.1",
"@lerna/prompt": "^3.6.0",
"@lerna/pulse-till-done": "^3.7.1",
"@lerna/validation-error": "^3.6.0",
@@ -1490,13 +1525,13 @@
}
},
"@lerna/init": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@lerna/init/-/init-3.7.2.tgz",
- "integrity": "sha512-840Az0GtyepX7/WH3QvOQDZJCEGFf4IykjjFuCLF+23+Od8Wxn3QCsp4Yn/+HKi/w7bSpsCHJ6xQG208dygfdw==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@lerna/init/-/init-3.8.1.tgz",
+ "integrity": "sha512-pWS5EBaRr7kNr5uQSN06vd1kN2afIRJoYA4PEiD1Cs4Z9tPJYoDMEClPnss0sdh8O8RH3IzcDkN2gjzLn7oe/Q==",
"dev": true,
"requires": {
"@lerna/child-process": "^3.3.0",
- "@lerna/command": "^3.7.2",
+ "@lerna/command": "^3.8.1",
"fs-extra": "^7.0.0",
"p-map": "^1.2.0",
"write-json-file": "^2.3.0"
@@ -1525,26 +1560,26 @@
}
},
"@lerna/link": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@lerna/link/-/link-3.7.2.tgz",
- "integrity": "sha512-iwxftHVPknb+RXtD7257/FR4DYiCxJRxqo6z/YGlojWjehYRfbK7tJe4xzRzxepIXAE8+ooQFqQ73m0/ozk6kQ==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@lerna/link/-/link-3.8.1.tgz",
+ "integrity": "sha512-IKdnForLXk9XrR4i02ExfK//pQe94z0Q7TF9uSbjHk1JNLnUSzxRZ31WeuI5/ZZrhdHBJV1eDb6lJg7IRiXH5A==",
"dev": true,
"requires": {
- "@lerna/command": "^3.7.2",
+ "@lerna/command": "^3.8.1",
"@lerna/package-graph": "^3.6.0",
- "@lerna/symlink-dependencies": "^3.7.2",
+ "@lerna/symlink-dependencies": "^3.8.1",
"p-map": "^1.2.0",
"slash": "^1.0.0"
}
},
"@lerna/list": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@lerna/list/-/list-3.7.2.tgz",
- "integrity": "sha512-yup9KivG31APzr+C96up83m1llqs62spsLuKkinwVUhL5mobhDscT6QwIWTJPRJ8Bbmi++SdXGLfGFkYmgujzQ==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@lerna/list/-/list-3.8.1.tgz",
+ "integrity": "sha512-2Eafq6tlbXmCMBCpKLlQRD27b2W2ygAc6X/jYJ9bZtKZ1ZzNBjp5TWIHQAvj3/vAAR1VhSrfL+rMHIaqzEAASg==",
"dev": true,
"requires": {
- "@lerna/command": "^3.7.2",
- "@lerna/filter-options": "^3.6.0",
+ "@lerna/command": "^3.8.1",
+ "@lerna/filter-options": "^3.8.1",
"@lerna/listable": "^3.6.0",
"@lerna/output": "^3.6.0"
}
@@ -1601,9 +1636,9 @@
}
},
"@lerna/npm-install": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-3.6.0.tgz",
- "integrity": "sha512-RKV31VdrBZKjmKfq25JG4mIHJ8NAOsLKq/aYSaBs8zP+uwXH7RU39saVfv9ReKiAzhKE2ghOG2JeMdIHtYnPNA==",
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-3.8.2.tgz",
+ "integrity": "sha512-A22IrhPy70Gm30rBYSPp/PDWjByvj6QdxqQh41HlNGOCzM5WCCSDXpfeoxzS0ow0d3WGJMraE2k1GFpOP6Hyxg==",
"dev": true,
"requires": {
"@lerna/child-process": "^3.3.0",
@@ -1637,12 +1672,12 @@
}
},
"@lerna/npm-publish": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-3.7.1.tgz",
- "integrity": "sha512-3Tv4UWD+1Wz1Eqc7/8eEvAHL5c2pTx+rOKYMEc6P5Z1glN1+TfIfPckPAX0H2xg44yTCh1KGJSSBpJQl68QqIQ==",
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-3.8.2.tgz",
+ "integrity": "sha512-0ZVEmD7vQs29mV35O/8q/eCvTVA4nu49Jpq5821TMMENa2CiBmQCWv/MqLaQlPCAdTx/kXHJMQ9kmhwrhks0Aw==",
"dev": true,
"requires": {
- "@lerna/run-lifecycle": "^3.7.1",
+ "@lerna/run-lifecycle": "^3.8.2",
"figgy-pudding": "^3.5.1",
"fs-extra": "^7.0.0",
"libnpm": "^2.0.1"
@@ -1691,14 +1726,14 @@
}
},
"@lerna/pack-directory": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@lerna/pack-directory/-/pack-directory-3.7.2.tgz",
- "integrity": "sha512-yAZNSdAsBD26as+Il1l5R0fQaI6vTJqyNeK181V2vf34+KC0NX9TVaM+/Ht28QpK+3SaD2tvVP1T7OP2w0g2qg==",
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@lerna/pack-directory/-/pack-directory-3.8.2.tgz",
+ "integrity": "sha512-sYXioixVw3L5r9O4bt+hnfPQ8jLn/PVOJVivQdpSlup+ZUiI5mmtjzAO3NOK/k8DZf8YrUx0Lm1+vzgnqu1tKw==",
"dev": true,
"requires": {
"@lerna/get-packed": "^3.7.0",
"@lerna/package": "^3.7.2",
- "@lerna/run-lifecycle": "^3.7.1",
+ "@lerna/run-lifecycle": "^3.8.2",
"figgy-pudding": "^3.5.1",
"libnpm": "^2.0.1",
"npm-packlist": "^1.1.12",
@@ -1819,7 +1854,7 @@
},
"globby": {
"version": "8.0.1",
- "resolved": "http://registry.npmjs.org/globby/-/globby-8.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz",
"integrity": "sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw==",
"dev": true,
"requires": {
@@ -1955,33 +1990,32 @@
}
},
"@lerna/publish": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.8.0.tgz",
- "integrity": "sha512-EJDF6oPySIHQRre9KMMqtltrPReuBT7Po72W6OQxCUmCjqDyUd6884lhqFHOgbtOl1axrVVaSOpxCU1m+SLNgA==",
+ "version": "3.8.4",
+ "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.8.4.tgz",
+ "integrity": "sha512-Bbz3Ne0UHiBqLrHAhB2+zitzYjgjIiydLmhLiuzhwbPgah7kP7nv9/HrXv927kjEY7EHd/+zqs/NuviJvKKb0g==",
"dev": true,
"requires": {
"@lerna/batch-packages": "^3.6.0",
- "@lerna/check-working-tree": "^3.6.0",
+ "@lerna/check-working-tree": "^3.8.1",
"@lerna/child-process": "^3.3.0",
- "@lerna/collect-updates": "^3.6.0",
- "@lerna/command": "^3.7.2",
- "@lerna/describe-ref": "^3.6.0",
+ "@lerna/collect-updates": "^3.8.1",
+ "@lerna/command": "^3.8.1",
+ "@lerna/describe-ref": "^3.8.1",
"@lerna/log-packed": "^3.6.0",
"@lerna/npm-conf": "^3.7.0",
"@lerna/npm-dist-tag": "^3.7.1",
- "@lerna/npm-publish": "^3.7.1",
+ "@lerna/npm-publish": "^3.8.2",
"@lerna/output": "^3.6.0",
- "@lerna/pack-directory": "^3.7.2",
+ "@lerna/pack-directory": "^3.8.2",
"@lerna/prompt": "^3.6.0",
"@lerna/pulse-till-done": "^3.7.1",
- "@lerna/run-lifecycle": "^3.7.1",
+ "@lerna/run-lifecycle": "^3.8.2",
"@lerna/run-parallel-batches": "^3.0.0",
"@lerna/validation-error": "^3.6.0",
- "@lerna/version": "^3.8.0",
+ "@lerna/version": "^3.8.2",
"figgy-pudding": "^3.5.1",
"fs-extra": "^7.0.0",
"libnpm": "^2.0.1",
- "npm-registry-fetch": "^3.8.0",
"p-finally": "^1.0.0",
"p-map": "^1.2.0",
"p-pipe": "^1.2.0",
@@ -2066,14 +2100,14 @@
}
},
"@lerna/run": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.7.2.tgz",
- "integrity": "sha512-FwBjcrtYSFyvY2YXJ8GoI9VNv2UElUbVra5+iTF1DgQh37RmK0ZCODkfXp6PYyUszHkgCRuJqhK0+yMWRJo61w==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.8.1.tgz",
+ "integrity": "sha512-EKJsdfuZYLr6QrEqOt7qteBIR/hZ/Fdk526fdVBtryaL5t1UESwaF741M65WWQMJnFOtJZI6n2tna5CX0n7xVQ==",
"dev": true,
"requires": {
"@lerna/batch-packages": "^3.6.0",
- "@lerna/command": "^3.7.2",
- "@lerna/filter-options": "^3.6.0",
+ "@lerna/command": "^3.8.1",
+ "@lerna/filter-options": "^3.8.1",
"@lerna/npm-run-script": "^3.6.0",
"@lerna/output": "^3.6.0",
"@lerna/run-parallel-batches": "^3.0.0",
@@ -2083,9 +2117,9 @@
}
},
"@lerna/run-lifecycle": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/@lerna/run-lifecycle/-/run-lifecycle-3.7.1.tgz",
- "integrity": "sha512-kE6w8d8Qde+ewZaDNIz4zhwde8s/i8vbbOsGDlR/Vw/9nqlmtj2YBZaS262NtWj83N04dtdYr4FVj51thciGQw==",
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@lerna/run-lifecycle/-/run-lifecycle-3.8.2.tgz",
+ "integrity": "sha512-V80nIoHpp0IL9WEaK8wz47SeqLSlI8DyNqVqUoG1DCeCGr6rdvRGD0FgHSKgRnZxk/SgP1Az/YBBtc5qnA+CzA==",
"dev": true,
"requires": {
"@lerna/npm-conf": "^3.7.0",
@@ -2138,9 +2172,9 @@
}
},
"@lerna/symlink-dependencies": {
- "version": "3.7.2",
- "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-3.7.2.tgz",
- "integrity": "sha512-53fZUGQ+QLr5P7I9/pqFmCizLo4Q/Jz5ETd1NURO2+eABGdYuTnuvtqyGku+eOr9A4gYDaVmg50KEpsOXq9TWg==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-3.8.1.tgz",
+ "integrity": "sha512-MlXRTpB3Go/ubexxySngzg8PnItpPIxa0ydHMxvvw7s06g7ZsOOMOAx+F7AUPPr7bssdZ+gg5bfSq+J1HoINrg==",
"dev": true,
"requires": {
"@lerna/create-symlink": "^3.6.0",
@@ -2190,20 +2224,20 @@
}
},
"@lerna/version": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.8.0.tgz",
- "integrity": "sha512-c+TNPzlyv0dgDpgMu87CPauk8R2jZwwftgQarHOCGbEZ0ClXqLFTEAKxvLpzprlt+kH3goIWYNQrZiJflpMOCA==",
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.8.2.tgz",
+ "integrity": "sha512-TANvavzkyTcSVElsh8+zTZmsjzF6B0xuE9ldRdFKQaYAqmkkWNmf73BwLDZGisqEh45wnveiR9GeflSw4XI4iw==",
"dev": true,
"requires": {
"@lerna/batch-packages": "^3.6.0",
- "@lerna/check-working-tree": "^3.6.0",
+ "@lerna/check-working-tree": "^3.8.1",
"@lerna/child-process": "^3.3.0",
- "@lerna/collect-updates": "^3.6.0",
- "@lerna/command": "^3.7.2",
+ "@lerna/collect-updates": "^3.8.1",
+ "@lerna/command": "^3.8.1",
"@lerna/conventional-commits": "^3.6.0",
"@lerna/output": "^3.6.0",
"@lerna/prompt": "^3.6.0",
- "@lerna/run-lifecycle": "^3.7.1",
+ "@lerna/run-lifecycle": "^3.8.2",
"@lerna/validation-error": "^3.6.0",
"chalk": "^2.3.1",
"dedent": "^0.7.0",
@@ -2272,9 +2306,9 @@
"integrity": "sha512-59/mWwU7sXHfoU2kI3RcWRki2Jjbz5nEVJNBN4MUyIhPjXTebAcZqgsQACvlk+sjKVOTMEMHcrFrKQbaxz/1Dw=="
},
"@types/node": {
- "version": "10.12.18",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz",
- "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ=="
+ "version": "10.12.15",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.15.tgz",
+ "integrity": "sha512-9kROxduaN98QghwwHmxXO2Xz3MaWf+I1sLVAA6KJDF5xix+IyXVhds0MAfdNwtcpSrzhaTsNB0/jnL86fgUhqA=="
},
"@webassemblyjs/ast": {
"version": "1.7.11",
@@ -2458,14 +2492,14 @@
}
},
"@wordpress/api-fetch": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-2.2.2.tgz",
- "integrity": "sha512-yqJjHR+EjbMZ9BO3DWJqydvlRZoS9M1NvdwXouzkmxCCdVF4JfmWdydfakeXreYH8+T01V/JjP2rZYcQDn36/Q==",
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-2.2.6.tgz",
+ "integrity": "sha512-cZfJrkfv4+w8rWEMzuh6Q5QoaT1MxD+K3MuT+PHP/SZiSS0AuP733LsWlYJDo28EatNUHU2XPR3IpeKzbiHlvQ==",
"requires": {
"@babel/runtime": "^7.0.0",
"@wordpress/hooks": "^2.0.3",
- "@wordpress/i18n": "^3.0.1",
- "@wordpress/url": "^2.2.0"
+ "@wordpress/i18n": "^3.1.0",
+ "@wordpress/url": "^2.3.2"
},
"dependencies": {
"@wordpress/i18n": {
@@ -2504,9 +2538,9 @@
}
},
"@wordpress/babel-preset-default": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@wordpress/babel-preset-default/-/babel-preset-default-2.1.0.tgz",
- "integrity": "sha512-0Fb6FS4oGQ8AWJ2fMvkX23Y/fJWFwe5PP5ASdTu3qbgajiMmesxGcnpk2Sx59CL74S+LtOUaUkG4eusEkJP4Mg==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@wordpress/babel-preset-default/-/babel-preset-default-3.0.1.tgz",
+ "integrity": "sha512-5pbmYh0b4flwyAbuEMTOgTZJ1jqn5iucXhoAESWHZyHCn6D+s36ws0RkFrefz1mYQv4KgIoVpqshDXdN9wR/Bg==",
"dev": true,
"requires": {
"@babel/plugin-proposal-async-generator-functions": "^7.0.0",
@@ -2525,71 +2559,107 @@
"integrity": "sha512-RZ9XeDeXTc/l3RdSnfYYwcsylFPouV+2ZpQQaAgALSXthMWJT2wU61zD4mH9aMI5Oo6Z8OUVI2vOZM/7HObPxw=="
},
"@wordpress/components": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-3.0.0.tgz",
- "integrity": "sha512-W0ca62EGf2as+wintOzZP1W4DzKBJmuhSsrbuKLUXMCZPh9x0KIuedlTOrRYh5bkK0mWtQ1DQRwbnh01dYBN2A==",
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-7.0.5.tgz",
+ "integrity": "sha512-Csu2z4r8g3PwwLWWRMDeA//vQhHh05J9hyogE15dMS/6jrSKyl8lonGWvbnO2PSrMzKIHPeoXYzutUeNBjY1pg==",
"requires": {
"@babel/runtime": "^7.0.0",
- "@wordpress/a11y": "^2.0.0",
- "@wordpress/api-fetch": "^2.0.0",
- "@wordpress/compose": "^2.0.0",
- "@wordpress/deprecated": "^2.0.0",
- "@wordpress/dom": "^2.0.0",
- "@wordpress/element": "^2.0.0",
- "@wordpress/hooks": "^2.0.0",
- "@wordpress/i18n": "^2.0.0",
+ "@wordpress/a11y": "^2.0.2",
+ "@wordpress/api-fetch": "^2.2.7",
+ "@wordpress/compose": "^3.0.0",
+ "@wordpress/dom": "^2.0.8",
+ "@wordpress/element": "^2.1.8",
+ "@wordpress/hooks": "^2.0.4",
+ "@wordpress/i18n": "^3.1.0",
"@wordpress/is-shallow-equal": "^1.1.4",
- "@wordpress/keycodes": "^2.0.0",
- "@wordpress/url": "^2.0.0",
+ "@wordpress/keycodes": "^2.0.5",
+ "@wordpress/rich-text": "^3.0.4",
+ "@wordpress/url": "^2.3.3",
"classnames": "^2.2.5",
- "clipboard": "^1.7.1",
+ "clipboard": "^2.0.1",
+ "diff": "^3.5.0",
"dom-scroll-into-view": "^1.2.1",
- "element-closest": "^2.0.2",
"lodash": "^4.17.10",
"memize": "^1.0.5",
"moment": "^2.22.1",
"mousetrap": "^1.6.2",
- "react-click-outside": "^2.3.1",
- "react-color": "^2.13.4",
- "react-datepicker": "^1.4.1",
+ "re-resizable": "^4.7.1",
+ "react-click-outside": "^3.0.0",
+ "react-dates": "^17.1.1",
"rememo": "^3.0.0",
- "uuid": "^3.1.0"
+ "tinycolor2": "^1.4.1",
+ "uuid": "^3.3.2"
},
"dependencies": {
- "react-click-outside": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/react-click-outside/-/react-click-outside-2.3.1.tgz",
- "integrity": "sha1-MYc3698IGko7zUaCVmNnTL6YNus=",
+ "@wordpress/api-fetch": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-2.2.7.tgz",
+ "integrity": "sha512-7Bl4hfLLw5rWeQ7LIa3U/rananC2Tk6uZ55acetC+hag9gJpDpddbXOlW3Li8Zk1cJvvcpgfElVPwPFnS0e/qg==",
"requires": {
- "hoist-non-react-statics": "^1.2.0"
+ "@babel/runtime": "^7.0.0",
+ "@wordpress/hooks": "^2.0.4",
+ "@wordpress/i18n": "^3.1.0",
+ "@wordpress/url": "^2.3.3"
+ }
+ },
+ "@wordpress/hooks": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-2.0.4.tgz",
+ "integrity": "sha512-9Z+zymxRI1vNVPnAhGOYjp05Do/rNWdj/0lrx0oC8vluQFyaU9OWS7+il1eL8kfr+27nzcBnoU0e2WfvoXVhyg==",
+ "requires": {
+ "@babel/runtime": "^7.0.0"
+ }
+ },
+ "@wordpress/url": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-2.3.3.tgz",
+ "integrity": "sha512-WGqQjOyu02E7bJ77G8385GGjUYpvF8vDqZXXHW06/WRSb4nW6fmMIM65UWdBaYY5XecAkpglCqwd8DNbquLucQ==",
+ "requires": {
+ "@babel/runtime": "^7.0.0",
+ "qs": "^6.5.2"
+ }
+ },
+ "clipboard": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz",
+ "integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==",
+ "requires": {
+ "good-listener": "^1.2.2",
+ "select": "^1.1.2",
+ "tiny-emitter": "^2.0.0"
+ }
+ },
+ "react-dates": {
+ "version": "17.2.0",
+ "resolved": "https://registry.npmjs.org/react-dates/-/react-dates-17.2.0.tgz",
+ "integrity": "sha512-RDlerU8DdRRrlYS0MQ7Z9igPWABGLDwz6+ykBNff67RM3Sset2TDqeuOr+R5o00Ggn5U47GeLsGcSDxlZd9cHw==",
+ "requires": {
+ "airbnb-prop-types": "^2.10.0",
+ "consolidated-events": "^1.1.1 || ^2.0.0",
+ "is-touch-device": "^1.0.1",
+ "lodash": "^4.1.1",
+ "object.assign": "^4.1.0",
+ "object.values": "^1.0.4",
+ "prop-types": "^15.6.1",
+ "react-addons-shallow-compare": "^15.6.2",
+ "react-moment-proptypes": "^1.6.0",
+ "react-outside-click-handler": "^1.2.0",
+ "react-portal": "^4.1.5",
+ "react-with-styles": "^3.2.0",
+ "react-with-styles-interface-css": "^4.0.2"
}
}
}
},
"@wordpress/compose": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-2.1.2.tgz",
- "integrity": "sha512-jr1bWRYx8vt4bCWB4hqR9Ve9rk/TCJ5mFRvkwEd+xTDyXG6ZMmps3HszGA6aCH7E+TCHH+bWw2qZo9sAeHVK/w==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-3.0.0.tgz",
+ "integrity": "sha512-jghgcLLKYQiIxjKp1q9FGcLlbeTKmYUIbYcru2AX7VF1uqp85oeRcuWsowrQUvomWHADcf09psBfDo2Gz/OH8A==",
"requires": {
"@babel/runtime": "^7.0.0",
- "@wordpress/deprecated": "^2.0.3",
- "@wordpress/element": "^2.1.7",
+ "@wordpress/element": "^2.1.8",
"@wordpress/is-shallow-equal": "^1.1.4",
"lodash": "^4.17.10"
- },
- "dependencies": {
- "@wordpress/element": {
- "version": "2.1.8",
- "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-2.1.8.tgz",
- "integrity": "sha512-hPbNWcxGQCpTeXoTdwr0Bu3kNJMSSKAnIb5B8P/2lTQ9mJ6w8l1Vc/0L11Yy8+uElaLwGq4Lja9ljgTlWbXUkA==",
- "requires": {
- "@babel/runtime": "^7.0.0",
- "@wordpress/escape-html": "^1.0.1",
- "lodash": "^4.17.10",
- "react": "^16.6.3",
- "react-dom": "^16.6.3"
- }
- }
}
},
"@wordpress/custom-templated-path-webpack-plugin": {
@@ -2603,14 +2673,13 @@
}
},
"@wordpress/data": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-3.1.0.tgz",
- "integrity": "sha512-XQNSOy7xSHVi4KGxOOd6gJJ3+Qq4XWZMK5hMBSEwVCiyIcSbcP6I1AT1NnnPuJeH94BmFCPNADElHB4gazg8xA==",
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-4.2.0.tgz",
+ "integrity": "sha512-9cdm5xBWgLJJ45nQCbUQFF26vGoG2PzEJrinNXLr45XNAr3XSzN/JsrmNCaHwI/NzyFIwFmFjv6ONQKxxkErrg==",
"requires": {
"@babel/runtime": "^7.0.0",
- "@wordpress/compose": "^2.1.0",
- "@wordpress/deprecated": "^2.0.3",
- "@wordpress/element": "^2.1.5",
+ "@wordpress/compose": "^3.0.0",
+ "@wordpress/element": "^2.1.8",
"@wordpress/is-shallow-equal": "^1.1.4",
"@wordpress/redux-routine": "^3.0.3",
"equivalent-key-map": "^0.2.2",
@@ -2621,28 +2690,19 @@
}
},
"@wordpress/date": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-2.1.0.tgz",
- "integrity": "sha512-MMDU2/N0unnwKTmaeCYy4fW/CuyCdM5t+/ANXVigBxY/IiOGeRXnmiU4VHK1BshEnsWRJz687MmEGEkxVpwd8w==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-3.0.1.tgz",
+ "integrity": "sha512-LOOwZM0A5OeElWgdyuR3LJQ7sJJZ5oHdXnNTs3LEB5GH7FUoozF6B6KY5Qm13pizzWX018C8vggsHrsltuLo3A==",
"requires": {
"@babel/runtime": "^7.0.0",
"moment": "^2.22.1",
"moment-timezone": "^0.5.16"
}
},
- "@wordpress/deprecated": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-2.0.3.tgz",
- "integrity": "sha512-5v8h6BJ9xQFTho7ucitshpIahD+rVnAhgc/4juYmPLb9/GJzwY1J91Ve5mcjcjgWhdtjBKO0TCq/S4PCfS812w==",
- "requires": {
- "@babel/runtime": "^7.0.0",
- "@wordpress/hooks": "^2.0.3"
- }
- },
"@wordpress/dom": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-2.0.7.tgz",
- "integrity": "sha512-vjOdGSpW3WdHH5oOoamfzdoyF4BbUJOWNNT7bBb2y15GII8rN1cGyGxqVDiiajMDe51p3lyWWCpUeY4ppxj/UA==",
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-2.0.8.tgz",
+ "integrity": "sha512-Nz1k1tB/NXcfpAWUL+mTtEzxC6Dp6UAavIzJVQgAq8gsdayh7F9lgkyyL5MWLirAKkGuhztwMrSle9s5HzrTlw==",
"requires": {
"@babel/runtime": "^7.0.0",
"lodash": "^4.17.10"
@@ -2657,15 +2717,15 @@
}
},
"@wordpress/element": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-2.1.5.tgz",
- "integrity": "sha512-y567y5SZv3VXDrUw/qpO7ElrTc8/BhumAivVlpAItychfn/PdTxd2l5V1Cc91Uc2/JDoAhPCRIO23UFWX+Ehtw==",
+ "version": "2.1.8",
+ "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-2.1.8.tgz",
+ "integrity": "sha512-hPbNWcxGQCpTeXoTdwr0Bu3kNJMSSKAnIb5B8P/2lTQ9mJ6w8l1Vc/0L11Yy8+uElaLwGq4Lja9ljgTlWbXUkA==",
"requires": {
"@babel/runtime": "^7.0.0",
"@wordpress/escape-html": "^1.0.1",
"lodash": "^4.17.10",
- "react": "^16.4.1",
- "react-dom": "^16.4.1"
+ "react": "^16.6.3",
+ "react-dom": "^16.6.3"
}
},
"@wordpress/escape-html": {
@@ -2685,23 +2745,24 @@
}
},
"@wordpress/html-entities": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-2.0.2.tgz",
- "integrity": "sha512-cxG7YjH9EMfZyeLJAd/Vc1nFJxitMSzybv71iMPP3Dqqgz3jixX6oSe4ukTqfoOKBaF7pY7LzS6eTKu7KAmyZw==",
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-2.0.4.tgz",
+ "integrity": "sha512-waT+n+sLLzoI7dUovWGwTUB25iNoRyktRYroc4NVgAbDkKuN5Dsi9IOmJnNNitdQ17HEAOn++ZO6X5/mbBkvBA==",
"requires": {
"@babel/runtime": "^7.0.0"
}
},
"@wordpress/i18n": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-2.0.0.tgz",
- "integrity": "sha512-q8rY7RIkHRmtZpkodk+1WJMwr8r/NIr7oFK67/1+ek1ervp+psSCAPF543m6DzYxCDxDj/m/Q55d31ImpvU/xg==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.1.0.tgz",
+ "integrity": "sha512-zHqLRuKrDV3FYh8PYDs4ABO/csiEAy1EfTffMtMS/8GAz4BcWrcqDjyH42GJF8iwWdG5+DdsllP5oerAQMHnng==",
"requires": {
"@babel/runtime": "^7.0.0",
"gettext-parser": "^1.3.1",
- "jed": "^1.1.1",
"lodash": "^4.17.10",
- "memize": "^1.0.5"
+ "memize": "^1.0.5",
+ "sprintf-js": "^1.1.1",
+ "tannin": "^1.0.1"
}
},
"@wordpress/is-shallow-equal": {
@@ -2723,25 +2784,41 @@
}
},
"@wordpress/jest-preset-default": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@wordpress/jest-preset-default/-/jest-preset-default-2.0.6.tgz",
- "integrity": "sha512-H+/2wYrGIwZ/MLzaev0TZvyxHWCH/OVpl0MjeSfiobza0+yDOqv6S5DNlcLpIHw9s324awl3pjBfjvyNr1C9tA==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@wordpress/jest-preset-default/-/jest-preset-default-3.0.3.tgz",
+ "integrity": "sha512-CjUmasTBL1n8jdnp+yvrZ3hEcZtC5e20aelHB594JeY4l2Lk0f96nl4PaNi/Tpd/QsAiZeTTW0DhTT97FKgdtg==",
"dev": true,
"requires": {
- "@wordpress/jest-console": "^2.0.6",
- "babel-jest": "^23.4.2",
- "enzyme": "^3.3.0",
- "enzyme-adapter-react-16": "^1.1.1",
+ "@wordpress/jest-console": "^2.0.7",
+ "babel-jest": "^23.6.0",
+ "enzyme": "^3.7.0",
+ "enzyme-adapter-react-16": "^1.6.0",
"jest-enzyme": "^6.0.2"
}
},
"@wordpress/keycodes": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.0.3.tgz",
- "integrity": "sha512-cg4IHxz9BjRHBIhs/e0NwO/snImNqMQLZfduPf6Y+GGlq28BbQuxnucDj0ktYw/4X9jxf6IHzWUq9bkX65QGiA==",
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-2.0.5.tgz",
+ "integrity": "sha512-uEnLRbEe+6FkXKTdQordwR9fBExIngnsa6FmAJ2ODzEI872g271jM5W61m33WzsBHfbFHQKqUi+ZaFAzu7XUcg==",
"requires": {
"@babel/runtime": "^7.0.0",
+ "@wordpress/i18n": "^3.1.0",
"lodash": "^4.17.10"
+ },
+ "dependencies": {
+ "@wordpress/i18n": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-3.1.0.tgz",
+ "integrity": "sha512-zHqLRuKrDV3FYh8PYDs4ABO/csiEAy1EfTffMtMS/8GAz4BcWrcqDjyH42GJF8iwWdG5+DdsllP5oerAQMHnng==",
+ "requires": {
+ "@babel/runtime": "^7.0.0",
+ "gettext-parser": "^1.3.1",
+ "lodash": "^4.17.10",
+ "memize": "^1.0.5",
+ "sprintf-js": "^1.1.1",
+ "tannin": "^1.0.1"
+ }
+ }
}
},
"@wordpress/npm-package-json-lint-config": {
@@ -2769,19 +2846,32 @@
"rungen": "^0.3.2"
}
},
+ "@wordpress/rich-text": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-3.0.4.tgz",
+ "integrity": "sha512-dv14T0wk0YPZtDNdoJKuduf3McCdQpcUHczhMoYg3WssBkyOPY3Vak8RH6t/uEnEwZhgJIolkcwrTedIFXiC4Q==",
+ "requires": {
+ "@babel/runtime": "^7.0.0",
+ "@wordpress/compose": "^3.0.0",
+ "@wordpress/data": "^4.2.0",
+ "@wordpress/escape-html": "^1.0.1",
+ "lodash": "^4.17.10",
+ "rememo": "^3.0.0"
+ }
+ },
"@wordpress/scripts": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/@wordpress/scripts/-/scripts-2.4.1.tgz",
- "integrity": "sha512-FXr451wUvVSve7am1lk7CthGJqjiqFMyNBYykQdZQ5OBWhXbvO8zMu5MCkISWOHIXXpJ3hedvrujoBp/psx+Fg==",
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/@wordpress/scripts/-/scripts-2.4.4.tgz",
+ "integrity": "sha512-cMjtC8enrY+JXXm8toIz7kTOaTjJ8k8+8eRghRks+D3s51ylVOSsfdu8UFh3O0c4Z+nOheTYZXKoWkAn6HmNVw==",
"requires": {
"@wordpress/babel-preset-default": "^3.0.1",
- "@wordpress/jest-preset-default": "^3.0.0",
+ "@wordpress/jest-preset-default": "^3.0.3",
"@wordpress/npm-package-json-lint-config": "^1.1.5",
"babel-eslint": "8.0.3",
"chalk": "^2.4.1",
"cross-spawn": "^5.1.0",
"eslint": "^4.19.1",
- "jest": "^23.4.2",
+ "jest": "^23.6.0",
"npm-package-json-lint": "^3.3.1",
"read-pkg-up": "^1.0.1",
"resolve-bin": "^0.4.0"
@@ -2916,7 +3006,7 @@
},
"eslint": {
"version": "4.19.1",
- "resolved": "http://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
"integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==",
"requires": {
"ajv": "^5.3.0",
@@ -2968,7 +3058,7 @@
},
"fast-deep-equal": {
"version": "1.1.0",
- "resolved": "http://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
"integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
},
"globals": {
@@ -3124,7 +3214,7 @@
},
"acorn-jsx": {
"version": "3.0.1",
- "resolved": "http://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
"integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
"requires": {
"acorn": "^3.0.4"
@@ -3132,7 +3222,7 @@
"dependencies": {
"acorn": {
"version": "3.3.0",
- "resolved": "http://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
"integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo="
}
}
@@ -3215,7 +3305,7 @@
},
"ansi-escapes": {
"version": "3.1.0",
- "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
"integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw=="
},
"ansi-regex": {
@@ -3317,7 +3407,7 @@
},
"is-accessor-descriptor": {
"version": "0.1.6",
- "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
"integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
"requires": {
"kind-of": "^3.0.2"
@@ -3335,7 +3425,7 @@
},
"is-data-descriptor": {
"version": "0.1.4",
- "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
"integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
"requires": {
"kind-of": "^3.0.2"
@@ -3529,7 +3619,7 @@
"dependencies": {
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -3544,7 +3634,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
@@ -3563,7 +3653,7 @@
"dependencies": {
"sprintf-js": {
"version": "1.0.3",
- "resolved": "http://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
}
}
@@ -3604,7 +3694,7 @@
},
"array-equal": {
"version": "1.0.0",
- "resolved": "http://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
"integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM="
},
"array-find-index": {
@@ -3713,7 +3803,7 @@
},
"util": {
"version": "0.10.3",
- "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
"integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
"dev": true,
"requires": {
@@ -3853,7 +3943,7 @@
},
"chalk": {
"version": "1.1.3",
- "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"requires": {
"ansi-styles": "^2.2.1",
@@ -3870,7 +3960,7 @@
},
"supports-color": {
"version": "2.0.0",
- "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
}
}
@@ -3923,7 +4013,7 @@
"dependencies": {
"jsesc": {
"version": "1.3.0",
- "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
"integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s="
}
}
@@ -3991,7 +4081,7 @@
},
"babel-plugin-istanbul": {
"version": "4.1.6",
- "resolved": "http://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz",
"integrity": "sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ==",
"requires": {
"babel-plugin-syntax-object-rest-spread": "^6.13.0",
@@ -4007,13 +4097,13 @@
},
"babel-plugin-syntax-class-properties": {
"version": "6.13.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
"integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=",
"dev": true
},
"babel-plugin-syntax-object-rest-spread": {
"version": "6.13.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
"integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U="
},
"babel-plugin-transform-class-properties": {
@@ -4293,9 +4383,9 @@
}
},
"big.js": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
- "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
+ "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
"dev": true
},
"bin-links": {
@@ -4319,7 +4409,7 @@
},
"bindings": {
"version": "1.2.1",
- "resolved": "http://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz",
"integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE=",
"dev": true
},
@@ -4414,14 +4504,14 @@
"dependencies": {
"resolve": {
"version": "1.1.7",
- "resolved": "http://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
"integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs="
}
}
},
"browserify-aes": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
"dev": true,
"requires": {
@@ -4458,7 +4548,7 @@
},
"browserify-rsa": {
"version": "4.0.1",
- "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
"integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
"dev": true,
"requires": {
@@ -4523,14 +4613,14 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
}
}
},
"buffer": {
"version": "4.9.1",
- "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
"integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
"dev": true,
"requires": {
@@ -4581,7 +4671,7 @@
},
"cacache": {
"version": "10.0.4",
- "resolved": "http://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz",
"integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==",
"dev": true,
"requires": {
@@ -4656,14 +4746,14 @@
"dependencies": {
"callsites": {
"version": "0.2.0",
- "resolved": "http://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
"integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo="
}
}
},
"callsites": {
"version": "2.0.0",
- "resolved": "http://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
"integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA="
},
"camelcase": {
@@ -4682,9 +4772,9 @@
}
},
"caniuse-lite": {
- "version": "1.0.30000925",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000925.tgz",
- "integrity": "sha512-zcYupoUxtW46rOikuDF7vfL9N1Qe9ZuUBTz3n3q8fFsoJIs/h9UN6Vg/0QpjsmvImXw9mVc3g+ZBfqvUz/iALA=="
+ "version": "1.0.30000921",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000921.tgz",
+ "integrity": "sha512-Bu09ciy0lMWLgpYC77I0YGuI8eFRBPPzaSOYJK1jTI64txCphYCqnWbxJYjHABYVt/TYX/p3jNjLBR87u1Bfpw=="
},
"capture-exit": {
"version": "1.2.0",
@@ -4982,6 +5072,7 @@
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-1.7.1.tgz",
"integrity": "sha1-Ng1taUbpmnof7zleQrqStem1oWs=",
+ "optional": true,
"requires": {
"good-listener": "^1.2.2",
"select": "^1.1.2",
@@ -5096,7 +5187,7 @@
},
"color": {
"version": "0.11.4",
- "resolved": "http://registry.npmjs.org/color/-/color-0.11.4.tgz",
+ "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz",
"integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=",
"dev": true,
"requires": {
@@ -5120,7 +5211,7 @@
},
"color-string": {
"version": "0.3.0",
- "resolved": "http://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz",
"integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=",
"dev": true,
"requires": {
@@ -5128,10 +5219,9 @@
}
},
"colors": {
- "version": "1.1.2",
- "resolved": "http://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
- "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
- "dev": true
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-0.5.1.tgz",
+ "integrity": "sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q="
},
"columnify": {
"version": "1.5.4",
@@ -5152,9 +5242,9 @@
}
},
"commander": {
- "version": "2.19.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
- "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg=="
+ "version": "2.17.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
+ "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
},
"commondir": {
"version": "1.0.1",
@@ -5205,7 +5295,7 @@
},
"concat-stream": {
"version": "1.6.2",
- "resolved": "http://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
"requires": {
"buffer-from": "^1.0.0",
@@ -5216,7 +5306,7 @@
"dependencies": {
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -5230,7 +5320,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
@@ -5275,13 +5365,13 @@
}
},
"execa": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
- "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz",
+ "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==",
"dev": true,
"requires": {
"cross-spawn": "^6.0.0",
- "get-stream": "^4.0.0",
+ "get-stream": "^3.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
@@ -5298,15 +5388,6 @@
"locate-path": "^3.0.0"
}
},
- "get-stream": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
- "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
- "dev": true,
- "requires": {
- "pump": "^3.0.0"
- }
- },
"has-flag": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
@@ -5350,20 +5431,20 @@
}
},
"os-locale": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
- "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.0.1.tgz",
+ "integrity": "sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw==",
"dev": true,
"requires": {
- "execa": "^1.0.0",
+ "execa": "^0.10.0",
"lcid": "^2.0.0",
"mem": "^4.0.0"
}
},
"p-limit": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz",
- "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz",
+ "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
@@ -5506,9 +5587,9 @@
}
},
"connect-livereload": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.6.1.tgz",
- "integrity": "sha512-3R0kMOdL7CjJpU66fzAkCe6HNtd3AavCS4m+uW4KtJjrdGPT0SQEZieAYd+cm+lJoBznNQ4lqipYWkhBMgk00g==",
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.6.0.tgz",
+ "integrity": "sha1-+fAJh0rWg3GDr7FwtMTjhXodfOs=",
"dev": true
},
"console-browserify": {
@@ -5701,7 +5782,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
@@ -5815,7 +5896,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
@@ -5920,7 +6001,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
@@ -6106,7 +6187,7 @@
},
"create-hash": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"dev": true,
"requires": {
@@ -6119,7 +6200,7 @@
},
"create-hmac": {
"version": "1.1.7",
- "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"dev": true,
"requires": {
@@ -6131,15 +6212,6 @@
"sha.js": "^2.4.8"
}
},
- "create-react-context": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.2.tgz",
- "integrity": "sha512-KkpaLARMhsTsgp0d2NA/R94F/eDLbhXERdIq3LvX2biCAXcDvHYoOqHfWCHf1+OLj+HKBotLG3KqaOOf+C1C+A==",
- "requires": {
- "fbjs": "^0.8.0",
- "gud": "^1.0.0"
- }
- },
"cross-env": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.0.tgz",
@@ -6247,6 +6319,38 @@
"schema-utils": "^1.0.0"
},
"dependencies": {
+ "big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "dev": true
+ },
+ "json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ },
+ "loader-utils": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz",
+ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==",
+ "dev": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^2.0.0",
+ "json5": "^1.0.1"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ },
"postcss": {
"version": "7.0.7",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz",
@@ -6268,7 +6372,7 @@
},
"css-select": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
"integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
"requires": {
"boolbase": "~1.0.0",
@@ -6290,13 +6394,13 @@
"dependencies": {
"jsesc": {
"version": "0.5.0",
- "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
"dev": true
},
"regexpu-core": {
"version": "1.0.0",
- "resolved": "http://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
"integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
"dev": true,
"requires": {
@@ -6307,13 +6411,13 @@
},
"regjsgen": {
"version": "0.2.0",
- "resolved": "http://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
"integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
"dev": true
},
"regjsparser": {
"version": "0.1.5",
- "resolved": "http://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
"integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
"dev": true,
"requires": {
@@ -6361,9 +6465,9 @@
"dev": true
},
"d3-array": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.0.3.tgz",
- "integrity": "sha512-C7g4aCOoJa+/K5hPVqZLG8wjYHsTUROTk7Z1Ep9F4P5l+WVrvV0+6nAZ1wKTRLMhFWpGbozxUpyjIPZYAaLi+g=="
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.0.2.tgz",
+ "integrity": "sha512-dbjbKhMdnTW6ToWsopRs4/+ZPOsqQE1QeeoUEvzIqhdkT29zzAUcUh8HMb92tTITVlbW/G0UBz4ryBqC2RTUIA=="
},
"d3-axis": {
"version": "1.0.12",
@@ -6478,7 +6582,7 @@
},
"dashify": {
"version": "0.2.2",
- "resolved": "http://registry.npmjs.org/dashify/-/dashify-0.2.2.tgz",
+ "resolved": "https://registry.npmjs.org/dashify/-/dashify-0.2.2.tgz",
"integrity": "sha1-agdBWgHJH69KMuONnfunH2HLIP4=",
"dev": true
},
@@ -6534,7 +6638,7 @@
},
"camelcase-keys": {
"version": "2.1.0",
- "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
"integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
"dev": true,
"requires": {
@@ -6559,7 +6663,7 @@
},
"meow": {
"version": "3.7.0",
- "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
"integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
"dev": true,
"requires": {
@@ -6577,7 +6681,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
@@ -6619,9 +6723,9 @@
}
},
"debug": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
- "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz",
+ "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==",
"requires": {
"ms": "^2.1.1"
}
@@ -6845,7 +6949,7 @@
},
"diffie-hellman": {
"version": "5.0.3",
- "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
"integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
"dev": true,
"requires": {
@@ -6903,6 +7007,14 @@
"prismjs": "^1.15.0",
"tinydate": "^1.0.0",
"tweezer.js": "^1.4.0"
+ },
+ "dependencies": {
+ "marked": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-0.5.2.tgz",
+ "integrity": "sha512-fdZvBa7/vSQIZCi4uuwo2N3q+7jJURpMVCcbaX0S1Mg65WZ5ilXvC67MviJAsdjqqgD+CEq4RKo5AYGgINkVAA==",
+ "dev": true
+ }
}
},
"docsify-cli": {
@@ -6942,7 +7054,7 @@
},
"chalk": {
"version": "1.1.3",
- "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
@@ -6975,7 +7087,7 @@
},
"os-locale": {
"version": "1.4.0",
- "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
"integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
"dev": true,
"requires": {
@@ -6984,7 +7096,7 @@
},
"string-width": {
"version": "1.0.2",
- "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"requires": {
@@ -6995,7 +7107,7 @@
},
"supports-color": {
"version": "2.0.0",
- "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
},
@@ -7107,7 +7219,7 @@
"dependencies": {
"domelementtype": {
"version": "1.1.3",
- "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
"integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs="
}
}
@@ -7164,7 +7276,7 @@
},
"duplexer": {
"version": "0.1.1",
- "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
"dev": true
},
@@ -7188,7 +7300,7 @@
"dependencies": {
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -7203,7 +7315,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
@@ -7236,7 +7348,7 @@
"dependencies": {
"lru-cache": {
"version": "3.2.0",
- "resolved": "http://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz",
"integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=",
"dev": true,
"requires": {
@@ -7258,14 +7370,9 @@
"dev": true
},
"electron-to-chromium": {
- "version": "1.3.96",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.96.tgz",
- "integrity": "sha512-ZUXBUyGLeoJxp4Nt6G/GjBRLnyz8IKQGexZ2ndWaoegThgMGFO1tdDYID5gBV32/1S83osjJHyfzvanE/8HY4Q=="
- },
- "element-closest": {
- "version": "2.0.2",
- "resolved": "http://registry.npmjs.org/element-closest/-/element-closest-2.0.2.tgz",
- "integrity": "sha1-cqdAoQdFM4LijfnOXbtajfD5Zuw="
+ "version": "1.3.94",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.94.tgz",
+ "integrity": "sha512-miQqXALb6eBD3OetCtg3UM5XTLMwHISux0l6mh14iiV5SE+qvftgOCXT9Vvp53fWaCLET4sfA/SmIMYHXkaNmw=="
},
"elliptic": {
"version": "6.4.1",
@@ -7459,7 +7566,7 @@
},
"es6-promisify": {
"version": "5.0.0",
- "resolved": "http://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
"dev": true,
"requires": {
@@ -7543,9 +7650,9 @@
},
"dependencies": {
"acorn": {
- "version": "6.0.4",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz",
- "integrity": "sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==",
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.5.tgz",
+ "integrity": "sha512-i33Zgp3XWtmZBMNvCr4azvOFeWVw1Rk6p3hfi3LUDvIFraOMywb1kAtrbi+med14m4Xfpqm3zRZMT+c0FNE7kg==",
"dev": true
},
"acorn-jsx": {
@@ -7784,7 +7891,7 @@
},
"espree": {
"version": "3.5.4",
- "resolved": "http://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
"integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
"requires": {
"acorn": "^5.5.0",
@@ -7830,13 +7937,13 @@
},
"eventemitter2": {
"version": "0.4.14",
- "resolved": "http://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
"integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
"dev": true
},
"events": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/events/-/events-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
"integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
"dev": true
},
@@ -7896,7 +8003,7 @@
},
"expand-range": {
"version": "1.8.2",
- "resolved": "http://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+ "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
"integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
"requires": {
"fill-range": "^2.1.0"
@@ -7964,7 +8071,7 @@
},
"external-editor": {
"version": "2.2.0",
- "resolved": "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
"integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
"requires": {
"chardet": "^0.4.0",
@@ -8119,7 +8226,7 @@
},
"is-accessor-descriptor": {
"version": "0.1.6",
- "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
"integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
"dev": true,
"requires": {
@@ -8139,7 +8246,7 @@
},
"is-data-descriptor": {
"version": "0.1.4",
- "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
"integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
"dev": true,
"requires": {
@@ -8410,7 +8517,7 @@
"dependencies": {
"core-js": {
"version": "1.2.7",
- "resolved": "http://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
}
}
@@ -8544,13 +8651,13 @@
"dependencies": {
"colors": {
"version": "0.6.2",
- "resolved": "http://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
"integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=",
"dev": true
},
"commander": {
"version": "2.1.0",
- "resolved": "http://registry.npmjs.org/commander/-/commander-2.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz",
"integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=",
"dev": true
}
@@ -8558,7 +8665,7 @@
},
"findup-sync": {
"version": "0.3.0",
- "resolved": "http://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
"integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=",
"dev": true,
"requires": {
@@ -8615,7 +8722,7 @@
"dependencies": {
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -8630,7 +8737,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
@@ -8699,7 +8806,7 @@
"dependencies": {
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -8714,7 +8821,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
@@ -8773,7 +8880,7 @@
"dependencies": {
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -8788,7 +8895,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
@@ -8814,21 +8921,25 @@
"dependencies": {
"abbrev": {
"version": "1.1.1",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"optional": true
},
"ansi-regex": {
"version": "2.1.1",
- "bundled": true
+ "resolved": false,
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
},
"aproba": {
"version": "1.2.0",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
"optional": true
},
"are-we-there-yet": {
"version": "1.1.4",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
"optional": true,
"requires": {
"delegates": "^1.0.0",
@@ -8837,13 +8948,13 @@
},
"balanced-match": {
"version": "1.0.0",
- "bundled": true,
- "optional": true
+ "resolved": false,
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"brace-expansion": {
"version": "1.1.11",
- "bundled": true,
- "optional": true,
+ "resolved": false,
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -8851,32 +8962,35 @@
},
"chownr": {
"version": "1.0.1",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=",
"optional": true
},
"code-point-at": {
"version": "1.1.0",
- "bundled": true,
- "optional": true
+ "resolved": false,
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
},
"concat-map": {
"version": "0.0.1",
- "bundled": true,
- "optional": true
+ "resolved": false,
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"console-control-strings": {
"version": "1.1.0",
- "bundled": true,
- "optional": true
+ "resolved": false,
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
},
"core-util-is": {
"version": "1.0.2",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"optional": true
},
"debug": {
"version": "2.6.9",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"optional": true,
"requires": {
"ms": "2.0.0"
@@ -8884,22 +8998,26 @@
},
"deep-extend": {
"version": "0.5.1",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==",
"optional": true
},
"delegates": {
"version": "1.0.0",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
"optional": true
},
"detect-libc": {
"version": "1.0.3",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
"optional": true
},
"fs-minipass": {
"version": "1.2.5",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==",
"optional": true,
"requires": {
"minipass": "^2.2.1"
@@ -8907,12 +9025,14 @@
},
"fs.realpath": {
"version": "1.0.0",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"optional": true
},
"gauge": {
"version": "2.7.4",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
"optional": true,
"requires": {
"aproba": "^1.0.3",
@@ -8927,7 +9047,8 @@
},
"glob": {
"version": "7.1.2",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"optional": true,
"requires": {
"fs.realpath": "^1.0.0",
@@ -8940,12 +9061,14 @@
},
"has-unicode": {
"version": "2.0.1",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
"optional": true
},
"iconv-lite": {
"version": "0.4.21",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==",
"optional": true,
"requires": {
"safer-buffer": "^2.1.0"
@@ -8953,7 +9076,8 @@
},
"ignore-walk": {
"version": "3.0.1",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
"optional": true,
"requires": {
"minimatch": "^3.0.4"
@@ -8961,7 +9085,8 @@
},
"inflight": {
"version": "1.0.6",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"optional": true,
"requires": {
"once": "^1.3.0",
@@ -8970,44 +9095,46 @@
},
"inherits": {
"version": "2.0.3",
- "bundled": true,
- "optional": true
+ "resolved": false,
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"ini": {
"version": "1.3.5",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
"optional": true
},
"is-fullwidth-code-point": {
"version": "1.0.0",
- "bundled": true,
- "optional": true,
+ "resolved": false,
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"requires": {
"number-is-nan": "^1.0.0"
}
},
"isarray": {
"version": "1.0.0",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
"optional": true
},
"minimatch": {
"version": "3.0.4",
- "bundled": true,
- "optional": true,
+ "resolved": false,
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
- "bundled": true,
- "optional": true
+ "resolved": false,
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
},
"minipass": {
"version": "2.2.4",
- "bundled": true,
- "optional": true,
+ "resolved": false,
+ "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
@@ -9015,7 +9142,8 @@
},
"minizlib": {
"version": "1.1.0",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==",
"optional": true,
"requires": {
"minipass": "^2.2.1"
@@ -9023,20 +9151,22 @@
},
"mkdirp": {
"version": "0.5.1",
- "bundled": true,
- "optional": true,
+ "resolved": false,
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"requires": {
"minimist": "0.0.8"
}
},
"ms": {
"version": "2.0.0",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"optional": true
},
"needle": {
"version": "2.2.0",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==",
"optional": true,
"requires": {
"debug": "^2.1.2",
@@ -9046,7 +9176,8 @@
},
"node-pre-gyp": {
"version": "0.10.0",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==",
"optional": true,
"requires": {
"detect-libc": "^1.0.2",
@@ -9063,7 +9194,8 @@
},
"nopt": {
"version": "4.0.1",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
"optional": true,
"requires": {
"abbrev": "1",
@@ -9072,12 +9204,14 @@
},
"npm-bundled": {
"version": "1.0.3",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==",
"optional": true
},
"npm-packlist": {
"version": "1.1.10",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==",
"optional": true,
"requires": {
"ignore-walk": "^3.0.1",
@@ -9086,7 +9220,8 @@
},
"npmlog": {
"version": "4.1.2",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
"optional": true,
"requires": {
"are-we-there-yet": "~1.1.2",
@@ -9097,35 +9232,39 @@
},
"number-is-nan": {
"version": "1.0.1",
- "bundled": true,
- "optional": true
+ "resolved": false,
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
},
"object-assign": {
"version": "4.1.1",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
"optional": true
},
"once": {
"version": "1.4.0",
- "bundled": true,
- "optional": true,
+ "resolved": false,
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1"
}
},
"os-homedir": {
"version": "1.0.2",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
"optional": true
},
"os-tmpdir": {
"version": "1.0.2",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
"optional": true
},
"osenv": {
"version": "0.1.5",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
"optional": true,
"requires": {
"os-homedir": "^1.0.0",
@@ -9134,17 +9273,20 @@
},
"path-is-absolute": {
"version": "1.0.1",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"optional": true
},
"process-nextick-args": {
"version": "2.0.0",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
"optional": true
},
"rc": {
"version": "1.2.7",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==",
"optional": true,
"requires": {
"deep-extend": "^0.5.1",
@@ -9155,14 +9297,16 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"optional": true
}
}
},
"readable-stream": {
"version": "2.3.6",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"optional": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -9176,7 +9320,8 @@
},
"rimraf": {
"version": "2.6.2",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
"optional": true,
"requires": {
"glob": "^7.0.5"
@@ -9184,37 +9329,43 @@
},
"safe-buffer": {
"version": "5.1.1",
- "bundled": true
+ "resolved": false,
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
},
"safer-buffer": {
"version": "2.1.2",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"optional": true
},
"sax": {
"version": "1.2.4",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"optional": true
},
"semver": {
"version": "5.5.0",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
"optional": true
},
"set-blocking": {
"version": "2.0.0",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
"optional": true
},
"signal-exit": {
"version": "3.0.2",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
"optional": true
},
"string-width": {
"version": "1.0.2",
- "bundled": true,
- "optional": true,
+ "resolved": false,
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -9223,7 +9374,8 @@
},
"string_decoder": {
"version": "1.1.1",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"optional": true,
"requires": {
"safe-buffer": "~5.1.0"
@@ -9231,19 +9383,22 @@
},
"strip-ansi": {
"version": "3.0.1",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
"ansi-regex": "^2.0.0"
}
},
"strip-json-comments": {
"version": "2.0.1",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
"optional": true
},
"tar": {
"version": "4.4.1",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==",
"optional": true,
"requires": {
"chownr": "^1.0.1",
@@ -9257,12 +9412,14 @@
},
"util-deprecate": {
"version": "1.0.2",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"optional": true
},
"wide-align": {
"version": "1.1.2",
- "bundled": true,
+ "resolved": false,
+ "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
"optional": true,
"requires": {
"string-width": "^1.0.2"
@@ -9270,11 +9427,13 @@
},
"wrappy": {
"version": "1.0.2",
- "bundled": true
+ "resolved": false,
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"yallist": {
"version": "3.0.2",
- "bundled": true
+ "resolved": false,
+ "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k="
}
}
},
@@ -9337,7 +9496,7 @@
},
"string-width": {
"version": "1.0.2",
- "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"requires": {
@@ -9405,7 +9564,7 @@
},
"camelcase-keys": {
"version": "2.1.0",
- "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
"integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
"dev": true,
"requires": {
@@ -9430,7 +9589,7 @@
},
"meow": {
"version": "3.7.0",
- "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
"integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
"dev": true,
"requires": {
@@ -9448,7 +9607,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
@@ -9493,7 +9652,7 @@
},
"get-stream": {
"version": "3.0.0",
- "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
},
"get-value": {
@@ -9517,7 +9676,7 @@
},
"gettext-parser": {
"version": "1.4.0",
- "resolved": "http://registry.npmjs.org/gettext-parser/-/gettext-parser-1.4.0.tgz",
+ "resolved": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-1.4.0.tgz",
"integrity": "sha512-sedZYLHlHeBop/gZ1jdg59hlUEcpcZJofLq2JFwJT1zTqAU3l2wFv6IsuwFHGqbiT9DWzMUW4/em2+hspnmMMA==",
"requires": {
"encoding": "^0.1.12",
@@ -9581,7 +9740,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
@@ -9690,7 +9849,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
@@ -9896,7 +10055,7 @@
"dependencies": {
"minimist": {
"version": "1.1.3",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.1.3.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.3.tgz",
"integrity": "sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=",
"dev": true
}
@@ -9912,7 +10071,7 @@
},
"got": {
"version": "6.7.1",
- "resolved": "http://registry.npmjs.org/got/-/got-6.7.1.tgz",
+ "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
"integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
"dev": true,
"requires": {
@@ -10003,7 +10162,7 @@
},
"grunt-cli": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz",
"integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=",
"dev": true,
"requires": {
@@ -10025,7 +10184,7 @@
},
"resolve": {
"version": "1.1.7",
- "resolved": "http://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
"integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
"dev": true
}
@@ -10049,7 +10208,7 @@
},
"chalk": {
"version": "0.2.1",
- "resolved": "http://registry.npmjs.org/chalk/-/chalk-0.2.1.tgz",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.2.1.tgz",
"integrity": "sha1-dhPhV1FFshOGSD9/SFql/6jL0Qw=",
"dev": true,
"requires": {
@@ -10075,6 +10234,14 @@
"grunt-legacy-log-utils": "~2.0.0",
"hooker": "~0.2.3",
"lodash": "~4.17.5"
+ },
+ "dependencies": {
+ "colors": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+ "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
+ "dev": true
+ }
}
},
"grunt-legacy-log-utils": {
@@ -10104,7 +10271,7 @@
"dependencies": {
"async": {
"version": "1.5.2",
- "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
"dev": true
}
@@ -10309,11 +10476,6 @@
"minimalistic-crypto-utils": "^1.0.1"
}
},
- "hoist-non-react-statics": {
- "version": "1.2.0",
- "resolved": "http://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz",
- "integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs="
- },
"home-or-tmp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
@@ -10390,7 +10552,7 @@
},
"http-errors": {
"version": "1.6.3",
- "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
"dev": true,
"requires": {
@@ -10482,16 +10644,16 @@
}
},
"husky": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/husky/-/husky-1.2.1.tgz",
- "integrity": "sha512-4Ylal3HWhnDvIszuiyLoVrSGI7QLg/ogkNCoHE34c+yZYzb9kBZNrlTOsdw92cGi3cJT8pPb6CdVfxFkLnc8Dg==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-1.3.1.tgz",
+ "integrity": "sha512-86U6sVVVf4b5NYSZ0yvv88dRgBSSXXmHaiq5pP4KDj5JVzdwKgBjEtUPOm8hcoytezFwbU+7gotXNhpHdystlg==",
"dev": true,
"requires": {
"cosmiconfig": "^5.0.7",
"execa": "^1.0.0",
"find-up": "^3.0.0",
"get-stdin": "^6.0.0",
- "is-ci": "^1.2.1",
+ "is-ci": "^2.0.0",
"pkg-dir": "^3.0.0",
"please-upgrade-node": "^3.1.1",
"read-pkg": "^4.0.1",
@@ -10499,6 +10661,12 @@
"slash": "^2.0.0"
},
"dependencies": {
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -10551,6 +10719,15 @@
"pump": "^3.0.0"
}
},
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
@@ -10610,6 +10787,16 @@
"find-up": "^3.0.0"
}
},
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
"read-pkg": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz",
@@ -10871,9 +11058,9 @@
}
},
"interpret": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz",
- "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
+ "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=",
"dev": true
},
"invariant": {
@@ -10902,7 +11089,7 @@
},
"is-accessor-descriptor": {
"version": "0.1.6",
- "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
"integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
"requires": {
"kind-of": "^3.0.2"
@@ -10956,7 +11143,7 @@
},
"is-builtin-module": {
"version": "1.0.0",
- "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
"integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
"requires": {
"builtin-modules": "^1.0.0"
@@ -10977,7 +11164,7 @@
},
"is-data-descriptor": {
"version": "0.1.4",
- "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
"integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
"requires": {
"kind-of": "^3.0.2"
@@ -11055,7 +11242,7 @@
},
"is-generator-fn": {
"version": "1.0.0",
- "resolved": "http://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz",
"integrity": "sha1-lp1J4bszKfa7fwkIm+JleLLd1Go="
},
"is-glob": {
@@ -11114,7 +11301,7 @@
},
"is-obj": {
"version": "1.0.1",
- "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
"dev": true
},
@@ -11407,11 +11594,6 @@
"integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==",
"dev": true
},
- "jed": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/jed/-/jed-1.1.1.tgz",
- "integrity": "sha1-elSbvZ/+FYWwzQoZHiAwVb7ldLQ="
- },
"jest": {
"version": "23.6.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-23.6.0.tgz",
@@ -11678,7 +11860,7 @@
},
"jest-environment-jsdom": {
"version": "22.4.3",
- "resolved": "http://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz",
"integrity": "sha512-FviwfR+VyT3Datf13+ULjIMO5CSeajlayhhYQwpzgunswoaLIPutdbrnfUHEMyJCwvqQFaVtTmn9+Y8WCt6n1w==",
"requires": {
"jest-mock": "^22.4.3",
@@ -11746,7 +11928,7 @@
},
"jest-get-type": {
"version": "22.4.3",
- "resolved": "http://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz",
"integrity": "sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w=="
},
"jest-haste-map": {
@@ -11837,7 +12019,7 @@
},
"jest-message-util": {
"version": "22.4.3",
- "resolved": "http://registry.npmjs.org/jest-message-util/-/jest-message-util-22.4.3.tgz",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-22.4.3.tgz",
"integrity": "sha512-iAMeKxhB3Se5xkSjU0NndLLCHtP4n+GtCqV0bISKA5dmOXQfEbdEmYiu2qpnWBDCQdEafNDDU6Q+l6oBMd/+BA==",
"requires": {
"@babel/code-frame": "^7.0.0-beta.35",
@@ -11849,7 +12031,7 @@
},
"jest-mock": {
"version": "22.4.3",
- "resolved": "http://registry.npmjs.org/jest-mock/-/jest-mock-22.4.3.tgz",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-22.4.3.tgz",
"integrity": "sha512-+4R6mH5M1G4NK16CKg9N1DtCaFmuxhcIqF4lQK/Q1CIotqMs/XBemfpDPeVZBFow6iyUNu6EBT9ugdNOTT5o5Q=="
},
"jest-regex-util": {
@@ -12085,7 +12267,7 @@
},
"jest-util": {
"version": "22.4.3",
- "resolved": "http://registry.npmjs.org/jest-util/-/jest-util-22.4.3.tgz",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-22.4.3.tgz",
"integrity": "sha512-rfDfG8wyC5pDPNdcnAlZgwKnzHvZDu8Td2NJI/jAGKEGxJPYiE4F0ss/gSAkG4778Y23Hvbz+0GMrDJTeo7RjQ==",
"requires": {
"callsites": "^2.0.0",
@@ -12242,12 +12424,12 @@
},
"json5": {
"version": "0.5.1",
- "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE="
},
"jsonfile": {
"version": "2.4.0",
- "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
"integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
"dev": true,
"requires": {
@@ -12322,26 +12504,26 @@
"integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA=="
},
"lerna": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.8.0.tgz",
- "integrity": "sha512-OLdf7JSWjpgVecvVLyTRpeKPjTJOcQa366IvaEhorOIxFPZvR1rNIEvi4DMOAaxNINpmCB4nSm769H7H4jNQyw==",
+ "version": "3.8.4",
+ "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.8.4.tgz",
+ "integrity": "sha512-bmFDfYiHhgaDndFT9o0HcQ7jNHi5OVF47Y8hWZWtVOpQuVDAYiAKXwtFCNoqgzIeZxsdGXI/VoW9aZ/IPHErMw==",
"dev": true,
"requires": {
- "@lerna/add": "^3.7.2",
- "@lerna/bootstrap": "^3.7.2",
- "@lerna/changed": "^3.8.0",
- "@lerna/clean": "^3.7.2",
+ "@lerna/add": "^3.8.2",
+ "@lerna/bootstrap": "^3.8.2",
+ "@lerna/changed": "^3.8.2",
+ "@lerna/clean": "^3.8.1",
"@lerna/cli": "^3.6.0",
- "@lerna/create": "^3.7.2",
- "@lerna/diff": "^3.7.2",
- "@lerna/exec": "^3.7.2",
- "@lerna/import": "^3.7.2",
- "@lerna/init": "^3.7.2",
- "@lerna/link": "^3.7.2",
- "@lerna/list": "^3.7.2",
- "@lerna/publish": "^3.8.0",
- "@lerna/run": "^3.7.2",
- "@lerna/version": "^3.8.0",
+ "@lerna/create": "^3.8.1",
+ "@lerna/diff": "^3.8.1",
+ "@lerna/exec": "^3.8.1",
+ "@lerna/import": "^3.8.1",
+ "@lerna/init": "^3.8.1",
+ "@lerna/link": "^3.8.1",
+ "@lerna/list": "^3.8.1",
+ "@lerna/publish": "^3.8.4",
+ "@lerna/run": "^3.8.1",
+ "@lerna/version": "^3.8.2",
"import-local": "^1.0.0",
"libnpm": "^2.0.1"
}
@@ -12414,6 +12596,16 @@
"requires": {
"pump": "^3.0.0"
}
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
}
}
},
@@ -12499,6 +12691,16 @@
"requires": {
"pump": "^3.0.0"
}
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
}
}
},
@@ -12528,6 +12730,16 @@
"requires": {
"pump": "^3.0.0"
}
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
}
}
},
@@ -12563,6 +12775,16 @@
"pump": "^3.0.0"
}
},
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
"ssri": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
@@ -12593,6 +12815,16 @@
"requires": {
"pump": "^3.0.0"
}
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
}
}
},
@@ -12622,6 +12854,16 @@
"requires": {
"pump": "^3.0.0"
}
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
}
}
},
@@ -12677,7 +12919,7 @@
},
"load-json-file": {
"version": "1.1.0",
- "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
"requires": {
"graceful-fs": "^4.1.2",
@@ -12745,31 +12987,14 @@
"dev": true
},
"loader-utils": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz",
- "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+ "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
"dev": true,
"requires": {
- "big.js": "^5.2.2",
+ "big.js": "^3.1.3",
"emojis-list": "^2.0.0",
- "json5": "^1.0.1"
- },
- "dependencies": {
- "json5": {
- "version": "1.0.1",
- "resolved": "http://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
- "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
- "dev": true,
- "requires": {
- "minimist": "^1.2.0"
- }
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- }
+ "json5": "^0.5.0"
}
},
"locate-path": {
@@ -13068,6 +13293,16 @@
"through2": "^2.0.0"
}
},
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
"ssri": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
@@ -13139,14 +13374,9 @@
"dev": true
},
"marked": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/marked/-/marked-0.5.2.tgz",
- "integrity": "sha512-fdZvBa7/vSQIZCi4uuwo2N3q+7jJURpMVCcbaX0S1Mg65WZ5ilXvC67MviJAsdjqqgD+CEq4RKo5AYGgINkVAA=="
- },
- "material-colors": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz",
- "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg=="
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-0.6.0.tgz",
+ "integrity": "sha512-HduzIW2xApSXKXJSpCipSxKyvMbwRRa/TwMbepmlZziKdH8548WSoDP4SxzulEKjlo8BE39l+2fwJZuRKOln6g=="
},
"math-random": {
"version": "1.0.1",
@@ -13181,7 +13411,7 @@
},
"medium-zoom": {
"version": "0.4.0",
- "resolved": "http://registry.npmjs.org/medium-zoom/-/medium-zoom-0.4.0.tgz",
+ "resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-0.4.0.tgz",
"integrity": "sha512-0z7yMfd6I1BTCAa8QaR4cp5AqDkQD571GzhHIbbfefKEssGLSvs+4Xai/itOAncm4FBlF5gUoMQ22yW9/f8Sig==",
"dev": true
},
@@ -13210,7 +13440,7 @@
"dependencies": {
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -13225,7 +13455,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
@@ -13332,7 +13562,7 @@
"dependencies": {
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@@ -13346,7 +13576,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
@@ -13436,7 +13666,7 @@
},
"minimist": {
"version": "0.0.8",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
},
"minimist-options": {
@@ -13491,18 +13721,6 @@
"pumpify": "^1.3.3",
"stream-each": "^1.1.0",
"through2": "^2.0.0"
- },
- "dependencies": {
- "pump": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
- "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
- "dev": true,
- "requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- }
}
},
"mixin-deep": {
@@ -13544,7 +13762,7 @@
},
"mkdirp": {
"version": "0.5.1",
- "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"requires": {
"minimist": "0.0.8"
@@ -13600,7 +13818,7 @@
},
"multimatch": {
"version": "2.1.0",
- "resolved": "http://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz",
"integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=",
"dev": true,
"requires": {
@@ -13612,13 +13830,13 @@
},
"mute-stream": {
"version": "0.0.7",
- "resolved": "http://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
},
"nan": {
- "version": "2.12.1",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz",
- "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw=="
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.0.tgz",
+ "integrity": "sha512-zT5nC0JhbljmyEf+Z456nvm7iO7XgRV2hYxoBtPpnyp+0Q4aCoP6uWNn76v/I6k2kCYNLWqWbwBWQcjsNI/bjw=="
},
"nanomatch": {
"version": "1.2.13",
@@ -13661,12 +13879,12 @@
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
},
"nearley": {
- "version": "2.16.0",
- "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.16.0.tgz",
- "integrity": "sha512-Tr9XD3Vt/EujXbZBv6UAHYoLUSMQAxSsTnm9K3koXzjzNWY195NqALeyrzLZBKzAkL3gl92BcSogqrHjD8QuUg==",
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.15.1.tgz",
+ "integrity": "sha512-8IUY/rUrKz2mIynUGh8k+tul1awMKEjeHHC5G3FHvvyAW6oq4mQfNp2c0BMea+sYZJvYcrrM6GmZVIle/GRXGw==",
"requires": {
- "commander": "^2.19.0",
"moo": "^0.4.3",
+ "nomnom": "~1.6.2",
"railroad-diagrams": "^1.0.0",
"randexp": "0.4.6",
"semver": "^5.4.1"
@@ -13747,7 +13965,7 @@
"dependencies": {
"semver": {
"version": "5.3.0",
- "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
"dev": true
}
@@ -13797,7 +14015,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -13812,7 +14030,7 @@
"dependencies": {
"string_decoder": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
@@ -13835,9 +14053,9 @@
}
},
"node-releases": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.3.tgz",
- "integrity": "sha512-6VrvH7z6jqqNFY200kdB6HdzkgM96Oaj9v3dqGfgp6mF+cHmU4wyQKZ2/WPDRVoR0Jz9KqbamaBN0ZhdUaysUQ==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.1.tgz",
+ "integrity": "sha512-2UXrBr6gvaebo5TNF84C66qyJJ6r0kxBObgZIDX3D3/mt1ADKiHux3NJPWisq0wxvJJdkjECH+9IIKYViKj71Q==",
"requires": {
"semver": "^5.3.0"
}
@@ -13883,7 +14101,7 @@
},
"camelcase-keys": {
"version": "2.1.0",
- "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
"integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
"dev": true,
"requires": {
@@ -13893,7 +14111,7 @@
},
"chalk": {
"version": "1.1.3",
- "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
@@ -13931,7 +14149,7 @@
},
"meow": {
"version": "3.7.0",
- "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
"integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
"dev": true,
"requires": {
@@ -13949,7 +14167,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
@@ -13974,7 +14192,7 @@
},
"supports-color": {
"version": "2.0.0",
- "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
},
@@ -14014,12 +14232,21 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
}
}
},
+ "nomnom": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.6.2.tgz",
+ "integrity": "sha1-hKZqJgF0QI/Ft3oY+IjszET7aXE=",
+ "requires": {
+ "colors": "0.5.x",
+ "underscore": "~1.4.4"
+ }
+ },
"nopt": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
@@ -14402,7 +14629,7 @@
"dependencies": {
"ansi-escapes": {
"version": "1.4.0",
- "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
"integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
"dev": true
},
@@ -14414,7 +14641,7 @@
},
"chalk": {
"version": "1.1.3",
- "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
@@ -14448,13 +14675,13 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
"node-fetch": {
"version": "1.6.3",
- "resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz",
"integrity": "sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ=",
"dev": true,
"requires": {
@@ -14464,7 +14691,7 @@
},
"opn": {
"version": "4.0.2",
- "resolved": "http://registry.npmjs.org/opn/-/opn-4.0.2.tgz",
+ "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz",
"integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=",
"dev": true,
"requires": {
@@ -14474,7 +14701,7 @@
},
"supports-color": {
"version": "2.0.0",
- "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
}
@@ -14538,7 +14765,7 @@
},
"os-homedir": {
"version": "1.0.2",
- "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
},
"os-locale": {
@@ -14553,7 +14780,7 @@
},
"os-tmpdir": {
"version": "1.0.2",
- "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
},
"osenv": {
@@ -14590,7 +14817,7 @@
},
"p-is-promise": {
"version": "1.1.0",
- "resolved": "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
"integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=",
"dev": true
},
@@ -14756,6 +14983,16 @@
"through2": "^2.0.0"
}
},
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
"ssri": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
@@ -14813,7 +15050,7 @@
"dependencies": {
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -14828,7 +15065,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
@@ -14845,7 +15082,7 @@
},
"parse-asn1": {
"version": "5.1.1",
- "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
"integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==",
"dev": true,
"requires": {
@@ -14922,7 +15159,7 @@
},
"path-browserify": {
"version": "0.0.0",
- "resolved": "http://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
"integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=",
"dev": true
},
@@ -14939,7 +15176,7 @@
},
"path-is-absolute": {
"version": "1.0.1",
- "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"path-is-inside": {
@@ -15017,7 +15254,7 @@
},
"pify": {
"version": "2.3.0",
- "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
},
"pinkie": {
@@ -15068,11 +15305,6 @@
"resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
"integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA=="
},
- "popper.js": {
- "version": "1.14.6",
- "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.6.tgz",
- "integrity": "sha512-AGwHGQBKumlk/MDfrSOf0JHhJCImdDMcGNoqKmKkU+68GFazv3CQ6q9r7Ja1sKDZmYWTckY/uLyEznheTDycnA=="
- },
"posix-character-classes": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
@@ -15145,7 +15377,7 @@
},
"chalk": {
"version": "1.1.3",
- "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
@@ -15158,7 +15390,7 @@
"dependencies": {
"supports-color": {
"version": "2.0.0",
- "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
}
@@ -15397,15 +15629,15 @@
}
},
"postcss-reporter": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-6.0.1.tgz",
- "integrity": "sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-6.0.0.tgz",
+ "integrity": "sha512-5xQXm1UPWuFObjbtyQzWvQaupru8yFcFi4HUlm6OPo1o2bUszYASuqRJ7bVArb3svGCdbYtqdMBKrqR1Aoy+tw==",
"dev": true,
"requires": {
- "chalk": "^2.4.1",
- "lodash": "^4.17.11",
- "log-symbols": "^2.2.0",
- "postcss": "^7.0.7"
+ "chalk": "^2.0.1",
+ "lodash": "^4.17.4",
+ "log-symbols": "^2.0.0",
+ "postcss": "^7.0.2"
},
"dependencies": {
"postcss": {
@@ -15649,7 +15881,7 @@
},
"globby": {
"version": "6.1.0",
- "resolved": "http://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
"integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
"dev": true,
"requires": {
@@ -15707,7 +15939,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
@@ -15905,9 +16137,9 @@
}
},
"pump": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
@@ -15923,18 +16155,6 @@
"duplexify": "^3.6.0",
"inherits": "^2.0.3",
"pump": "^2.0.0"
- },
- "dependencies": {
- "pump": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
- "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
- "dev": true,
- "requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- }
}
},
"punycode": {
@@ -16068,21 +16288,26 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
}
}
},
+ "re-resizable": {
+ "version": "4.11.0",
+ "resolved": "https://registry.npmjs.org/re-resizable/-/re-resizable-4.11.0.tgz",
+ "integrity": "sha512-dye+7rERqNf/6mDT1iwps+4Gf42420xuZgygF33uX178DxffqcyeuHbBuJ382FIcB5iP6mMZOhfW7kI0uXwb/Q=="
+ },
"react": {
- "version": "16.7.0",
- "resolved": "https://registry.npmjs.org/react/-/react-16.7.0.tgz",
- "integrity": "sha512-StCz3QY8lxTb5cl2HJxjwLFOXPIFQp+p+hxQfc8WE0QiLfCtIlKj8/+5tjjKm8uSTlAW+fCPaavGFS06V9Ar3A==",
+ "version": "16.6.3",
+ "resolved": "https://registry.npmjs.org/react/-/react-16.6.3.tgz",
+ "integrity": "sha512-zCvmH2vbEolgKxtqXL2wmGCUxUyNheYn/C+PD1YAjfxHC54+MhdruyhO7QieQrYsYeTxrn93PM2y0jRH1zEExw==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
- "scheduler": "^0.12.0"
+ "scheduler": "^0.11.2"
}
},
"react-addons-create-fragment": {
@@ -16119,30 +16344,6 @@
}
}
},
- "react-color": {
- "version": "2.17.0",
- "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.17.0.tgz",
- "integrity": "sha512-kJfE5tSaFe6GzalXOHksVjqwCPAsTl+nzS9/BWfP7j3EXbQ4IiLAF9sZGNzk3uq7HfofGYgjmcUgh0JP7xAQ0w==",
- "requires": {
- "@icons/material": "^0.2.4",
- "lodash": ">4.17.4",
- "material-colors": "^1.2.1",
- "prop-types": "^15.5.10",
- "reactcss": "^1.2.0",
- "tinycolor2": "^1.4.1"
- }
- },
- "react-datepicker": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-1.8.0.tgz",
- "integrity": "sha512-N4LdVTtqJCsZyKXBQ/AqSEcH6FyhgsY1gD07zECNu60nGt5s4ngRlhYdHoE34VNFO+ZY+pvljZRLwSC8LS9RxQ==",
- "requires": {
- "classnames": "^2.2.5",
- "prop-types": "^15.6.0",
- "react-onclickoutside": "^6.7.1",
- "react-popper": "^1.0.2"
- }
- },
"react-dates": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dates/-/react-dates-18.3.1.tgz",
@@ -16187,7 +16388,7 @@
},
"babylon": {
"version": "5.8.38",
- "resolved": "http://registry.npmjs.org/babylon/-/babylon-5.8.38.tgz",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-5.8.38.tgz",
"integrity": "sha1-7JsSCxG/bM1Bc6GL8hfmC3mFn/0=",
"dev": true
},
@@ -16219,20 +16420,20 @@
}
},
"react-dom": {
- "version": "16.7.0",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.7.0.tgz",
- "integrity": "sha512-D0Ufv1ExCAmF38P2Uh1lwpminZFRXEINJe53zRAbm4KPwSyd6DY/uDoS0Blj9jvPpn1+wivKpZYc8aAAN/nAkg==",
+ "version": "16.6.3",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.6.3.tgz",
+ "integrity": "sha512-8ugJWRCWLGXy+7PmNh8WJz3g1TaTUt1XyoIcFN+x0Zbkoz+KKdUyx1AQLYJdbFXjuF41Nmjn5+j//rxvhFjgSQ==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
- "scheduler": "^0.12.0"
+ "scheduler": "^0.11.2"
}
},
"react-is": {
- "version": "16.7.0",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.7.0.tgz",
- "integrity": "sha512-Z0VRQdF4NPDoI0tsXVMLkJLiwEBa+RP66g0xDHxgxysxSoCUccSten4RTF/UFvZF1dZvZ9Zu1sx+MDXwcOR34g=="
+ "version": "16.6.3",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.6.3.tgz",
+ "integrity": "sha512-u7FDWtthB4rWibG/+mFbVd5FvdI20yde86qKGx4lVUTWmPlSWQ4QxbBIrrs+HnXGbxOUlUzTAP/VDmvCwaP2yA=="
},
"react-lifecycles-compat": {
"version": "3.0.4",
@@ -16280,11 +16481,6 @@
"moment": ">=1.6.0"
}
},
- "react-onclickoutside": {
- "version": "6.7.1",
- "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.7.1.tgz",
- "integrity": "sha512-p84kBqGaMoa7VYT0vZ/aOYRfJB+gw34yjpda1Z5KeLflg70HipZOT+MXQenEhdkPAABuE2Astq4zEPdMqUQxcg=="
- },
"react-outside-click-handler": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/react-outside-click-handler/-/react-outside-click-handler-1.2.2.tgz",
@@ -16296,19 +16492,6 @@
"prop-types": "^15.6.1"
}
},
- "react-popper": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.2.tgz",
- "integrity": "sha512-UbFWj55Yt9uqvy0oZ+vULDL2Bw1oxeZF9/JzGyxQ5ypgauRH/XlarA5+HLZWro/Zss6Ht2kqpegtb6sYL8GUGw==",
- "requires": {
- "@babel/runtime": "^7.1.2",
- "create-react-context": "<=0.2.2",
- "popper.js": "^1.14.4",
- "prop-types": "^15.6.1",
- "typed-styles": "^0.0.7",
- "warning": "^4.0.2"
- }
- },
"react-portal": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/react-portal/-/react-portal-4.2.0.tgz",
@@ -16357,20 +16540,20 @@
"integrity": "sha512-jZzE+vbYAblPXSPFlir+aL5ljxwB0dJ62O2pR74OS/TUVDTW95msrdszJKLNp4lxzNcoHnCRIzLT6crBgTolGg=="
},
"react-test-renderer": {
- "version": "16.7.0",
- "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.7.0.tgz",
- "integrity": "sha512-tFbhSjknSQ6+ttzmuGdv+SjQfmvGcq3PFKyPItohwhhOBmRoTf1We3Mlt3rJtIn85mjPXOkKV+TaKK4irvk9Yg==",
+ "version": "16.6.3",
+ "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.6.3.tgz",
+ "integrity": "sha512-B5bCer+qymrQz/wN03lT0LppbZUDRq6AMfzMKrovzkGzfO81a9T+PWQW6MzkWknbwODQH/qpJno/yFQLX5IWrQ==",
"requires": {
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
- "react-is": "^16.7.0",
- "scheduler": "^0.12.0"
+ "react-is": "^16.6.3",
+ "scheduler": "^0.11.2"
}
},
"react-transition-group": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.5.2.tgz",
- "integrity": "sha512-vwHP++S+f6KL7rg8V1mfs62+MBKtbMeZDR8KiNmD7v98Gs3UPGsDZDahPJH2PVprFW5YHJfh6cbNim3zPndaSQ==",
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.5.1.tgz",
+ "integrity": "sha512-8x/CxUL9SjYFmUdzsBPTgtKeCxt7QArjNSte0wwiLtF/Ix/o1nWNJooNy5o9XbHIKS31pz7J5VF2l41TwlvbHQ==",
"requires": {
"dom-helpers": "^3.3.1",
"loose-envify": "^1.4.0",
@@ -16436,14 +16619,6 @@
"world-countries": "^2.0.0"
}
},
- "reactcss": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
- "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==",
- "requires": {
- "lodash": "^4.0.1"
- }
- },
"read": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
@@ -16527,9 +16702,9 @@
}
},
"readable-stream": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz",
- "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.0.tgz",
+ "integrity": "sha512-vpydAvIJvPODZNagCPuHG87O9JNPtvFEtjHHRVwNVsVVRBqemvPJkc2SYbxJsiZXawJdtZNmkmnsPuE3IgsG0A==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@@ -16644,7 +16819,7 @@
},
"is-accessor-descriptor": {
"version": "0.1.6",
- "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
"integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
"dev": true,
"requires": {
@@ -16664,7 +16839,7 @@
},
"is-data-descriptor": {
"version": "0.1.4",
- "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
"integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
"dev": true,
"requires": {
@@ -16850,7 +17025,7 @@
},
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -16865,7 +17040,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
@@ -16988,7 +17163,7 @@
},
"regexpp": {
"version": "1.1.0",
- "resolved": "http://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz",
"integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw=="
},
"regexpu-core": {
@@ -17038,7 +17213,7 @@
"dependencies": {
"jsesc": {
"version": "0.5.0",
- "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0="
}
}
@@ -17199,13 +17374,13 @@
}
},
"execa": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
- "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz",
+ "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==",
"dev": true,
"requires": {
"cross-spawn": "^6.0.0",
- "get-stream": "^4.0.0",
+ "get-stream": "^3.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
@@ -17222,15 +17397,6 @@
"locate-path": "^3.0.0"
}
},
- "get-stream": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
- "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
- "dev": true,
- "requires": {
- "pump": "^3.0.0"
- }
- },
"invert-kv": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
@@ -17268,20 +17434,20 @@
}
},
"os-locale": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
- "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.0.1.tgz",
+ "integrity": "sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw==",
"dev": true,
"requires": {
- "execa": "^1.0.0",
+ "execa": "^0.10.0",
"lcid": "^2.0.0",
"mem": "^4.0.0"
}
},
"p-limit": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz",
- "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz",
+ "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
@@ -17424,7 +17590,7 @@
},
"require-uncached": {
"version": "1.0.3",
- "resolved": "http://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+ "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
"integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
"requires": {
"caller-path": "^0.1.0",
@@ -17627,7 +17793,7 @@
},
"safe-regex": {
"version": "1.1.0",
- "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
"requires": {
"ret": "~0.1.10"
@@ -17731,7 +17897,7 @@
},
"is-accessor-descriptor": {
"version": "0.1.6",
- "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
"integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
"requires": {
"kind-of": "^3.0.2"
@@ -17749,7 +17915,7 @@
},
"is-data-descriptor": {
"version": "0.1.4",
- "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
"integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
"requires": {
"kind-of": "^3.0.2"
@@ -17912,7 +18078,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
},
"ms": {
@@ -17962,7 +18128,7 @@
},
"os-locale": {
"version": "1.4.0",
- "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
"integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
"dev": true,
"requires": {
@@ -17971,7 +18137,7 @@
},
"string-width": {
"version": "1.0.2",
- "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"requires": {
@@ -18046,9 +18212,9 @@
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"scheduler": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.12.0.tgz",
- "integrity": "sha512-t7MBR28Akcp4Jm+QoR63XgAi9YgCUmgvDHqf5otgAj4QvdoBE4ImCX0ffehefePPG+aitiYHp0g/mW6s4Tp+dw==",
+ "version": "0.11.3",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.11.3.tgz",
+ "integrity": "sha512-i9X9VRRVZDd3xZw10NY5Z2cVMbdYg6gqFecfj79USv1CFN+YrJ3gIPRKf1qlY+Sxly4djoKdfx1T+m9dnRB8kQ==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
@@ -18085,7 +18251,7 @@
"dependencies": {
"source-map": {
"version": "0.4.4",
- "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
"integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
"dev": true,
"requires": {
@@ -18164,9 +18330,9 @@
}
},
"serialize-javascript": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz",
- "integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz",
+ "integrity": "sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ==",
"dev": true
},
"serve-static": {
@@ -18220,7 +18386,7 @@
},
"sha.js": {
"version": "2.4.11",
- "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"dev": true,
"requires": {
@@ -18516,9 +18682,9 @@
}
},
"spdx-license-ids": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz",
- "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g=="
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz",
+ "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg=="
},
"specificity": {
"version": "0.4.1",
@@ -18558,9 +18724,9 @@
"integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
},
"sshpk": {
- "version": "1.16.0",
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.0.tgz",
- "integrity": "sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ==",
+ "version": "1.15.2",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz",
+ "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==",
"requires": {
"asn1": "~0.2.3",
"assert-plus": "^1.0.0",
@@ -18629,7 +18795,7 @@
"dependencies": {
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -18644,7 +18810,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
@@ -18660,7 +18826,7 @@
},
"stream-browserify": {
"version": "2.0.1",
- "resolved": "http://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
"integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
"dev": true,
"requires": {
@@ -18670,7 +18836,7 @@
"dependencies": {
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -18685,7 +18851,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
@@ -18719,7 +18885,7 @@
"dependencies": {
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -18734,7 +18900,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
@@ -18825,7 +18991,7 @@
},
"strip-ansi": {
"version": "3.0.1",
- "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
"ansi-regex": "^2.0.0"
@@ -18848,7 +19014,7 @@
},
"strip-eof": {
"version": "1.0.0",
- "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
},
"strip-indent": {
@@ -18874,7 +19040,7 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
}
@@ -19037,7 +19203,7 @@
},
"is-accessor-descriptor": {
"version": "0.1.6",
- "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
"integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
"dev": true,
"requires": {
@@ -19057,7 +19223,7 @@
},
"is-data-descriptor": {
"version": "0.1.4",
- "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
"integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
"dev": true,
"requires": {
@@ -19161,7 +19327,7 @@
},
"globby": {
"version": "8.0.1",
- "resolved": "http://registry.npmjs.org/globby/-/globby-8.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz",
"integrity": "sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw==",
"dev": true,
"requires": {
@@ -19410,31 +19576,31 @@
}
},
"stylelint-scss": {
- "version": "3.4.4",
- "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-3.4.4.tgz",
- "integrity": "sha512-GquwsRegF2gsVRePaUN93cYf9aJDygr03X/QRiwk9O5lOe7QZHlM4Vzrb8JAu+pZ0xodPRpN6W259yA6ApM3WA==",
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-3.4.1.tgz",
+ "integrity": "sha512-ENYTE25wd9ndSkwxMksr8hrXVdWYu+RfDKM1ef2MHEqxk4cU362WQv7mgJK3HZqdCZFxL21sFegQO9Kz2vzwGw==",
"dev": true,
"requires": {
"lodash": "^4.17.11",
"postcss-media-query-parser": "^0.2.3",
"postcss-resolve-nested-selector": "^0.1.1",
- "postcss-selector-parser": "^5.0.0",
+ "postcss-selector-parser": "^4.0.0",
"postcss-value-parser": "^3.3.1"
},
"dependencies": {
"cssesc": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
- "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-1.0.1.tgz",
+ "integrity": "sha512-S2hzrpWvE6G/rW7i7IxJfWBYn27QWfOIncUW++8Rbo1VB5zsJDSVPcnI+Q8z7rhxT6/yZeLOCja4cZnghJrNGA==",
"dev": true
},
"postcss-selector-parser": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
- "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-4.0.0.tgz",
+ "integrity": "sha512-5h+MvEjnzu1qy6MabjuoPatsGAjjDV9B24e7Cktjl+ClNtjVjmvAXjOFQr1u7RlWULKNGYaYVE4s+DIIQ4bOGA==",
"dev": true,
"requires": {
- "cssesc": "^2.0.0",
+ "cssesc": "^1.0.1",
"indexes-of": "^1.0.1",
"uniq": "^1.0.1"
}
@@ -19524,7 +19690,7 @@
},
"fast-deep-equal": {
"version": "1.1.0",
- "resolved": "http://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
"integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
},
"json-schema-traverse": {
@@ -19550,7 +19716,7 @@
},
"tar": {
"version": "2.2.1",
- "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
"integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
"dev": true,
"requires": {
@@ -19597,9 +19763,9 @@
}
},
"terser": {
- "version": "3.13.1",
- "resolved": "https://registry.npmjs.org/terser/-/terser-3.13.1.tgz",
- "integrity": "sha512-ogyZye4DFqOtMzT92Y3Nxxw8OvXmL39HOALro4fc+EUYFFF9G/kk0znkvwMz6PPYgBtdKAodh3FPR70eugdaQA==",
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-3.14.0.tgz",
+ "integrity": "sha512-KQC1QNKbC/K1ZUjLIWsezW7wkTJuB4v9ptQQUNOzAPVHuVf2LrwEcB0I9t2HTEYUwAFVGiiS6wc+P4ClLDc5FQ==",
"dev": true,
"requires": {
"commander": "~2.17.1",
@@ -19607,12 +19773,6 @@
"source-map-support": "~0.5.6"
},
"dependencies": {
- "commander": {
- "version": "2.17.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
- "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
- "dev": true
- },
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -19759,6 +19919,16 @@
"find-up": "^3.0.0"
}
},
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -19818,7 +19988,7 @@
},
"through": {
"version": "2.3.8",
- "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
},
"through2": {
@@ -19833,7 +20003,7 @@
"dependencies": {
"readable-stream": {
"version": "2.3.6",
- "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@@ -19848,7 +20018,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
@@ -20024,7 +20194,7 @@
},
"tty-browserify": {
"version": "0.0.0",
- "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
"integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
"dev": true
},
@@ -20060,11 +20230,6 @@
"prelude-ls": "~1.1.2"
}
},
- "typed-styles": {
- "version": "0.0.7",
- "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz",
- "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q=="
- },
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
@@ -20109,12 +20274,6 @@
"source-map": "~0.6.1"
},
"dependencies": {
- "commander": {
- "version": "2.17.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
- "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
- "optional": true
- },
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -20141,6 +20300,11 @@
"integrity": "sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0=",
"dev": true
},
+ "underscore": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz",
+ "integrity": "sha1-YaajIBBiKvoHljvzJSA88SI51gQ="
+ },
"underscore.string": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz",
@@ -20511,9 +20675,9 @@
}
},
"validator": {
- "version": "10.10.0",
- "resolved": "https://registry.npmjs.org/validator/-/validator-10.10.0.tgz",
- "integrity": "sha512-DyZyLJlMXM3CGdVaVHE/EDzCagMRoPI3mmGdxxNQbqkGqh56+M3d1i0ZAWd69En8U21DHbPTn12aOdhO+hfm5w=="
+ "version": "10.9.0",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-10.9.0.tgz",
+ "integrity": "sha512-hZJcZSWz9poXBlAkjjcsNAdrZ6JbjD3kWlNjq/+vE7RLLS/+8PAj3qVVwrwsOz/WL8jPmZ1hYkRvtlUeZAm4ug=="
},
"value-equal": {
"version": "0.4.0",
@@ -20564,7 +20728,7 @@
},
"vm-browserify": {
"version": "0.0.4",
- "resolved": "http://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
+ "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
"integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
"dev": true,
"requires": {
@@ -20606,7 +20770,7 @@
"dependencies": {
"minimist": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
}
}
@@ -20637,9 +20801,9 @@
"integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
},
"webpack": {
- "version": "4.28.2",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.2.tgz",
- "integrity": "sha512-PK3uVg3/NuNVOjPfYleFI6JF7khO7c2kIlksH7mivQm+QDcwiqV1x6+q89dDeOioh5FNxJHr3LKbDu3oSAhl9g==",
+ "version": "4.28.3",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.3.tgz",
+ "integrity": "sha512-vLZN9k5I7Nr/XB1IDG9GbZB4yQd1sPuvufMFgJkx0b31fi2LD97KQIjwjxE7xytdruAYfu5S0FLBLjdxmwGJCg==",
"dev": true,
"requires": {
"@webassemblyjs/ast": "1.7.11",
@@ -20769,7 +20933,7 @@
},
"is-accessor-descriptor": {
"version": "0.1.6",
- "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
"integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
"dev": true,
"requires": {
@@ -20789,7 +20953,7 @@
},
"is-data-descriptor": {
"version": "0.1.4",
- "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
"integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
"dev": true,
"requires": {
@@ -21023,13 +21187,13 @@
}
},
"execa": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
- "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz",
+ "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==",
"dev": true,
"requires": {
"cross-spawn": "^6.0.0",
- "get-stream": "^4.0.0",
+ "get-stream": "^3.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
@@ -21046,15 +21210,6 @@
"locate-path": "^3.0.0"
}
},
- "get-stream": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
- "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
- "dev": true,
- "requires": {
- "pump": "^3.0.0"
- }
- },
"import-local": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
@@ -21102,20 +21257,20 @@
}
},
"os-locale": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
- "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.0.1.tgz",
+ "integrity": "sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw==",
"dev": true,
"requires": {
- "execa": "^1.0.0",
+ "execa": "^0.10.0",
"lcid": "^2.0.0",
"mem": "^4.0.0"
}
},
"p-limit": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz",
- "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz",
+ "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
@@ -21269,13 +21424,13 @@
}
},
"world-countries": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/world-countries/-/world-countries-2.1.0.tgz",
- "integrity": "sha512-g8DRgoH7UJiF5L0xjj+RP/GFH4fOVlD3J5CxkJ+PZYH1PNl0i5JrstBOX53Ub8ObTZ6lCx0V7nIA8BuCvxMoSg=="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/world-countries/-/world-countries-2.0.0.tgz",
+ "integrity": "sha512-f/Atl3VHj/FxFEw5jVkTkKofbbD8z/WF/PCpmv3JPrUR2X/XtuApulLy8QwKcyrurlDDRO0lGPvX+m0GzjxaNQ=="
},
"wrap-ansi": {
"version": "2.1.0",
- "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
"requires": {
"string-width": "^1.0.1",
@@ -21292,7 +21447,7 @@
},
"string-width": {
"version": "1.0.2",
- "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"requires": {
"code-point-at": "^1.0.0",
@@ -21429,7 +21584,7 @@
},
"chalk": {
"version": "1.1.3",
- "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
@@ -21442,7 +21597,7 @@
},
"supports-color": {
"version": "2.0.0",
- "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
}
@@ -21450,7 +21605,7 @@
},
"yargs": {
"version": "11.1.0",
- "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz",
"integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==",
"requires": {
"cliui": "^4.0.0",
diff --git a/plugins/woocommerce-admin/package.json b/plugins/woocommerce-admin/package.json
index 4d708d6ec98..c7d60efbe68 100644
--- a/plugins/woocommerce-admin/package.json
+++ b/plugins/woocommerce-admin/package.json
@@ -1,6 +1,6 @@
{
"name": "wc-admin",
- "version": "0.3.0",
+ "version": "0.4.0",
"main": "js/index.js",
"author": "Automattic",
"license": "GPL-2.0-or-later",
@@ -39,6 +39,7 @@
"test": "wp-scripts test-unit-js --config tests/js/jest.config.json",
"test:watch": "npm run test -- --watch",
"test:update-snapshots": "jest --updateSnapshot --config tests/js/jest.config.json",
+ "jest:update": "jest -u --config=tests/js/jest.config.json",
"docs": "node ./bin/generate-docs",
"publish:check": "npm run build:packages && lerna updated",
"publish:dev": "npm run build:packages && lerna publish from-package --npm-tag next",
@@ -52,10 +53,10 @@
"@babel/runtime-corejs2": "7.2.0",
"@wordpress/babel-plugin-import-jsx-pragma": "1.1.2",
"@wordpress/babel-plugin-makepot": "2.1.2",
- "@wordpress/babel-preset-default": "2.1.0",
+ "@wordpress/babel-preset-default": "3.0.1",
"@wordpress/browserslist-config": "2.2.2",
"@wordpress/custom-templated-path-webpack-plugin": "1.1.5",
- "@wordpress/jest-preset-default": "2.0.6",
+ "@wordpress/jest-preset-default": "3.0.3",
"@wordpress/postcss-themes": "1.0.4",
"ast-types": "0.11.7",
"autoprefixer": "9.4.3",
@@ -83,8 +84,8 @@
"grunt": "1.0.3",
"grunt-checktextdomain": "1.0.1",
"grunt-wp-i18n": "1.0.3",
- "husky": "1.2.1",
- "lerna": "3.8.0",
+ "husky": "1.3.1",
+ "lerna": "3.8.4",
"node-sass": "4.11.0",
"postcss-color-function": "4.0.1",
"postcss-loader": "3.0.0",
@@ -101,21 +102,21 @@
"style-loader": "0.23.1",
"stylelint": "9.9.0",
"stylelint-config-wordpress": "13.1.0",
- "webpack": "4.28.2",
+ "webpack": "4.28.3",
"webpack-cli": "3.1.2"
},
"dependencies": {
"@fresh-data/framework": "^0.5.1",
- "@wordpress/api-fetch": "2.2.2",
- "@wordpress/components": "3.0.0",
- "@wordpress/data": "3.1.0",
- "@wordpress/date": "2.1.0",
- "@wordpress/element": "2.1.5",
+ "@wordpress/api-fetch": "2.2.6",
+ "@wordpress/components": "7.0.5",
+ "@wordpress/data": "4.2.0",
+ "@wordpress/date": "3.0.1",
+ "@wordpress/element": "2.1.8",
"@wordpress/hooks": "2.0.3",
- "@wordpress/html-entities": "2.0.2",
- "@wordpress/i18n": "2.0.0",
- "@wordpress/keycodes": "2.0.3",
- "@wordpress/scripts": "2.4.1",
+ "@wordpress/html-entities": "2.0.4",
+ "@wordpress/i18n": "3.1.0",
+ "@wordpress/keycodes": "2.0.5",
+ "@wordpress/scripts": "2.4.4",
"@wordpress/viewport": "^2.0.7",
"browser-filesaver": "^1.1.1",
"classnames": "^2.2.5",
@@ -135,7 +136,7 @@
"html-to-react": "1.3.4",
"interpolate-components": "1.1.1",
"lodash": "^4.17.11",
- "marked": "0.5.2",
+ "marked": "0.6.0",
"prismjs": "^1.15.0",
"qs": "^6.5.2",
"react-click-outside": "3.0.1",
diff --git a/plugins/woocommerce-admin/packages/components/CHANGELOG.md b/plugins/woocommerce-admin/packages/components/CHANGELOG.md
index 5774db71a64..5e51ab89fff 100644
--- a/plugins/woocommerce-admin/packages/components/CHANGELOG.md
+++ b/plugins/woocommerce-admin/packages/components/CHANGELOG.md
@@ -3,7 +3,11 @@
- Add order number autocompleter to search component
- Add order number, username, and IP address filters to the downloads report.
- Added `interactive` prop for `d3chart/legend` to signal if legend items are clickable or not.
-- Fix for undefined ref in `d3chart/legend`
+- Fix for undefined ref in `d3chart/legend`.
+- Added three news props to ``:
+ - `interactiveLegend`: whether legend items are clickable or not. Defaults to true.
+ - `legendPosition`: can be `top`, `side` or `bottom`. If not specified, it's calculated based on `mode` and viewport width.
+ - `showHeaderControls`: whether the header controls must be visible. Defaults to true.
# 1.3.0
diff --git a/plugins/woocommerce-admin/packages/components/package.json b/plugins/woocommerce-admin/packages/components/package.json
index 4f1a39ac57c..61256041b45 100644
--- a/plugins/woocommerce-admin/packages/components/package.json
+++ b/plugins/woocommerce-admin/packages/components/package.json
@@ -26,13 +26,13 @@
"@woocommerce/currency": "^1.0.0",
"@woocommerce/date": "^1.0.3",
"@woocommerce/navigation": "^1.1.0",
- "@wordpress/components": "3.0.0",
+ "@wordpress/components": "7.0.5",
"@wordpress/compose": "3.0.0",
- "@wordpress/date": "2.1.0",
- "@wordpress/element": "2.1.5",
- "@wordpress/html-entities": "2.0.2",
- "@wordpress/i18n": "2.0.0",
- "@wordpress/keycodes": "2.0.2",
+ "@wordpress/date": "3.0.1",
+ "@wordpress/element": "2.1.8",
+ "@wordpress/html-entities": "2.0.4",
+ "@wordpress/i18n": "3.1.0",
+ "@wordpress/keycodes": "2.0.5",
"@wordpress/viewport": "^2.0.7",
"classnames": "^2.2.5",
"core-js": "2.6.1",
diff --git a/plugins/woocommerce-admin/packages/components/src/calendar/date-range.js b/plugins/woocommerce-admin/packages/components/src/calendar/date-range.js
index 9d8deb3b7e4..271a1c9039f 100644
--- a/plugins/woocommerce-admin/packages/components/src/calendar/date-range.js
+++ b/plugins/woocommerce-admin/packages/components/src/calendar/date-range.js
@@ -118,6 +118,7 @@ class DateRange extends Component {
),
shortDateFormat
) }
+ onFocus={ () => this.onFocusChange( 'startDate' ) }
/>
{ __( 'to', 'wc-admin' ) }
this.onFocusChange( 'endDate' ) }
/>
@@ -150,7 +152,6 @@ class DateRange extends Component {
noBorder
initialVisibleMonth={ this.setTnitialVisibleMonth( isDoubleCalendar, before ) }
phrases={ phrases }
- firstDayOfWeek={ Number( wcSettings.date.dow ) }
/>
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/chart.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/chart.js
index b7144a65a43..0903fad61a8 100644
--- a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/chart.js
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/chart.js
@@ -8,31 +8,31 @@ import { Component, createRef } from '@wordpress/element';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { timeFormat as d3TimeFormat, utcParse as d3UTCParse } from 'd3-time-format';
-import { select as d3Select } from 'd3-selection';
/**
* Internal dependencies
*/
import D3Base from './d3base';
import {
- drawAxis,
- drawBars,
- drawLines,
getDateSpaces,
getOrderedKeys,
getLine,
getLineData,
- getXTicks,
getUniqueKeys,
getUniqueDates,
+ getFormatter,
+} from './utils';
+import {
getXScale,
getXGroupScale,
getXLineScale,
getYMax,
getYScale,
getYTickOffset,
- getFormatter,
-} from './utils';
+} from './utils/scales';
+import { drawAxis, getXTicks } from './utils/axis';
+import { drawBars } from './utils/bar-chart';
+import { drawLines } from './utils/line-chart';
/**
* A simple D3 line and bar chart component for timeseries data in React.
@@ -70,23 +70,48 @@ class D3Chart extends Component {
}
drawChart( node ) {
- const { data, margin, type } = this.props;
- const params = this.getParams();
- const adjParams = Object.assign( {}, params, {
- height: params.adjHeight,
- width: params.adjWidth,
- tooltip: d3Select( this.tooltipRef.current ),
- valueType: params.valueType,
+ setTimeout( () => {
+ const { data, margin, type } = this.props;
+ const params = this.getParams();
+ const adjParams = Object.assign( {}, params, {
+ height: params.adjHeight,
+ width: params.adjWidth,
+ tooltip: this.tooltipRef.current,
+ valueType: params.valueType,
+ } );
+
+ const g = node
+ .attr( 'id', 'chart' )
+ .append( 'g' )
+ .attr( 'transform', `translate(${ margin.left },${ margin.top })` );
+
+ drawAxis( g, adjParams );
+ type === 'line' && drawLines( g, data, adjParams );
+ type === 'bar' && drawBars( g, data, adjParams );
} );
+ }
- const g = node
- .attr( 'id', 'chart' )
- .append( 'g' )
- .attr( 'transform', `translate(${ margin.left },${ margin.top })` );
+ shouldBeCompact() {
+ const { data, margin, type, width } = this.props;
+ if ( type !== 'bar' ) {
+ return false;
+ }
+ const widthWithoutMargins = width - margin.left - margin.right;
+ const columnsPerDate = data && data.length ? Object.keys( data[ 0 ] ).length - 1 : 0;
+ const minimumWideWidth = data.length * ( columnsPerDate + 1 );
- drawAxis( g, adjParams );
- type === 'line' && drawLines( g, data, adjParams );
- type === 'bar' && drawBars( g, data, adjParams );
+ return widthWithoutMargins < minimumWideWidth;
+ }
+
+ getWidth() {
+ const { data, margin, type, width } = this.props;
+ if ( type !== 'bar' ) {
+ return width;
+ }
+ const columnsPerDate = data && data.length ? Object.keys( data[ 0 ] ).length - 1 : 0;
+ const minimumWidth = this.shouldBeCompact() ? data.length * columnsPerDate : data.length * ( columnsPerDate + 1 );
+
+ return Math.max( width, minimumWidth + margin.left + margin.right );
}
getParams() {
@@ -104,14 +129,14 @@ class D3Chart extends Component {
tooltipValueFormat,
tooltipTitle,
type,
- width,
xFormat,
x2Format,
yFormat,
valueType,
} = this.props;
const adjHeight = height - margin.top - margin.bottom;
- const adjWidth = width - margin.left - margin.right;
+ const adjWidth = this.getWidth() - margin.left - margin.right;
+ const compact = this.shouldBeCompact();
const uniqueKeys = getUniqueKeys( data );
const newOrderedKeys = orderedKeys || getOrderedKeys( data, uniqueKeys );
const lineData = getLineData( data, newOrderedKeys );
@@ -120,7 +145,7 @@ class D3Chart extends Component {
const parseDate = d3UTCParse( dateParser );
const uniqueDates = getUniqueDates( lineData, parseDate );
const xLineScale = getXLineScale( uniqueDates, adjWidth );
- const xScale = getXScale( uniqueDates, adjWidth );
+ const xScale = getXScale( uniqueDates, adjWidth, compact );
const xTicks = getXTicks( uniqueDates, adjWidth, mode, interval );
return {
adjHeight,
@@ -143,7 +168,7 @@ class D3Chart extends Component {
uniqueKeys,
xFormat: getFormatter( xFormat, d3TimeFormat ),
x2Format: getFormatter( x2Format, d3TimeFormat ),
- xGroupScale: getXGroupScale( orderedKeys, xScale ),
+ xGroupScale: getXGroupScale( orderedKeys, xScale, compact ),
xLineScale,
xTicks,
xScale,
@@ -156,21 +181,24 @@ class D3Chart extends Component {
}
render() {
- if ( isEmpty( this.props.data ) ) {
+ const { className, data, height } = this.props;
+ if ( isEmpty( data ) ) {
return null; // TODO: improve messaging
}
+ const computedWidth = this.getWidth();
return (
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/d3base/index.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/d3base/index.js
index 9f259fdfe22..6b35c157fb0 100644
--- a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/d3base/index.js
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/d3base/index.js
@@ -6,9 +6,14 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import { Component, createRef } from '@wordpress/element';
-import { isEqual } from 'lodash';
+import { isEqual, throttle } from 'lodash';
import { select as d3Select } from 'd3-selection';
+/**
+ * Internal dependencies
+ */
+import { hideTooltip } from '../utils/tooltip';
+
/**
* Provides foundation to use D3 within React.
*
@@ -25,6 +30,10 @@ export default class D3Base extends Component {
super( props );
this.chartRef = createRef();
+
+ this.delayedScroll = throttle( () => {
+ hideTooltip( this.chartRef.current, props.tooltipRef.current );
+ }, 300 );
}
componentDidMount() {
@@ -86,7 +95,7 @@ export default class D3Base extends Component {
render() {
return (
-
+
);
}
}
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/d3base/style.scss b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/d3base/style.scss
index f3aa0895bd8..3feb26e2b7e 100644
--- a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/d3base/style.scss
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/d3base/style.scss
@@ -2,6 +2,8 @@
.d3-base {
background: transparent;
+ overflow-x: auto;
+ overflow-y: hidden;
position: relative;
width: 100%;
height: 100%;
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/legend.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/legend.js
index 9ba9c053354..48684fa0604 100644
--- a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/legend.js
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/legend.js
@@ -9,7 +9,8 @@ import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
-import { getColor, getFormatter } from './utils';
+import { getFormatter } from './utils';
+import { getColor } from './utils/color';
/**
* A legend specifically designed for the WooCommerce admin charts.
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/test/fixtures/dummy-hour.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/test/fixtures/dummy-hour.js
deleted file mode 100644
index b310f491f07..00000000000
--- a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/test/fixtures/dummy-hour.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/** @format */
-
-// /**
-// * /* eslint-disable quote-props
-// *
-// * @format
-// */
-
-export default [
- {
- date: '2018-08-01T00:00:00',
- 'Custom (Aug 1, 2018)': { label: '2018-08-01 00:00', value: 58929.99 },
- 'Previous Period (Jul 31, 2018)': { label: '2018-07-31 00:00', value: 160130.74000000002 },
- },
- {
- date: '2018-08-01T01:00:00',
- 'Custom (Aug 1, 2018)': { label: '2018-08-01 01:00', value: 3805.56 },
- 'Previous Period (Jul 31, 2018)': { label: '2018-07-31 01:00', value: 0 },
- },
- {
- date: '2018-08-01T02:00:00',
- 'Custom (Aug 1, 2018)': { label: '2018-08-01 02:00', value: 3805.56 },
- 'Previous Period (Jul 31, 2018)': { label: '2018-07-31 02:00', value: 0 },
- },
-];
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils.js
index b8792ec9b65..c356968de3c 100644
--- a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils.js
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils.js
@@ -144,25 +144,29 @@ export const getColor = ( key, params ) => {
* Describes getXScale
* @param {array} uniqueDates - from `getUniqueDates`
* @param {number} width - calculated width of the charting space
+ * @param {boolean} compact - whether the chart must be compact (without padding
+ between days)
* @returns {function} a D3 scale of the dates
*/
-export const getXScale = ( uniqueDates, width ) =>
+export const getXScale = ( uniqueDates, width, compact = false ) =>
d3ScaleBand()
.domain( uniqueDates )
.rangeRound( [ 0, width ] )
- .paddingInner( 0.1 );
+ .paddingInner( compact ? 0 : 0.1 );
/**
* Describes getXGroupScale
* @param {array} orderedKeys - from `getOrderedKeys`
* @param {function} xScale - from `getXScale`
+ * @param {boolean} compact - whether the chart must be compact (without padding
+ between days)
* @returns {function} a D3 scale for each category within the xScale range
*/
-export const getXGroupScale = ( orderedKeys, xScale ) =>
+export const getXGroupScale = ( orderedKeys, xScale, compact = false ) =>
d3ScaleBand()
.domain( orderedKeys.filter( d => d.visible ).map( d => d.key ) )
.rangeRound( [ 0, xScale.bandwidth() ] )
- .padding( 0.07 );
+ .padding( compact ? 0 : 0.07 );
/**
* Describes getXLineScale
@@ -568,27 +572,30 @@ const calculateTooltipXPosition = (
elementWidthRatio,
tooltipPosition
) => {
- const xPosition =
- elementCoords.left + elementCoords.width * elementWidthRatio + tooltipMargin - chartCoords.left;
+ const d3BaseCoords = d3Select( '.d3-base' ).node().getBoundingClientRect();
+ const leftMargin = Math.max( d3BaseCoords.left, chartCoords.left );
if ( tooltipPosition === 'below' ) {
return Math.max(
tooltipMargin,
Math.min(
- xPosition - tooltipSize.width / 2,
- chartCoords.width - tooltipSize.width - tooltipMargin
+ elementCoords.left + elementCoords.width * 0.5 - tooltipSize.width / 2 - leftMargin,
+ d3BaseCoords.width - tooltipSize.width - tooltipMargin
)
);
}
- if ( xPosition + tooltipSize.width + tooltipMargin > chartCoords.width ) {
+ const xPosition =
+ elementCoords.left + elementCoords.width * elementWidthRatio + tooltipMargin - leftMargin;
+
+ if ( xPosition + tooltipSize.width + tooltipMargin > d3BaseCoords.width ) {
return Math.max(
tooltipMargin,
elementCoords.left +
elementCoords.width * ( 1 - elementWidthRatio ) -
tooltipSize.width -
tooltipMargin -
- chartCoords.left
+ leftMargin
);
}
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/axis.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/axis.js
new file mode 100644
index 00000000000..3062b90ac12
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/axis.js
@@ -0,0 +1,266 @@
+/** @format */
+
+/**
+ * External dependencies
+ */
+import { axisBottom as d3AxisBottom, axisLeft as d3AxisLeft } from 'd3-axis';
+import { smallBreak, wideBreak } from './breakpoints';
+
+const dayTicksThreshold = 63;
+const weekTicksThreshold = 9;
+const mediumBreak = 1130;
+const smallPoints = 7;
+const mediumPoints = 12;
+const largePoints = 16;
+const mostPoints = 31;
+
+/**
+* Describes `smallestFactor`
+* @param {number} inputNum - any double or integer
+* @returns {integer} smallest factor of num
+*/
+const getFactors = inputNum => {
+ const numFactors = [];
+ for ( let i = 1; i <= Math.floor( Math.sqrt( inputNum ) ); i += 1 ) {
+ if ( inputNum % i === 0 ) {
+ numFactors.push( i );
+ inputNum / i !== i && numFactors.push( inputNum / i );
+ }
+ }
+ numFactors.sort( ( x, y ) => x - y ); // numeric sort
+
+ return numFactors;
+};
+
+/**
+ * Calculate the maximum number of ticks allowed in the x-axis based on the width and mode of the chart
+ * @param {integer} width - calculated page width
+ * @param {string} mode - item-comparison or time-comparison
+ * @returns {integer} number of x-axis ticks based on width and chart mode
+ */
+const calculateMaxXTicks = ( width, mode ) => {
+ if ( width < smallBreak ) {
+ return smallPoints;
+ } else if ( width >= smallBreak && width <= mediumBreak ) {
+ return mediumPoints;
+ } else if ( width > mediumBreak && width <= wideBreak ) {
+ if ( mode === 'time-comparison' ) {
+ return largePoints;
+ } else if ( mode === 'item-comparison' ) {
+ return mediumPoints;
+ }
+ } else if ( width > wideBreak ) {
+ if ( mode === 'time-comparison' ) {
+ return mostPoints;
+ } else if ( mode === 'item-comparison' ) {
+ return largePoints;
+ }
+ }
+
+ return largePoints;
+};
+
+/**
+ * Get x-axis ticks given the unique dates and the increment factor.
+ * @param {array} uniqueDates - all the unique dates from the input data for the chart
+ * @param {integer} incrementFactor - increment factor for the visible ticks.
+ * @returns {array} Ticks for the x-axis.
+ */
+const getXTicksFromIncrementFactor = ( uniqueDates, incrementFactor ) => {
+ const ticks = [];
+
+ for ( let idx = 0; idx < uniqueDates.length; idx = idx + incrementFactor ) {
+ ticks.push( uniqueDates[ idx ] );
+ }
+
+ // If the first date is missing from the ticks array, add it back in.
+ if ( ticks[ 0 ] !== uniqueDates[ 0 ] ) {
+ ticks.unshift( uniqueDates[ 0 ] );
+ }
+
+ return ticks;
+};
+
+/**
+ * Calculates the increment factor between ticks so there aren't more than maxTicks.
+ * @param {array} uniqueDates - all the unique dates from the input data for the chart
+ * @param {integer} maxTicks - maximum number of ticks that can be displayed in the x-axis
+ * @returns {integer} x-axis ticks increment factor
+ */
+const calculateXTicksIncrementFactor = ( uniqueDates, maxTicks ) => {
+ let factors = [];
+ let i = 1;
+ // First we get all the factors of the length of the uniqueDates array
+ // if the number is a prime number or near prime (with 3 factors) then we
+ // step down by 1 integer and try again.
+ while ( factors.length <= 3 ) {
+ factors = getFactors( uniqueDates.length - i );
+ i += 1;
+ }
+
+ return factors.find( f => uniqueDates.length / f < maxTicks );
+};
+
+/**
+ * Given an array of dates, returns true if the first and last one belong to the same day.
+ * @param {array} dates - an array of dates
+ * @returns {boolean} whether the first and last date are different hours from the same date.
+ */
+const areDatesInTheSameDay = dates => {
+ const firstDate = new Date( dates [ 0 ] );
+ const lastDate = new Date( dates [ dates.length - 1 ] );
+ return (
+ firstDate.getDate() === lastDate.getDate() &&
+ firstDate.getMonth() === lastDate.getMonth() &&
+ firstDate.getFullYear() === lastDate.getFullYear()
+ );
+};
+
+/**
+* Filter out irrelevant dates so only the first date of each month is kept.
+* @param {array} dates - string dates.
+* @returns {array} Filtered dates.
+*/
+const getFirstDatePerMonth = dates => {
+ return dates.filter(
+ ( date, i ) => i === 0 || new Date( date ).getMonth() !== new Date( dates[ i - 1 ] ).getMonth()
+ );
+};
+
+/**
+ * Returns ticks for the x-axis.
+ * @param {array} uniqueDates - all the unique dates from the input data for the chart
+ * @param {integer} width - calculated page width
+ * @param {string} mode - item-comparison or time-comparison
+ * @param {string} interval - string of the interval used in the graph (hour, day, week...)
+ * @returns {integer} number of x-axis ticks based on width and chart mode
+ */
+export const getXTicks = ( uniqueDates, width, mode, interval ) => {
+ const maxTicks = calculateMaxXTicks( width, mode );
+
+ if (
+ ( uniqueDates.length >= dayTicksThreshold && interval === 'day' ) ||
+ ( uniqueDates.length >= weekTicksThreshold && interval === 'week' )
+ ) {
+ uniqueDates = getFirstDatePerMonth( uniqueDates );
+ }
+ if ( uniqueDates.length <= maxTicks ||
+ ( interval === 'hour' && areDatesInTheSameDay( uniqueDates ) && width > smallBreak ) ) {
+ return uniqueDates;
+ }
+
+ const incrementFactor = calculateXTicksIncrementFactor( uniqueDates, maxTicks );
+
+ return getXTicksFromIncrementFactor( uniqueDates, incrementFactor );
+};
+
+/**
+* Compares 2 strings and returns a list of words that are unique from s2
+* @param {string} s1 - base string to compare against
+* @param {string} s2 - string to compare against the base string
+* @param {string|Object} splitChar - character or RegExp to use to deliminate words
+* @returns {array} of unique words that appear in s2 but not in s1, the base string
+*/
+export const compareStrings = ( s1, s2, splitChar = new RegExp( [ ' |,' ], 'g' ) ) => {
+ const string1 = s1.split( splitChar );
+ const string2 = s2.split( splitChar );
+ const diff = new Array();
+ const long = s1.length > s2.length ? string1 : string2;
+ for ( let x = 0; x < long.length; x++ ) {
+ string1[ x ] !== string2[ x ] && diff.push( string2[ x ] );
+ }
+ return diff;
+};
+
+export const drawAxis = ( node, params ) => {
+ const xScale = params.type === 'line' ? params.xLineScale : params.xScale;
+ const removeDuplicateDates = ( d, i, ticks, formatter ) => {
+ const monthDate = d instanceof Date ? d : new Date( d );
+ let prevMonth = i !== 0 ? ticks[ i - 1 ] : ticks[ i ];
+ prevMonth = prevMonth instanceof Date ? prevMonth : new Date( prevMonth );
+ return i === 0
+ ? formatter( monthDate )
+ : compareStrings( formatter( prevMonth ), formatter( monthDate ) ).join( ' ' );
+ };
+
+ const yGrids = [];
+ for ( let i = 0; i < 4; i++ ) {
+ if ( params.yMax > 1 ) {
+ const roundedValue = Math.round( i / 3 * params.yMax );
+ if ( yGrids[ yGrids.length - 1 ] !== roundedValue ) {
+ yGrids.push( roundedValue );
+ }
+ } else {
+ yGrids.push( i / 3 * params.yMax );
+ }
+ }
+
+ const ticks = params.xTicks.map( d => ( params.type === 'line' ? new Date( d ) : d ) );
+
+ node
+ .append( 'g' )
+ .attr( 'class', 'axis' )
+ .attr( 'aria-hidden', 'true' )
+ .attr( 'transform', `translate(0, ${ params.height })` )
+ .call(
+ d3AxisBottom( xScale )
+ .tickValues( ticks )
+ .tickFormat( ( d, i ) => params.interval === 'hour'
+ ? params.xFormat( d )
+ : removeDuplicateDates( d, i, ticks, params.xFormat ) )
+ );
+
+ node
+ .append( 'g' )
+ .attr( 'class', 'axis axis-month' )
+ .attr( 'aria-hidden', 'true' )
+ .attr( 'transform', `translate(0, ${ params.height + 20 })` )
+ .call(
+ d3AxisBottom( xScale )
+ .tickValues( ticks )
+ .tickFormat( ( d, i ) => removeDuplicateDates( d, i, ticks, params.x2Format ) )
+ )
+ .call( g => g.select( '.domain' ).remove() );
+
+ node
+ .append( 'g' )
+ .attr( 'class', 'pipes' )
+ .attr( 'transform', `translate(0, ${ params.height })` )
+ .call(
+ d3AxisBottom( xScale )
+ .tickValues( ticks )
+ .tickSize( 5 )
+ .tickFormat( '' )
+ );
+
+ node
+ .append( 'g' )
+ .attr( 'class', 'grid' )
+ .attr( 'transform', `translate(-${ params.margin.left },0)` )
+ .call(
+ d3AxisLeft( params.yScale )
+ .tickValues( yGrids )
+ .tickSize( -params.width - params.margin.left - params.margin.right )
+ .tickFormat( '' )
+ )
+ .call( g => g.select( '.domain' ).remove() );
+
+ node
+ .append( 'g' )
+ .attr( 'class', 'axis y-axis' )
+ .attr( 'aria-hidden', 'true' )
+ .attr( 'transform', 'translate(-50, 0)' )
+ .attr( 'text-anchor', 'start' )
+ .call(
+ d3AxisLeft( params.yTickOffset )
+ .tickValues( yGrids )
+ .tickFormat( d => params.yFormat( d !== 0 ? d : 0 ) )
+ );
+
+ node.selectAll( '.domain' ).remove();
+ node
+ .selectAll( '.axis' )
+ .selectAll( '.tick' )
+ .select( 'line' )
+ .remove();
+};
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/bar-chart.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/bar-chart.js
new file mode 100644
index 00000000000..3854e446702
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/bar-chart.js
@@ -0,0 +1,103 @@
+/** @format */
+
+/**
+ * External dependencies
+ */
+import { get } from 'lodash';
+import { event as d3Event, select as d3Select } from 'd3-selection';
+
+/**
+ * Internal dependencies
+ */
+import { getColor } from './color';
+import { calculateTooltipPosition, hideTooltip, showTooltip } from './tooltip';
+
+const handleMouseOverBarChart = ( date, parentNode, node, data, params, position ) => {
+ d3Select( parentNode )
+ .select( '.barfocus' )
+ .attr( 'opacity', '0.1' );
+ showTooltip( params, data.find( e => e.date === date ), position );
+};
+
+export const drawBars = ( node, data, params ) => {
+ const barGroup = node
+ .append( 'g' )
+ .attr( 'class', 'bars' )
+ .selectAll( 'g' )
+ .data( data )
+ .enter()
+ .append( 'g' )
+ .attr( 'transform', d => `translate(${ params.xScale( d.date ) },0)` )
+ .attr( 'class', 'bargroup' )
+ .attr( 'role', 'region' )
+ .attr(
+ 'aria-label',
+ d =>
+ params.mode === 'item-comparison'
+ ? params.tooltipLabelFormat( d.date instanceof Date ? d.date : new Date( d.date ) )
+ : null
+ );
+
+ barGroup
+ .append( 'rect' )
+ .attr( 'class', 'barfocus' )
+ .attr( 'x', 0 )
+ .attr( 'y', 0 )
+ .attr( 'width', params.xGroupScale.range()[ 1 ] )
+ .attr( 'height', params.height )
+ .attr( 'opacity', '0' );
+
+ barGroup
+ .selectAll( '.bar' )
+ .data( d =>
+ params.orderedKeys.filter( row => row.visible ).map( row => ( {
+ key: row.key,
+ focus: row.focus,
+ value: get( d, [ row.key, 'value' ], 0 ),
+ label: get( d, [ row.key, 'label' ], '' ),
+ visible: row.visible,
+ date: d.date,
+ } ) )
+ )
+ .enter()
+ .append( 'rect' )
+ .attr( 'class', 'bar' )
+ .attr( 'x', d => params.xGroupScale( d.key ) )
+ .attr( 'y', d => params.yScale( d.value ) )
+ .attr( 'width', params.xGroupScale.bandwidth() )
+ .attr( 'height', d => params.height - params.yScale( d.value ) )
+ .attr( 'fill', d => getColor( d.key, params ) )
+ .attr( 'tabindex', '0' )
+ .attr( 'aria-label', d => {
+ const label = params.mode === 'time-comparison' && d.label ? d.label : d.key;
+ return `${ label } ${ params.tooltipValueFormat( d.value ) }`;
+ } )
+ .style( 'opacity', d => {
+ const opacity = d.focus ? 1 : 0.1;
+ return d.visible ? opacity : 0;
+ } )
+ .on( 'focus', ( d, i, nodes ) => {
+ const targetNode = d.value > 0 ? d3Event.target : d3Event.target.parentNode;
+ const position = calculateTooltipPosition( targetNode, node.node(), params.tooltipPosition );
+ handleMouseOverBarChart( d.date, nodes[ i ].parentNode, node, data, params, position );
+ } )
+ .on( 'blur', ( d, i, nodes ) => hideTooltip( nodes[ i ].parentNode, params.tooltip ) );
+
+ barGroup
+ .append( 'rect' )
+ .attr( 'class', 'barmouse' )
+ .attr( 'x', 0 )
+ .attr( 'y', 0 )
+ .attr( 'width', params.xGroupScale.range()[ 1 ] )
+ .attr( 'height', params.height )
+ .attr( 'opacity', '0' )
+ .on( 'mouseover', ( d, i, nodes ) => {
+ const position = calculateTooltipPosition(
+ d3Event.target,
+ node.node(),
+ params.tooltipPosition
+ );
+ handleMouseOverBarChart( d.date, nodes[ i ].parentNode, node, data, params, position );
+ } )
+ .on( 'mouseout', ( d, i, nodes ) => hideTooltip( nodes[ i ].parentNode, params.tooltip ) );
+};
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/breakpoints.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/breakpoints.js
new file mode 100644
index 00000000000..19b8b559da9
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/breakpoints.js
@@ -0,0 +1,3 @@
+/** @format */
+export const smallBreak = 783;
+export const wideBreak = 1365;
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/color.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/color.js
new file mode 100644
index 00000000000..1e2a42c922a
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/color.js
@@ -0,0 +1,25 @@
+/** @format */
+
+/**
+ * External dependencies
+ */
+import { findIndex } from 'lodash';
+
+export const getColor = ( key, params ) => {
+ const smallColorScales = [
+ [],
+ [ 0.5 ],
+ [ 0.333, 0.667 ],
+ [ 0.2, 0.5, 0.8 ],
+ [ 0.12, 0.375, 0.625, 0.88 ],
+ ];
+ let keyValue = 0;
+ const len = params.orderedKeys.length;
+ const idx = findIndex( params.orderedKeys, d => d.key === key );
+ if ( len < 5 ) {
+ keyValue = smallColorScales[ len ][ idx ];
+ } else {
+ keyValue = idx / ( params.orderedKeys.length - 1 );
+ }
+ return params.colorScheme( keyValue );
+};
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/index.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/index.js
new file mode 100644
index 00000000000..8dcbb4716f0
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/index.js
@@ -0,0 +1,136 @@
+/** @format */
+
+/**
+ * External dependencies
+ */
+import { find, get } from 'lodash';
+import { format as d3Format } from 'd3-format';
+import { line as d3Line } from 'd3-shape';
+
+/**
+ * Allows an overriding formatter or defaults to d3Format or d3TimeFormat
+ * @param {string|function} format - either a format string for the D3 formatters or an overriding fomatting method
+ * @param {function} formatter - default d3Format or another formatting method, which accepts the string `format`
+ * @returns {function} to be used to format an input given the format and formatter
+ */
+export const getFormatter = ( format, formatter = d3Format ) =>
+ typeof format === 'function' ? format : formatter( format );
+
+/**
+ * Describes `getUniqueKeys`
+ * @param {array} data - The chart component's `data` prop.
+ * @returns {array} of unique category keys
+ */
+export const getUniqueKeys = data => {
+ return [
+ ...new Set(
+ data.reduce( ( accum, curr ) => {
+ Object.keys( curr ).forEach( key => key !== 'date' && accum.push( key ) );
+ return accum;
+ }, [] )
+ ),
+ ];
+};
+
+/**
+ * Describes `getOrderedKeys`
+ * @param {array} data - The chart component's `data` prop.
+ * @param {array} uniqueKeys - from `getUniqueKeys`.
+ * @returns {array} of unique category keys ordered by cumulative total value
+ */
+export const getOrderedKeys = ( data, uniqueKeys ) =>
+ uniqueKeys
+ .map( key => ( {
+ key,
+ focus: true,
+ total: data.reduce( ( a, c ) => a + c[ key ].value, 0 ),
+ visible: true,
+ } ) )
+ .sort( ( a, b ) => b.total - a.total );
+
+/**
+ * Describes `getLineData`
+ * @param {array} data - The chart component's `data` prop.
+ * @param {array} orderedKeys - from `getOrderedKeys`.
+ * @returns {array} an array objects with a category `key` and an array of `values` with `date` and `value` properties
+ */
+export const getLineData = ( data, orderedKeys ) =>
+ orderedKeys.map( row => ( {
+ key: row.key,
+ focus: row.focus,
+ visible: row.visible,
+ values: data.map( d => ( {
+ date: d.date,
+ focus: row.focus,
+ label: get( d, [ row.key, 'label' ], '' ),
+ value: get( d, [ row.key, 'value' ], 0 ),
+ visible: row.visible,
+ } ) ),
+ } ) );
+
+/**
+ * Describes `getUniqueDates`
+ * @param {array} lineData - from `GetLineData`
+ * @param {function} parseDate - D3 time format parser
+ * @returns {array} an array of unique date values sorted from earliest to latest
+ */
+export const getUniqueDates = ( lineData, parseDate ) => {
+ return [
+ ...new Set(
+ lineData.reduce( ( accum, { values } ) => {
+ values.forEach( ( { date } ) => accum.push( date ) );
+ return accum;
+ }, [] )
+ ),
+ ].sort( ( a, b ) => parseDate( a ) - parseDate( b ) );
+};
+
+/**
+ * Describes getLine
+ * @param {function} xLineScale - from `getXLineScale`.
+ * @param {function} yScale - from `getYScale`.
+ * @returns {function} the D3 line function for plotting all category values
+ */
+export const getLine = ( xLineScale, yScale ) =>
+ d3Line()
+ .x( d => xLineScale( new Date( d.date ) ) )
+ .y( d => yScale( d.value ) );
+
+/**
+ * Describes getDateSpaces
+ * @param {array} data - The chart component's `data` prop.
+ * @param {array} uniqueDates - from `getUniqueDates`
+ * @param {number} width - calculated width of the charting space
+ * @param {function} xLineScale - from `getXLineScale`
+ * @returns {array} that icnludes the date, start (x position) and width to mode the mouseover rectangles
+ */
+export const getDateSpaces = ( data, uniqueDates, width, xLineScale ) =>
+ uniqueDates.map( ( d, i ) => {
+ const datapoints = find( data, { date: d } );
+ const xNow = xLineScale( new Date( d ) );
+ const xPrev =
+ i >= 1
+ ? xLineScale( new Date( uniqueDates[ i - 1 ] ) )
+ : xLineScale( new Date( uniqueDates[ 0 ] ) );
+ const xNext =
+ i < uniqueDates.length - 1
+ ? xLineScale( new Date( uniqueDates[ i + 1 ] ) )
+ : xLineScale( new Date( uniqueDates[ uniqueDates.length - 1 ] ) );
+ let xWidth = i === 0 ? xNext - xNow : xNow - xPrev;
+ const xStart = i === 0 ? 0 : xNow - xWidth / 2;
+ xWidth = i === 0 || i === uniqueDates.length - 1 ? xWidth / 2 : xWidth;
+ return {
+ date: d,
+ start: uniqueDates.length > 1 ? xStart : 0,
+ width: uniqueDates.length > 1 ? xWidth : width,
+ values: Object.keys( datapoints )
+ .filter( key => key !== 'date' )
+ .map( key => {
+ return {
+ key,
+ value: datapoints[ key ].value,
+ date: d,
+ };
+ } ),
+ };
+ } );
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/line-chart.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/line-chart.js
new file mode 100644
index 00000000000..b4193b5fd8b
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/line-chart.js
@@ -0,0 +1,138 @@
+/** @format */
+
+/**
+ * External dependencies
+ */
+import { event as d3Event, select as d3Select } from 'd3-selection';
+import { smallBreak, wideBreak } from './breakpoints';
+
+/**
+ * Internal dependencies
+ */
+import { getColor } from './color';
+import { calculateTooltipPosition, hideTooltip, showTooltip } from './tooltip';
+
+const handleMouseOverLineChart = ( date, parentNode, node, data, params, position ) => {
+ d3Select( parentNode )
+ .select( '.focus-grid' )
+ .attr( 'opacity', '1' );
+ showTooltip( params, data.find( e => e.date === date ), position );
+};
+
+export const drawLines = ( node, data, params ) => {
+ const series = node
+ .append( 'g' )
+ .attr( 'class', 'lines' )
+ .selectAll( '.line-g' )
+ .data( params.lineData.filter( d => d.visible ).reverse() )
+ .enter()
+ .append( 'g' )
+ .attr( 'class', 'line-g' )
+ .attr( 'role', 'region' )
+ .attr( 'aria-label', d => d.key );
+
+ let lineStroke = params.width <= wideBreak || params.uniqueDates.length > 50 ? 2 : 3;
+ lineStroke = params.width <= smallBreak ? 1.25 : lineStroke;
+ const dotRadius = params.width <= wideBreak ? 4 : 6;
+
+ series
+ .append( 'path' )
+ .attr( 'fill', 'none' )
+ .attr( 'stroke-width', lineStroke )
+ .attr( 'stroke-linejoin', 'round' )
+ .attr( 'stroke-linecap', 'round' )
+ .attr( 'stroke', d => getColor( d.key, params ) )
+ .style( 'opacity', d => {
+ const opacity = d.focus ? 1 : 0.1;
+ return d.visible ? opacity : 0;
+ } )
+ .attr( 'd', d => params.line( d.values ) );
+
+ const minDataPointSpacing = 36;
+
+ params.width / params.uniqueDates.length > minDataPointSpacing &&
+ series
+ .selectAll( 'circle' )
+ .data( ( d, i ) => d.values.map( row => ( { ...row, i, visible: d.visible, key: d.key } ) ) )
+ .enter()
+ .append( 'circle' )
+ .attr( 'r', dotRadius )
+ .attr( 'fill', d => getColor( d.key, params ) )
+ .attr( 'stroke', '#fff' )
+ .attr( 'stroke-width', lineStroke + 1 )
+ .style( 'opacity', d => {
+ const opacity = d.focus ? 1 : 0.1;
+ return d.visible ? opacity : 0;
+ } )
+ .attr( 'cx', d => params.xLineScale( new Date( d.date ) ) )
+ .attr( 'cy', d => params.yScale( d.value ) )
+ .attr( 'tabindex', '0' )
+ .attr( 'aria-label', d => {
+ const label = d.label
+ ? d.label
+ : params.tooltipLabelFormat( d.date instanceof Date ? d.date : new Date( d.date ) );
+ return `${ label } ${ params.tooltipValueFormat( d.value ) }`;
+ } )
+ .on( 'focus', ( d, i, nodes ) => {
+ const position = calculateTooltipPosition(
+ d3Event.target,
+ node.node(),
+ params.tooltipPosition
+ );
+ handleMouseOverLineChart( d.date, nodes[ i ].parentNode, node, data, params, position );
+ } )
+ .on( 'blur', ( d, i, nodes ) => hideTooltip( nodes[ i ].parentNode, params.tooltip ) );
+
+ const focus = node
+ .append( 'g' )
+ .attr( 'class', 'focusspaces' )
+ .selectAll( '.focus' )
+ .data( params.dateSpaces )
+ .enter()
+ .append( 'g' )
+ .attr( 'class', 'focus' );
+
+ const focusGrid = focus
+ .append( 'g' )
+ .attr( 'class', 'focus-grid' )
+ .attr( 'opacity', '0' );
+
+ focusGrid
+ .append( 'line' )
+ .attr( 'x1', d => params.xLineScale( new Date( d.date ) ) )
+ .attr( 'y1', 0 )
+ .attr( 'x2', d => params.xLineScale( new Date( d.date ) ) )
+ .attr( 'y2', params.height );
+
+ focusGrid
+ .selectAll( 'circle' )
+ .data( d => d.values.reverse() )
+ .enter()
+ .append( 'circle' )
+ .attr( 'r', dotRadius + 2 )
+ .attr( 'fill', d => getColor( d.key, params ) )
+ .attr( 'stroke', '#fff' )
+ .attr( 'stroke-width', lineStroke + 2 )
+ .attr( 'cx', d => params.xLineScale( new Date( d.date ) ) )
+ .attr( 'cy', d => params.yScale( d.value ) );
+
+ focus
+ .append( 'rect' )
+ .attr( 'class', 'focus-g' )
+ .attr( 'x', d => d.start )
+ .attr( 'y', 0 )
+ .attr( 'width', d => d.width )
+ .attr( 'height', params.height )
+ .attr( 'opacity', 0 )
+ .on( 'mouseover', ( d, i, nodes ) => {
+ const elementWidthRatio = i === 0 || i === params.dateSpaces.length - 1 ? 0 : 0.5;
+ const position = calculateTooltipPosition(
+ d3Event.target,
+ node.node(),
+ params.tooltipPosition,
+ elementWidthRatio
+ );
+ handleMouseOverLineChart( d.date, nodes[ i ].parentNode, node, data, params, position );
+ } )
+ .on( 'mouseout', ( d, i, nodes ) => hideTooltip( nodes[ i ].parentNode, params.tooltip ) );
+};
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/scales.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/scales.js
new file mode 100644
index 00000000000..5639530be73
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/scales.js
@@ -0,0 +1,83 @@
+/** @format */
+
+/**
+ * External dependencies
+ */
+import { max as d3Max } from 'd3-array';
+import {
+ scaleBand as d3ScaleBand,
+ scaleLinear as d3ScaleLinear,
+ scaleTime as d3ScaleTime,
+} from 'd3-scale';
+
+/**
+ * Describes and rounds the maximum y value to the nearest thousand, ten-thousand, million etc. In case it is a decimal number, ceils it.
+ * @param {array} lineData - from `getLineData`
+ * @returns {number} the maximum value in the timeseries multiplied by 4/3
+ */
+export const getYMax = lineData => {
+ const yMax = 4 / 3 * d3Max( lineData, d => d3Max( d.values.map( date => date.value ) ) );
+ const pow3Y = Math.pow( 10, ( ( Math.log( yMax ) * Math.LOG10E + 1 ) | 0 ) - 2 ) * 3;
+ return Math.ceil( Math.ceil( yMax / pow3Y ) * pow3Y );
+};
+
+/**
+ * Describes getXScale
+ * @param {array} uniqueDates - from `getUniqueDates`
+ * @param {number} width - calculated width of the charting space
+ * @param {boolean} compact - whether the chart must be compact (without padding
+ between days)
+ * @returns {function} a D3 scale of the dates
+ */
+export const getXScale = ( uniqueDates, width, compact = false ) =>
+ d3ScaleBand()
+ .domain( uniqueDates )
+ .rangeRound( [ 0, width ] )
+ .paddingInner( compact ? 0 : 0.1 );
+
+/**
+ * Describes getXGroupScale
+ * @param {array} orderedKeys - from `getOrderedKeys`
+ * @param {function} xScale - from `getXScale`
+ * @param {boolean} compact - whether the chart must be compact (without padding
+ between days)
+ * @returns {function} a D3 scale for each category within the xScale range
+ */
+export const getXGroupScale = ( orderedKeys, xScale, compact = false ) =>
+ d3ScaleBand()
+ .domain( orderedKeys.filter( d => d.visible ).map( d => d.key ) )
+ .rangeRound( [ 0, xScale.bandwidth() ] )
+ .padding( compact ? 0 : 0.07 );
+
+/**
+ * Describes getXLineScale
+ * @param {array} uniqueDates - from `getUniqueDates`
+ * @param {number} width - calculated width of the charting space
+ * @returns {function} a D3 scaletime for each date
+ */
+export const getXLineScale = ( uniqueDates, width ) =>
+ d3ScaleTime()
+ .domain( [ new Date( uniqueDates[ 0 ] ), new Date( uniqueDates[ uniqueDates.length - 1 ] ) ] )
+ .rangeRound( [ 0, width ] );
+
+/**
+ * Describes getYScale
+ * @param {number} height - calculated height of the charting space
+ * @param {number} yMax - from `getYMax`
+ * @returns {function} the D3 linear scale from 0 to the value from `getYMax`
+ */
+export const getYScale = ( height, yMax ) =>
+ d3ScaleLinear()
+ .domain( [ 0, yMax ] )
+ .rangeRound( [ height, 0 ] );
+
+/**
+ * Describes getyTickOffset
+ * @param {number} height - calculated height of the charting space
+ * @param {number} yMax - from `getYMax`
+ * @returns {function} the D3 linear scale from 0 to the value from `getYMax`, offset by 12 pixels down
+ */
+export const getYTickOffset = ( height, yMax ) =>
+ d3ScaleLinear()
+ .domain( [ 0, yMax ] )
+ .rangeRound( [ height + 12, 12 ] );
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/test/utils.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/axis.js
similarity index 51%
rename from plugins/woocommerce-admin/packages/components/src/chart/d3chart/test/utils.js
rename to plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/axis.js
index d29ed740b6e..7a19250c93f 100644
--- a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/test/utils.js
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/axis.js
@@ -1,162 +1,12 @@
+/** @format */
/**
* External dependencies
- *
- * @format
*/
-// import { noop } from 'lodash';
-import { utcParse as d3UTCParse } from 'd3-time-format';
/**
- * Internal dependencies
- */
-import dummyOrders from './fixtures/dummy';
-import {
- compareStrings,
- getDateSpaces,
- getOrderedKeys,
- getLineData,
- getUniqueKeys,
- getUniqueDates,
- getXScale,
- getXGroupScale,
- getXLineScale,
- getXTicks,
- getYMax,
- getYScale,
- getYTickOffset,
-} from '../utils';
-
-const orderedKeys = [
- {
- key: 'Cap',
- focus: true,
- visible: true,
- total: 34513697,
- },
- {
- key: 'T-Shirt',
- focus: true,
- visible: true,
- total: 14762281,
- },
- {
- key: 'Sunglasses',
- focus: true,
- visible: true,
- total: 12430349,
- },
- {
- key: 'Polo',
- focus: true,
- visible: true,
- total: 8712807,
- },
- {
- key: 'Hoodie',
- focus: true,
- visible: true,
- total: 6968764,
- },
-];
-const orderedDates = [
- '2018-05-30T00:00:00',
- '2018-05-31T00:00:00',
- '2018-06-01T00:00:00',
- '2018-06-02T00:00:00',
- '2018-06-03T00:00:00',
- '2018-06-04T00:00:00',
-];
-const parseDate = d3UTCParse( '%Y-%m-%dT%H:%M:%S' );
-const testUniqueKeys = getUniqueKeys( dummyOrders );
-const testOrderedKeys = getOrderedKeys( dummyOrders, testUniqueKeys );
-const testLineData = getLineData( dummyOrders, testOrderedKeys );
-const testUniqueDates = getUniqueDates( testLineData, parseDate );
-const testXScale = getXScale( testUniqueDates, 100 );
-const testXLineScale = getXLineScale( testUniqueDates, 100 );
-const testYMax = getYMax( testLineData );
-const testYScale = getYScale( 100, testYMax );
-
-describe( 'parseDate', () => {
- it( 'correctly parse date in the expected format', () => {
- const testDate = parseDate( '2018-06-30T00:00:00' );
- const expectedDate = new Date( Date.UTC( 2018, 5, 30 ) );
- expect( testDate.getTime() ).toEqual( expectedDate.getTime() );
- } );
-} );
-
-describe( 'getUniqueKeys', () => {
- it( 'returns an array of keys excluding date', () => {
- // sort is a mutating action so we need a copy
- const testUniqueKeysClone = testUniqueKeys.slice();
- const sortedAZKeys = orderedKeys.map( d => d.key ).slice();
- expect( testUniqueKeysClone.sort() ).toEqual( sortedAZKeys.sort() );
- } );
-} );
-
-describe( 'getOrderedKeys', () => {
- it( 'returns an array of keys order by value from largest to smallest', () => {
- expect( testOrderedKeys ).toEqual( orderedKeys );
- } );
-} );
-
-describe( 'getLineData', () => {
- it( 'returns a sorted array of objects with category key', () => {
- expect( testLineData ).toBeInstanceOf( Array );
- expect( testLineData ).toHaveLength( 5 );
- expect( testLineData.map( d => d.key ) ).toEqual( orderedKeys.map( d => d.key ) );
- } );
-
- testLineData.forEach( d => {
- it( 'ensure a key and that the values property is an array', () => {
- expect( d ).toHaveProperty( 'key' );
- expect( d ).toHaveProperty( 'values' );
- expect( d.values ).toBeInstanceOf( Array );
- } );
-
- it( 'ensure all unique dates exist in values array', () => {
- const rowDates = d.values.map( row => row.date );
- expect( rowDates ).toEqual( orderedDates );
- } );
-
- d.values.forEach( row => {
- it( 'ensure a date property and that the values property is an array with date (parseable) and value properties', () => {
- expect( row ).toHaveProperty( 'date' );
- expect( row ).toHaveProperty( 'value' );
- expect( parseDate( row.date ) ).not.toBeNull();
- expect( typeof row.date ).toBe( 'string' );
- expect( typeof row.value ).toBe( 'number' );
- } );
- } );
- } );
-} );
-
-describe( 'getXScale', () => {
- it( 'properly scale inputs to the provided domain and range', () => {
- expect( testXScale( orderedDates[ 0 ] ) ).toEqual( 3 );
- expect( testXScale( orderedDates[ 2 ] ) ).toEqual( 35 );
- expect( testXScale( orderedDates[ orderedDates.length - 1 ] ) ).toEqual( 83 );
- } );
- it( 'properly scale inputs and test the bandwidth', () => {
- expect( testXScale.bandwidth() ).toEqual( 14 );
- } );
-} );
-
-describe( 'getXGroupScale', () => {
- it( 'properly scale inputs based on the getXScale', () => {
- const testXGroupScale = getXGroupScale( testOrderedKeys, testXScale );
- expect( testXGroupScale( orderedKeys[ 0 ].key ) ).toEqual( 2 );
- expect( testXGroupScale( orderedKeys[ 2 ].key ) ).toEqual( 6 );
- expect( testXGroupScale( orderedKeys[ orderedKeys.length - 1 ].key ) ).toEqual( 10 );
- } );
-} );
-
-describe( 'getXLineScale', () => {
- it( 'properly scale inputs for the line', () => {
- expect( testXLineScale( new Date( orderedDates[ 0 ] ) ) ).toEqual( 0 );
- expect( testXLineScale( new Date( orderedDates[ 2 ] ) ) ).toEqual( 40 );
- expect( testXLineScale( new Date( orderedDates[ orderedDates.length - 1 ] ) ) ).toEqual( 100 );
- } );
-} );
+* Internal dependencies
+*/
+import { compareStrings, getXTicks } from '../axis';
describe( 'getXTicks', () => {
describe( 'interval=day', () => {
@@ -380,42 +230,6 @@ describe( 'getXTicks', () => {
} );
} );
-describe( 'getYMax', () => {
- it( 'calculate the correct maximum y value', () => {
- expect( testYMax ).toEqual( 15000000 );
- } );
-} );
-
-describe( 'getYScale', () => {
- it( 'properly scale the y values given the height and maximum y value', () => {
- expect( testYScale( 0 ) ).toEqual( 100 );
- expect( testYScale( testYMax ) ).toEqual( 0 );
- } );
-} );
-
-describe( 'getYTickOffset', () => {
- it( 'properly scale the y values for the y-axis ticks given the height and maximum y value', () => {
- const testYTickOffset1 = getYTickOffset( 100, testYMax );
- expect( testYTickOffset1( 0 ) ).toEqual( 112 );
- expect( testYTickOffset1( testYMax ) ).toEqual( 12 );
- } );
-} );
-
-describe( 'getDateSpaces', () => {
- it( 'return an array used to space out the mouseover rectangles, used for tooltips', () => {
- const testDateSpaces = getDateSpaces( dummyOrders, testUniqueDates, 100, testXLineScale );
- expect( testDateSpaces[ 0 ].date ).toEqual( '2018-05-30T00:00:00' );
- expect( testDateSpaces[ 0 ].start ).toEqual( 0 );
- expect( testDateSpaces[ 0 ].width ).toEqual( 10 );
- expect( testDateSpaces[ 3 ].date ).toEqual( '2018-06-02T00:00:00' );
- expect( testDateSpaces[ 3 ].start ).toEqual( 50 );
- expect( testDateSpaces[ 3 ].width ).toEqual( 20 );
- expect( testDateSpaces[ testDateSpaces.length - 1 ].date ).toEqual( '2018-06-04T00:00:00' );
- expect( testDateSpaces[ testDateSpaces.length - 1 ].start ).toEqual( 90 );
- expect( testDateSpaces[ testDateSpaces.length - 1 ].width ).toEqual( 10 );
- } );
-} );
-
describe( 'compareStrings', () => {
it( 'return an array of unique words from s2 that dont appear in base string', () => {
expect( compareStrings( 'Jul 2018', 'Aug 2018' ).join( ' ' ) ).toEqual( 'Aug' );
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/fixtures/dummy-ordered-dates.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/fixtures/dummy-ordered-dates.js
new file mode 100644
index 00000000000..85839f2932d
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/fixtures/dummy-ordered-dates.js
@@ -0,0 +1,9 @@
+/** @format */
+export default [
+ '2018-05-30T00:00:00',
+ '2018-05-31T00:00:00',
+ '2018-06-01T00:00:00',
+ '2018-06-02T00:00:00',
+ '2018-06-03T00:00:00',
+ '2018-06-04T00:00:00',
+];
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/fixtures/dummy-ordered-keys.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/fixtures/dummy-ordered-keys.js
new file mode 100644
index 00000000000..713e7ea877f
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/fixtures/dummy-ordered-keys.js
@@ -0,0 +1,33 @@
+/** @format */
+export default [
+ {
+ key: 'Cap',
+ focus: true,
+ visible: true,
+ total: 34513697,
+ },
+ {
+ key: 'T-Shirt',
+ focus: true,
+ visible: true,
+ total: 14762281,
+ },
+ {
+ key: 'Sunglasses',
+ focus: true,
+ visible: true,
+ total: 12430349,
+ },
+ {
+ key: 'Polo',
+ focus: true,
+ visible: true,
+ total: 8712807,
+ },
+ {
+ key: 'Hoodie',
+ focus: true,
+ visible: true,
+ total: 6968764,
+ },
+];
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/test/fixtures/dummy.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/fixtures/dummy-orders.js
similarity index 95%
rename from plugins/woocommerce-admin/packages/components/src/chart/d3chart/test/fixtures/dummy.js
rename to plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/fixtures/dummy-orders.js
index 6e1488316ed..9f825544f07 100644
--- a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/test/fixtures/dummy.js
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/fixtures/dummy-orders.js
@@ -1,11 +1,4 @@
/** @format */
-
-/**
- * /* eslint-disable quote-props
- *
- * @format
- */
-
export default [
{
date: '2018-05-30T00:00:00',
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/index.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/index.js
new file mode 100644
index 00000000000..85bae47e55d
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/index.js
@@ -0,0 +1,96 @@
+/** @format */
+/**
+ * External dependencies
+ */
+import { utcParse as d3UTCParse } from 'd3-time-format';
+
+/**
+ * Internal dependencies
+ */
+import dummyOrders from './fixtures/dummy-orders';
+import orderedDates from './fixtures/dummy-ordered-dates';
+import orderedKeys from './fixtures/dummy-ordered-keys';
+import {
+ getDateSpaces,
+ getOrderedKeys,
+ getLineData,
+ getUniqueKeys,
+ getUniqueDates,
+} from '../index';
+import { getXLineScale } from '../scales';
+
+const parseDate = d3UTCParse( '%Y-%m-%dT%H:%M:%S' );
+const testUniqueKeys = getUniqueKeys( dummyOrders );
+const testOrderedKeys = getOrderedKeys( dummyOrders, testUniqueKeys );
+const testLineData = getLineData( dummyOrders, testOrderedKeys );
+const testUniqueDates = getUniqueDates( testLineData, parseDate );
+const testXLineScale = getXLineScale( testUniqueDates, 100 );
+
+describe( 'parseDate', () => {
+ it( 'correctly parse date in the expected format', () => {
+ const testDate = parseDate( '2018-06-30T00:00:00' );
+ const expectedDate = new Date( Date.UTC( 2018, 5, 30 ) );
+ expect( testDate.getTime() ).toEqual( expectedDate.getTime() );
+ } );
+} );
+
+describe( 'getUniqueKeys', () => {
+ it( 'returns an array of keys excluding date', () => {
+ // sort is a mutating action so we need a copy
+ const testUniqueKeysClone = testUniqueKeys.slice();
+ const sortedAZKeys = orderedKeys.map( d => d.key ).slice();
+ expect( testUniqueKeysClone.sort() ).toEqual( sortedAZKeys.sort() );
+ } );
+} );
+
+describe( 'getOrderedKeys', () => {
+ it( 'returns an array of keys order by value from largest to smallest', () => {
+ expect( testOrderedKeys ).toEqual( orderedKeys );
+ } );
+} );
+
+describe( 'getLineData', () => {
+ it( 'returns a sorted array of objects with category key', () => {
+ expect( testLineData ).toBeInstanceOf( Array );
+ expect( testLineData ).toHaveLength( 5 );
+ expect( testLineData.map( d => d.key ) ).toEqual( orderedKeys.map( d => d.key ) );
+ } );
+
+ testLineData.forEach( d => {
+ it( 'ensure a key and that the values property is an array', () => {
+ expect( d ).toHaveProperty( 'key' );
+ expect( d ).toHaveProperty( 'values' );
+ expect( d.values ).toBeInstanceOf( Array );
+ } );
+
+ it( 'ensure all unique dates exist in values array', () => {
+ const rowDates = d.values.map( row => row.date );
+ expect( rowDates ).toEqual( orderedDates );
+ } );
+
+ d.values.forEach( row => {
+ it( 'ensure a date property and that the values property is an array with date (parseable) and value properties', () => {
+ expect( row ).toHaveProperty( 'date' );
+ expect( row ).toHaveProperty( 'value' );
+ expect( parseDate( row.date ) ).not.toBeNull();
+ expect( typeof row.date ).toBe( 'string' );
+ expect( typeof row.value ).toBe( 'number' );
+ } );
+ } );
+ } );
+} );
+
+describe( 'getDateSpaces', () => {
+ it( 'return an array used to space out the mouseover rectangles, used for tooltips', () => {
+ const testDateSpaces = getDateSpaces( dummyOrders, testUniqueDates, 100, testXLineScale );
+ expect( testDateSpaces[ 0 ].date ).toEqual( '2018-05-30T00:00:00' );
+ expect( testDateSpaces[ 0 ].start ).toEqual( 0 );
+ expect( testDateSpaces[ 0 ].width ).toEqual( 10 );
+ expect( testDateSpaces[ 3 ].date ).toEqual( '2018-06-02T00:00:00' );
+ expect( testDateSpaces[ 3 ].start ).toEqual( 50 );
+ expect( testDateSpaces[ 3 ].width ).toEqual( 20 );
+ expect( testDateSpaces[ testDateSpaces.length - 1 ].date ).toEqual( '2018-06-04T00:00:00' );
+ expect( testDateSpaces[ testDateSpaces.length - 1 ].start ).toEqual( 90 );
+ expect( testDateSpaces[ testDateSpaces.length - 1 ].width ).toEqual( 10 );
+ } );
+} );
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/scales.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/scales.js
new file mode 100644
index 00000000000..346d727c5db
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/test/scales.js
@@ -0,0 +1,78 @@
+/** @format */
+/**
+ * External dependencies
+ */
+import { utcParse as d3UTCParse } from 'd3-time-format';
+
+/**
+ * Internal dependencies
+ */
+import dummyOrders from './fixtures/dummy-orders';
+import orderedDates from './fixtures/dummy-ordered-dates';
+import orderedKeys from './fixtures/dummy-ordered-keys';
+import {
+ getOrderedKeys,
+ getLineData,
+ getUniqueKeys,
+ getUniqueDates,
+} from '../index';
+import { getXGroupScale, getXScale, getXLineScale, getYMax, getYScale, getYTickOffset } from '../scales';
+
+const parseDate = d3UTCParse( '%Y-%m-%dT%H:%M:%S' );
+const testUniqueKeys = getUniqueKeys( dummyOrders );
+const testOrderedKeys = getOrderedKeys( dummyOrders, testUniqueKeys );
+const testLineData = getLineData( dummyOrders, testOrderedKeys );
+const testUniqueDates = getUniqueDates( testLineData, parseDate );
+const testXScale = getXScale( testUniqueDates, 100 );
+const testXLineScale = getXLineScale( testUniqueDates, 100 );
+const testYMax = getYMax( testLineData );
+const testYScale = getYScale( 100, testYMax );
+
+describe( 'getXScale', () => {
+ it( 'properly scale inputs to the provided domain and range', () => {
+ expect( testXScale( orderedDates[ 0 ] ) ).toEqual( 3 );
+ expect( testXScale( orderedDates[ 2 ] ) ).toEqual( 35 );
+ expect( testXScale( orderedDates[ orderedDates.length - 1 ] ) ).toEqual( 83 );
+ } );
+ it( 'properly scale inputs and test the bandwidth', () => {
+ expect( testXScale.bandwidth() ).toEqual( 14 );
+ } );
+} );
+
+describe( 'getXGroupScale', () => {
+ it( 'properly scale inputs based on the getXScale', () => {
+ const testXGroupScale = getXGroupScale( testOrderedKeys, testXScale );
+ expect( testXGroupScale( orderedKeys[ 0 ].key ) ).toEqual( 2 );
+ expect( testXGroupScale( orderedKeys[ 2 ].key ) ).toEqual( 6 );
+ expect( testXGroupScale( orderedKeys[ orderedKeys.length - 1 ].key ) ).toEqual( 10 );
+ } );
+} );
+
+describe( 'getXLineScale', () => {
+ it( 'properly scale inputs for the line', () => {
+ expect( testXLineScale( new Date( orderedDates[ 0 ] ) ) ).toEqual( 0 );
+ expect( testXLineScale( new Date( orderedDates[ 2 ] ) ) ).toEqual( 40 );
+ expect( testXLineScale( new Date( orderedDates[ orderedDates.length - 1 ] ) ) ).toEqual( 100 );
+ } );
+} );
+
+describe( 'getYMax', () => {
+ it( 'calculate the correct maximum y value', () => {
+ expect( testYMax ).toEqual( 15000000 );
+ } );
+} );
+
+describe( 'getYScale', () => {
+ it( 'properly scale the y values given the height and maximum y value', () => {
+ expect( testYScale( 0 ) ).toEqual( 100 );
+ expect( testYScale( testYMax ) ).toEqual( 0 );
+ } );
+} );
+
+describe( 'getYTickOffset', () => {
+ it( 'properly scale the y values for the y-axis ticks given the height and maximum y value', () => {
+ const testYTickOffset1 = getYTickOffset( 100, testYMax );
+ expect( testYTickOffset1( 0 ) ).toEqual( 112 );
+ expect( testYTickOffset1( testYMax ) ).toEqual( 12 );
+ } );
+} );
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/tooltip.js b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/tooltip.js
new file mode 100644
index 00000000000..edf38cdcd21
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/chart/d3chart/utils/tooltip.js
@@ -0,0 +1,148 @@
+/** @format */
+
+/**
+ * External dependencies
+ */
+import { select as d3Select } from 'd3-selection';
+
+/**
+ * Internal dependencies
+ */
+import { getColor } from './color';
+
+export const hideTooltip = ( parentNode, tooltipNode ) => {
+ d3Select( parentNode )
+ .selectAll( '.barfocus, .focus-grid' )
+ .attr( 'opacity', '0' );
+ d3Select( tooltipNode )
+ .style( 'visibility', 'hidden' );
+};
+
+const calculateTooltipXPosition = (
+ elementCoords,
+ chartCoords,
+ tooltipSize,
+ tooltipMargin,
+ elementWidthRatio,
+ tooltipPosition
+) => {
+ const d3BaseCoords = d3Select( '.d3-base' ).node().getBoundingClientRect();
+ const leftMargin = Math.max( d3BaseCoords.left, chartCoords.left );
+
+ if ( tooltipPosition === 'below' ) {
+ return Math.max(
+ tooltipMargin,
+ Math.min(
+ elementCoords.left + elementCoords.width * 0.5 - tooltipSize.width / 2 - leftMargin,
+ d3BaseCoords.width - tooltipSize.width - tooltipMargin
+ )
+ );
+ }
+
+ const xPosition =
+ elementCoords.left + elementCoords.width * elementWidthRatio + tooltipMargin - leftMargin;
+
+ if ( xPosition + tooltipSize.width + tooltipMargin > d3BaseCoords.width ) {
+ return Math.max(
+ tooltipMargin,
+ elementCoords.left +
+ elementCoords.width * ( 1 - elementWidthRatio ) -
+ tooltipSize.width -
+ tooltipMargin -
+ leftMargin
+ );
+ }
+
+ return xPosition;
+};
+
+const calculateTooltipYPosition = (
+ elementCoords,
+ chartCoords,
+ tooltipSize,
+ tooltipMargin,
+ tooltipPosition
+) => {
+ if ( tooltipPosition === 'below' ) {
+ return chartCoords.height;
+ }
+
+ const yPosition = elementCoords.top + tooltipMargin - chartCoords.top;
+ if ( yPosition + tooltipSize.height + tooltipMargin > chartCoords.height ) {
+ return Math.max( 0, elementCoords.top - tooltipSize.height - tooltipMargin - chartCoords.top );
+ }
+
+ return yPosition;
+};
+
+export const calculateTooltipPosition = ( element, chart, tooltipPosition, elementWidthRatio = 1 ) => {
+ const elementCoords = element.getBoundingClientRect();
+ const chartCoords = chart.getBoundingClientRect();
+ const tooltipSize = d3Select( '.d3-chart__tooltip' )
+ .node()
+ .getBoundingClientRect();
+ const tooltipMargin = 24;
+
+ if ( tooltipPosition === 'below' ) {
+ elementWidthRatio = 0;
+ }
+
+ return {
+ x: calculateTooltipXPosition(
+ elementCoords,
+ chartCoords,
+ tooltipSize,
+ tooltipMargin,
+ elementWidthRatio,
+ tooltipPosition
+ ),
+ y: calculateTooltipYPosition(
+ elementCoords,
+ chartCoords,
+ tooltipSize,
+ tooltipMargin,
+ tooltipPosition
+ ),
+ };
+};
+
+const getTooltipRowLabel = ( d, row, params ) => {
+ if ( d[ row.key ].labelDate ) {
+ return params.tooltipLabelFormat(
+ d[ row.key ].labelDate instanceof Date
+ ? d[ row.key ].labelDate
+ : new Date( d[ row.key ].labelDate )
+ );
+ }
+ return row.key;
+};
+
+export const showTooltip = ( params, d, position ) => {
+ const keys = params.orderedKeys.filter( row => row.visible ).map(
+ row => `
+
+
+
+ ${ getTooltipRowLabel( d, row, params ) }
+
+ ${ params.tooltipValueFormat( d[ row.key ].value ) }
+
+ `
+ );
+
+ const tooltipTitle = params.tooltipTitle
+ ? params.tooltipTitle
+ : params.tooltipLabelFormat( d.date instanceof Date ? d.date : new Date( d.date ) );
+
+ d3Select( params.tooltip )
+ .style( 'left', position.x + 'px' )
+ .style( 'top', position.y + 'px' )
+ .style( 'visibility', 'visible' ).html( `
+
+ ` );
+};
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/index.js b/plugins/woocommerce-admin/packages/components/src/chart/index.js
index 0486d2f9eec..e45aa2e7403 100644
--- a/plugins/woocommerce-admin/packages/components/src/chart/index.js
+++ b/plugins/woocommerce-admin/packages/components/src/chart/index.js
@@ -113,8 +113,8 @@ class Chart extends Component {
}
handleLegendToggle( event ) {
- const { data, mode } = this.props;
- if ( mode ) {
+ const { data, interactiveLegend } = this.props;
+ if ( ! interactiveLegend ) {
return;
}
const orderedKeys = this.state.orderedKeys.map( d => ( {
@@ -211,28 +211,44 @@ class Chart extends Component {
return 220;
}
+ getLegendPosition() {
+ const { legendPosition, mode, isViewportWide } = this.props;
+ if ( legendPosition ) {
+ return legendPosition;
+ }
+ if ( isViewportWide && mode === 'time-comparison' ) {
+ return 'top';
+ }
+ if ( isViewportWide && mode === 'item-comparison' ) {
+ return 'side';
+ }
+ return 'bottom';
+ }
+
render() {
- const { orderedKeys, visibleData, width } = this.state;
+ const { interactiveLegend, orderedKeys, visibleData, width } = this.state;
const {
dateParser,
+ interval,
+ isRequesting,
+ isViewportLarge,
itemsLabel,
mode,
- isViewportLarge,
- isViewportWide,
+ showHeaderControls,
title,
tooltipLabelFormat,
tooltipValueFormat,
tooltipTitle,
+ type,
+ valueType,
xFormat,
x2Format,
- interval,
- valueType,
- type,
- isRequesting,
} = this.props;
let { yFormat } = this.props;
- const legendDirection = mode === 'time-comparison' && isViewportWide ? 'row' : 'column';
- const chartDirection = ( mode === 'item-comparison' ) && isViewportWide ? 'row' : 'column';
+
+ const legendPosition = this.getLegendPosition();
+ const legendDirection = legendPosition === 'top' ? 'row' : 'column';
+ const chartDirection = legendPosition === 'side' ? 'row' : 'column';
const chartHeight = this.getChartHeight();
const legend = (
@@ -241,7 +257,7 @@ class Chart extends Component {
data={ orderedKeys }
handleLegendHover={ this.handleLegendHover }
handleLegendToggle={ this.handleLegendToggle }
- interactive={ mode !== 'block' }
+ interactive={ interactiveLegend }
legendDirection={ legendDirection }
legendValueFormat={ tooltipValueFormat }
totalLabel={ sprintf( itemsLabel, orderedKeys.length ) }
@@ -267,10 +283,10 @@ class Chart extends Component {
}
return (
- { mode !== 'block' &&
+ { showHeaderControls && (
{ title }
- { isViewportWide && legendDirection === 'row' && legend }
+ { legendPosition === 'top' && legend }
{ this.renderIntervalSelector() }
- }
+ ) }
- { isViewportWide && legendDirection === 'column' && mode !== 'block' && legend }
+ { legendPosition === 'side' && legend }
{ isRequesting && (
@@ -328,7 +344,7 @@ class Chart extends Component {
height={ chartHeight }
interval={ interval }
margin={ margin }
- mode={ mode === 'block' ? 'item-comparison' : mode }
+ mode={ mode }
orderedKeys={ orderedKeys }
tooltipLabelFormat={ tooltipLabelFormat }
tooltipValueFormat={ tooltipValueFormat }
@@ -343,7 +359,9 @@ class Chart extends Component {
/>
) }
- { ( ! isViewportWide || mode === 'block' ) && { legend }
}
+ { ( legendPosition === 'bottom' ) && (
+ { legend }
+ ) }
);
@@ -351,6 +369,10 @@ class Chart extends Component {
}
Chart.propTypes = {
+ /**
+ * Allowed intervals to show in a dropdown.
+ */
+ allowedIntervals: PropTypes.array,
/**
* An array of data.
*/
@@ -363,6 +385,11 @@ Chart.propTypes = {
* Label describing the legend items.
*/
itemsLabel: PropTypes.string,
+ /**
+ * `item-comparison` (default) or `time-comparison`, this is used to generate correct
+ * ARIA properties.
+ */
+ mode: PropTypes.oneOf( [ 'item-comparison', 'time-comparison' ] ),
/**
* Current path
*/
@@ -371,6 +398,35 @@ Chart.propTypes = {
* The query string represented in object form
*/
query: PropTypes.object,
+ /**
+ * Whether the legend items can be activated/deactivated.
+ */
+ interactiveLegend: PropTypes.bool,
+ /**
+ * Interval specification (hourly, daily, weekly etc).
+ */
+ interval: PropTypes.oneOf( [ 'hour', 'day', 'week', 'month', 'quarter', 'year' ] ),
+ /**
+ * Information about the currently selected interval, and set of allowed intervals for the chart. See `getIntervalsForQuery`.
+ */
+ intervalData: PropTypes.object,
+ /**
+ * Render a chart placeholder to signify an in-flight data request.
+ */
+ isRequesting: PropTypes.bool,
+ /**
+ * Position the legend must be displayed in. If it's not defined, it's calculated
+ * depending on the viewport width and the mode.
+ */
+ legendPosition: PropTypes.oneOf( [ 'bottom', 'side', 'top' ] ),
+ /**
+ * Wether header UI controls must be displayed.
+ */
+ showHeaderControls: PropTypes.bool,
+ /**
+ * A title describing this chart.
+ */
+ title: PropTypes.string,
/**
* A datetime formatting string or overriding function to format the tooltip label.
*/
@@ -383,6 +439,14 @@ Chart.propTypes = {
* A string to use as a title for the tooltip. Takes preference over `tooltipLabelFormat`.
*/
tooltipTitle: PropTypes.string,
+ /**
+ * Chart type of either `line` or `bar`.
+ */
+ type: PropTypes.oneOf( [ 'bar', 'line' ] ),
+ /**
+ * What type of data is to be displayed? Number, Average, String?
+ */
+ valueType: PropTypes.string,
/**
* A datetime formatting string, passed to d3TimeFormat.
*/
@@ -395,53 +459,22 @@ Chart.propTypes = {
* A number formatting string, passed to d3Format.
*/
yFormat: PropTypes.string,
- /**
- * `item-comparison` (default) or `time-comparison`, this is used to generate correct
- * ARIA properties.
- */
- mode: PropTypes.oneOf( [ 'block', 'item-comparison', 'time-comparison' ] ),
- /**
- * A title describing this chart.
- */
- title: PropTypes.string,
- /**
- * Chart type of either `line` or `bar`.
- */
- type: PropTypes.oneOf( [ 'bar', 'line' ] ),
- /**
- * Information about the currently selected interval, and set of allowed intervals for the chart. See `getIntervalsForQuery`.
- */
- intervalData: PropTypes.object,
- /**
- * Interval specification (hourly, daily, weekly etc).
- */
- interval: PropTypes.oneOf( [ 'hour', 'day', 'week', 'month', 'quarter', 'year' ] ),
- /**
- * Allowed intervals to show in a dropdown.
- */
- allowedIntervals: PropTypes.array,
- /**
- * What type of data is to be displayed? Number, Average, String?
- */
- valueType: PropTypes.string,
- /**
- * Render a chart placeholder to signify an in-flight data request.
- */
- isRequesting: PropTypes.bool,
};
Chart.defaultProps = {
data: [],
dateParser: '%Y-%m-%dT%H:%M:%S',
+ interactiveLegend: true,
+ interval: 'day',
+ isRequesting: false,
+ mode: 'time-comparison',
+ showHeaderControls: true,
tooltipLabelFormat: '%B %d, %Y',
tooltipValueFormat: ',',
+ type: 'line',
xFormat: '%d',
x2Format: '%b %Y',
yFormat: '$.3s',
- mode: 'time-comparison',
- type: 'line',
- interval: 'day',
- isRequesting: false,
};
export default withViewportMatch( {
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/placeholder.js b/plugins/woocommerce-admin/packages/components/src/chart/placeholder.js
index 2fb3ced50e8..0eb374380c0 100644
--- a/plugins/woocommerce-admin/packages/components/src/chart/placeholder.js
+++ b/plugins/woocommerce-admin/packages/components/src/chart/placeholder.js
@@ -4,6 +4,7 @@
*/
import { Component } from '@wordpress/element';
import PropTypes from 'prop-types';
+import { Spinner } from '@wordpress/components';
/**
* `ChartPlaceholder` displays a large loading indiciator for use in place of a `Chart` while data is loading.
@@ -13,7 +14,9 @@ class ChartPlaceholder extends Component {
const { height } = this.props;
return (
-
+
+
+
);
}
}
diff --git a/plugins/woocommerce-admin/packages/components/src/chart/style.scss b/plugins/woocommerce-admin/packages/components/src/chart/style.scss
index 8b4a86c5829..1bc09df1034 100644
--- a/plugins/woocommerce-admin/packages/components/src/chart/style.scss
+++ b/plugins/woocommerce-admin/packages/components/src/chart/style.scss
@@ -56,6 +56,12 @@
@include placeholder();
padding: 0;
width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ .components-spinner {
+ margin: 0;
+ }
}
.woocommerce-chart__interval-select {
diff --git a/plugins/woocommerce-admin/packages/components/src/filters/advanced/number-filter.js b/plugins/woocommerce-admin/packages/components/src/filters/advanced/number-filter.js
index d69c76983d4..804074ed676 100644
--- a/plugins/woocommerce-admin/packages/components/src/filters/advanced/number-filter.js
+++ b/plugins/woocommerce-admin/packages/components/src/filters/advanced/number-filter.js
@@ -4,30 +4,43 @@
*/
import { Component, Fragment } from '@wordpress/element';
import { SelectControl, TextControl } from '@wordpress/components';
-import { get, find, partial } from 'lodash';
+import { get, find, partial, isArray } from 'lodash';
import interpolateComponents from 'interpolate-components';
import classnames from 'classnames';
-import { _x } from '@wordpress/i18n';
+import { sprintf, __, _x } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import TextControlWithAffixes from '../../text-control-with-affixes';
+import { textContent } from './utils';
+
+/**
+ * WooCommerce dependencies
+ */
import { formatCurrency } from '@woocommerce/currency';
class NumberFilter extends Component {
getBetweenString() {
return _x(
- '{{rangeStart /}}{{span}}and{{/span}}{{rangeEnd /}}',
+ '{{rangeStart /}}{{span}} and {{/span}}{{rangeEnd /}}',
'Numerical range inputs arranged on a single line',
'wc-admin'
);
}
- getLegend( filter, config ) {
+ getScreenReaderText( filter, config ) {
const inputType = get( config, [ 'input', 'type' ], 'number' );
const rule = find( config.rules, { value: filter.rule } ) || {};
- let [ rangeStart, rangeEnd ] = ( filter.value || '' ).split( ',' );
+ let [ rangeStart, rangeEnd ] = isArray( filter.value ) ? filter.value : [ filter.value ];
+
+ // Return nothing if we're missing input(s)
+ if (
+ ! rangeStart ||
+ ( 'between' === rule.value && ! rangeEnd )
+ ) {
+ return '';
+ }
if ( 'currency' === inputType ) {
rangeStart = formatCurrency( rangeStart );
@@ -47,16 +60,16 @@ class NumberFilter extends Component {
} );
}
- return interpolateComponents( {
+ return textContent( interpolateComponents( {
mixedString: config.labels.title,
components: {
- filter: { filterStr },
- rule: { rule.label },
+ filter: { filterStr },
+ rule: { rule.label },
},
- } );
+ } ) );
}
- getFormControl( type, value, onChange ) {
+ getFormControl( { type, value, label, onChange } ) {
if ( 'currency' === type ) {
const currencySymbol = get( wcSettings, [ 'currency', 'symbol' ] );
const symbolPosition = get( wcSettings, [ 'currency', 'position' ] );
@@ -68,6 +81,7 @@ class NumberFilter extends Component {
className="woocommerce-filters-advanced__input"
type="number"
value={ value || '' }
+ aria-label={ label }
onChange={ onChange }
/>
:
);
@@ -85,6 +100,7 @@ class NumberFilter extends Component {
className="woocommerce-filters-advanced__input"
type="number"
value={ value || '' }
+ aria-label={ label }
onChange={ onChange }
/>
);
@@ -98,40 +114,71 @@ class NumberFilter extends Component {
return this.getRangeInput();
}
- const [ rangeStart, rangeEnd ] = ( filter.value || '' ).split( ',' );
+ const [ rangeStart, rangeEnd ] = isArray( filter.value ) ? filter.value : [ filter.value ];
if ( Boolean( rangeEnd ) ) {
// If there's a value for rangeEnd, we've just changed from "between"
// to "less than" or "more than" and need to transition the value
onFilterChange( filter.key, 'value', rangeStart || rangeEnd );
}
- return this.getFormControl(
- inputType,
- rangeStart || rangeEnd,
- partial( onFilterChange, filter.key, 'value' )
- );
+ let labelFormat = '';
+
+ if ( 'lessthan' === filter.rule ) {
+ /* eslint-disable-next-line max-len */
+ /* translators: Sentence fragment, "maximum amount" refers to a numeric value the field must be less than. Screenshot for context: https://cloudup.com/cmv5CLyMPNQ */
+ labelFormat = _x( '%(field)s maximum amount', 'maximum value input', 'wc-admin' );
+ } else {
+ /* eslint-disable-next-line max-len */
+ /* translators: Sentence fragment, "minimum amount" refers to a numeric value the field must be more than. Screenshot for context: https://cloudup.com/cmv5CLyMPNQ */
+ labelFormat = _x( '%(field)s minimum amount', 'minimum value input', 'wc-admin' );
+ }
+
+ return this.getFormControl( {
+ type: inputType,
+ value: rangeStart || rangeEnd,
+ label: sprintf( labelFormat, { field: get( config, [ 'labels', 'add' ] ) } ),
+ onChange: partial( onFilterChange, filter.key, 'value' ),
+ } );
}
getRangeInput() {
const { config, filter, onFilterChange } = this.props;
const inputType = get( config, [ 'input', 'type' ], 'number' );
- const [ rangeStart, rangeEnd ] = ( filter.value || '' ).split( ',' );
+ const [ rangeStart, rangeEnd ] = isArray( filter.value ) ? filter.value : [ filter.value ];
const rangeStartOnChange = ( newRangeStart ) => {
- const newValue = [ newRangeStart, rangeEnd ].join( ',' );
- onFilterChange( filter.key, 'value', newValue );
+ onFilterChange( filter.key, 'value', [ newRangeStart, rangeEnd ] );
};
const rangeEndOnChange = ( newRangeEnd ) => {
- const newValue = [ rangeStart, newRangeEnd ].join( ',' );
- onFilterChange( filter.key, 'value', newValue );
+ onFilterChange( filter.key, 'value', [ rangeStart, newRangeEnd ] );
};
return interpolateComponents( {
mixedString: this.getBetweenString(),
components: {
- rangeStart: this.getFormControl( inputType, rangeStart, rangeStartOnChange ),
- rangeEnd: this.getFormControl( inputType, rangeEnd, rangeEndOnChange ),
+ rangeStart: this.getFormControl( {
+ type: inputType,
+ value: rangeStart || '',
+ label: sprintf(
+ /* eslint-disable-next-line max-len */
+ /* translators: Sentence fragment, "range start" refers to the first of two numeric values the field must be between. Screenshot for context: https://cloudup.com/cmv5CLyMPNQ */
+ __( '%(field)s range start', 'wc-admin' ),
+ { field: get( config, [ 'labels', 'add' ] ) }
+ ),
+ onChange: rangeStartOnChange,
+ } ),
+ rangeEnd: this.getFormControl( {
+ type: inputType,
+ value: rangeEnd || '',
+ label: sprintf(
+ /* eslint-disable-next-line max-len */
+ /* translators: Sentence fragment, "range end" refers to the second of two numeric values the field must be between. Screenshot for context: https://cloudup.com/cmv5CLyMPNQ */
+ __( '%(field)s range end', 'wc-admin' ),
+ { field: get( config, [ 'labels', 'add' ] ) }
+ ),
+ onChange: rangeEndOnChange,
+ } ),
span: ,
},
} );
@@ -165,11 +212,14 @@ class NumberFilter extends Component {
),
},
} );
+
+ const screenReaderText = this.getScreenReaderText( filter, config );
+
/*eslint-disable jsx-a11y/no-noninteractive-tabindex*/
return (
);
/*eslint-enable jsx-a11y/no-noninteractive-tabindex*/
diff --git a/plugins/woocommerce-admin/packages/components/src/filters/advanced/search-filter.js b/plugins/woocommerce-admin/packages/components/src/filters/advanced/search-filter.js
index 3284b29895b..92189a5b006 100644
--- a/plugins/woocommerce-admin/packages/components/src/filters/advanced/search-filter.js
+++ b/plugins/woocommerce-admin/packages/components/src/filters/advanced/search-filter.js
@@ -2,7 +2,7 @@
/**
* External dependencies
*/
-import { Component } from '@wordpress/element';
+import { Component, Fragment } from '@wordpress/element';
import { SelectControl } from '@wordpress/components';
import { find, isEqual, partial } from 'lodash';
import PropTypes from 'prop-types';
@@ -13,6 +13,7 @@ import classnames from 'classnames';
* Internal dependencies
*/
import Search from '../../search';
+import { textContent } from './utils';
class SearchFilter extends Component {
constructor( { filter, config, query } ) {
@@ -51,18 +52,23 @@ class SearchFilter extends Component {
onFilterChange( filter.key, 'value', idList );
}
- getLegend( filter, config ) {
+ getScreenReaderText( filter, config ) {
const { selected } = this.state;
+
+ if ( 0 === selected.length ) {
+ return '';
+ }
+
const rule = find( config.rules, { value: filter.rule } ) || {};
const filterStr = selected.map( item => item.label ).join( ', ' );
- return interpolateComponents( {
+ return textContent( interpolateComponents( {
mixedString: config.labels.title,
components: {
- filter: { filterStr },
- rule: { rule.label },
+ filter: { filterStr },
+ rule: { rule.label },
},
- } );
+ } ) );
}
render() {
@@ -95,11 +101,14 @@ class SearchFilter extends Component {
),
},
} );
+
+ const screenReaderText = this.getScreenReaderText( filter, config );
+
/*eslint-disable jsx-a11y/no-noninteractive-tabindex*/
return (
);
/*eslint-enable jsx-a11y/no-noninteractive-tabindex*/
diff --git a/plugins/woocommerce-admin/packages/components/src/filters/advanced/select-filter.js b/plugins/woocommerce-admin/packages/components/src/filters/advanced/select-filter.js
index 9fd68cdc9d3..b967e6daf97 100644
--- a/plugins/woocommerce-admin/packages/components/src/filters/advanced/select-filter.js
+++ b/plugins/woocommerce-admin/packages/components/src/filters/advanced/select-filter.js
@@ -2,13 +2,18 @@
/**
* External dependencies
*/
-import { Component } from '@wordpress/element';
+import { Component, Fragment } from '@wordpress/element';
import { SelectControl, Spinner } from '@wordpress/components';
import { find, partial } from 'lodash';
import PropTypes from 'prop-types';
import interpolateComponents from 'interpolate-components';
import classnames from 'classnames';
+/**
+ * Internal dependencies
+ */
+import { textContent } from './utils';
+
/**
* WooCommerce dependencies
*/
@@ -41,16 +46,21 @@ class SelectFilter extends Component {
return options;
}
- getLegend( filter, config ) {
+ getScreenReaderText( filter, config ) {
+ if ( '' === filter.value ) {
+ return '';
+ }
+
const rule = find( config.rules, { value: filter.rule } ) || {};
const value = find( config.input.options, { value: filter.value } ) || {};
- return interpolateComponents( {
+
+ return textContent( interpolateComponents( {
mixedString: config.labels.title,
components: {
- filter: { value.label },
- rule: { rule.label },
+ filter: { value.label },
+ rule: { rule.label },
},
- } );
+ } ) );
}
render() {
@@ -83,10 +93,15 @@ class SelectFilter extends Component {
),
},
} );
+
+ const screenReaderText = this.getScreenReaderText( filter, config );
+
/*eslint-disable jsx-a11y/no-noninteractive-tabindex*/
return (
);
/*eslint-enable jsx-a11y/no-noninteractive-tabindex*/
diff --git a/plugins/woocommerce-admin/packages/components/src/filters/advanced/test/utils.js b/plugins/woocommerce-admin/packages/components/src/filters/advanced/test/utils.js
new file mode 100644
index 00000000000..93b9268a4b3
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/filters/advanced/test/utils.js
@@ -0,0 +1,83 @@
+/**
+ * Internal dependencies
+ */
+import { textContent } from '../utils';
+
+describe( 'textContent()', () => {
+ test( 'should get text `Hello World`', () => {
+ const component = (
+
+
Hello
World
+
+ );
+
+ expect( textContent( component ) ).toBe( 'Hello World' );
+ } );
+
+ test( 'render variable', () => {
+ const component = (
+
+
Hello
{ 'World' + '2' }
+
+ );
+
+ expect( textContent( component ) ).toBe( 'Hello World2' );
+ } );
+
+ test( 'render variable2', () => {
+ const component = (
+
+
Hello
{ 1 + 1 }
+
+ );
+
+ expect( textContent( component ) ).toBe( 'Hello 2' );
+ } );
+
+ test( 'should output empty string', () => {
+ const component = ( );
+
+ expect( textContent( component ) ).toBe( '' );
+ } );
+
+ test( 'array children', () => {
+ const component = (
+
+
Hello
World
+ {
+ [ 'a', b
]
+ }
+
+ );
+
+ expect( textContent( component ) ).toBe( 'Hello Worldab' );
+ } );
+
+ test( 'array children with null', () => {
+ const component = (
+
+
Hello
World
+ {
+ [ 'a', null ]
+ }
+
+ );
+
+ expect( textContent( component ) ).toBe( 'Hello Worlda' );
+ } );
+
+ test( 'array component', () => {
+ const component = ( [
+ a
,
+ 'b',
+ 'c',
+ (
+
+
x
y
+
+ ),
+ ] );
+
+ expect( textContent( component ) ).toBe( 'abcxy' );
+ } );
+} );
diff --git a/plugins/woocommerce-admin/packages/components/src/filters/advanced/utils.js b/plugins/woocommerce-admin/packages/components/src/filters/advanced/utils.js
new file mode 100644
index 00000000000..3bb5b7a149f
--- /dev/null
+++ b/plugins/woocommerce-admin/packages/components/src/filters/advanced/utils.js
@@ -0,0 +1,36 @@
+/**
+ * External dependencies
+ */
+import { isArray, isNumber, isString } from 'lodash';
+
+/**
+ * DOM Node.textContent for React components
+ * See: https://github.com/rwu823/react-addons-text-content/blob/master/src/index.js
+ *
+ * @param {Array} components array of components
+ *
+ * @returns {string} concatenated text content of all nodes
+ */
+export function textContent( components ) {
+ let text = '';
+
+ const toText = ( component ) => {
+ if ( isString( component ) || isNumber( component ) ) {
+ text += component;
+ } else if ( isArray( component ) ) {
+ component.forEach( toText );
+ } else if ( component && component.props ) {
+ const { children } = component.props;
+
+ if ( isArray( children ) ) {
+ children.forEach( toText );
+ } else {
+ toText( children );
+ }
+ }
+ };
+
+ toText( components );
+
+ return text;
+}
diff --git a/plugins/woocommerce-admin/packages/components/src/search/style.scss b/plugins/woocommerce-admin/packages/components/src/search/style.scss
index cb75d19ea59..15cc87d764d 100644
--- a/plugins/woocommerce-admin/packages/components/src/search/style.scss
+++ b/plugins/woocommerce-admin/packages/components/src/search/style.scss
@@ -10,8 +10,10 @@
fill: $core-grey-light-900;
}
- .woocommerce-tag {
- margin: 8px 6px 0 0;
+ &:not(.has-inline-tags) {
+ .woocommerce-tag {
+ margin: 8px 6px 0 0;
+ }
}
&.has-inline-tags {
@@ -19,10 +21,6 @@
top: 50%;
transform: translateY(-50%);
}
-
- .woocommerce-tag {
- margin: initial;
- }
}
.woocommerce-search__inline-container {
diff --git a/plugins/woocommerce-admin/packages/components/src/section-header/style.scss b/plugins/woocommerce-admin/packages/components/src/section-header/style.scss
index a3d8ceb9fb0..61a176f1f14 100644
--- a/plugins/woocommerce-admin/packages/components/src/section-header/style.scss
+++ b/plugins/woocommerce-admin/packages/components/src/section-header/style.scss
@@ -21,6 +21,19 @@
height: 1px;
margin: 0 10px;
}
+
+ @include breakpoint( '<782px' ) {
+ &.has-interval-select {
+ position: relative;
+ padding-bottom: 30px;
+ .woocommerce-chart__interval-select {
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ padding-left: 6px;
+ }
+ }
+ }
}
.woocommerce-section-header__actions,
@@ -31,6 +44,18 @@
display: flex;
flex-grow: 1;
justify-content: flex-end;
+ align-items: center;
+
+ .components-base-control {
+ padding-top: 0;
+ min-height: 34px;
+ }
+ .components-base-control__field {
+ margin-bottom: 0;
+ select {
+ background: transparent;
+ }
+ }
}
.woocommerce-ellipsis-menu__toggle {
@@ -48,7 +73,7 @@
// EllipsisMenu is 24px, so to match we add 6px padding around the
// heading text, which we know is 18px from line-height.
padding: 3px 0;
- @include font-size( 15 );
+ @include font-size( 18 );
line-height: 2.2;
font-weight: 600;
}
diff --git a/plugins/woocommerce-admin/packages/components/src/split-button/test/__snapshots__/index.js.snap b/plugins/woocommerce-admin/packages/components/src/split-button/test/__snapshots__/index.js.snap
index b5bb968b297..bd202037f19 100644
--- a/plugins/woocommerce-admin/packages/components/src/split-button/test/__snapshots__/index.js.snap
+++ b/plugins/woocommerce-admin/packages/components/src/split-button/test/__snapshots__/index.js.snap
@@ -20,7 +20,7 @@ exports[`SplitButton it should render a simple split button 1`] = `
type="button"
>