From 4b8c96b2d5870da3828b6c20e5d7a8772f397bca Mon Sep 17 00:00:00 2001 From: Yizhe Liu Date: Wed, 14 Oct 2020 22:27:57 -0700 Subject: [PATCH 1/8] Support HC detector on UI --- package.json | 5 + public/models/interfaces.ts | 7 + .../components/FeatureChart/FeatureChart.tsx | 20 +- .../containers/AnomaliesChart.tsx | 443 +-- .../containers/AnomalyDetailsChart.tsx | 388 +++ .../containers/AnomalyHeatmapChart.tsx | 514 +++ .../containers/AnomalyOccurrenceChart.tsx | 121 + .../containers/FeatureBreakDown.tsx | 90 +- .../__tests__/AnomaliesChart.test.tsx | 20 +- .../__tests__/FeatureBreakDown.test.tsx | 7 +- .../AnomalyCharts/utils/anomalyChartUtils.ts | 360 +- .../Components/AnomaliesDistribution.tsx | 4 +- .../Components/AnomaliesLiveChart.tsx | 6 +- public/pages/Dashboard/utils/utils.tsx | 4 +- .../containers/AnomalyHistory.tsx | 192 +- .../containers/AnomalyResults.tsx | 13 +- .../containers/AnomalyResultsTable.tsx | 31 +- public/pages/DetectorResults/index.scss | 6 + .../pages/DetectorResults/utils/tableUtils.ts | 10 + .../AggregationSelector.tsx | 9 +- .../FeatureAccordion/FeatureAccordion.tsx | 14 +- .../EditFeatures/containers/EditFeatures.tsx | 3 +- .../containers/SampleAnomalies.tsx | 61 +- .../containers/utils/formikToFeatures.ts | 4 +- public/pages/EditFeatures/utils/helpers.ts | 2 +- .../components/DataFilters/dataFilter.scss | 8 + .../containers/CreateDetector.tsx | 4 +- public/pages/utils/anomalyResultUtils.ts | 268 +- public/redux/reducers/alerting.ts | 25 + public/redux/reducers/anomalies.ts | 18 +- public/redux/reducers/anomalyResults.ts | 19 + public/utils/utils.tsx | 63 +- server/cluster/ad/alertingPlugin.ts | 23 +- server/models/interfaces.ts | 6 +- server/models/types.ts | 10 +- server/routes/ad.ts | 48 + server/routes/alerting.ts | 31 +- server/routes/utils/adHelpers.ts | 2 + server/utils/constants.ts | 2 + utils/constants.ts | 1 + yarn.lock | 2945 ++++++++++++++++- 41 files changed, 5174 insertions(+), 633 deletions(-) create mode 100644 public/pages/AnomalyCharts/containers/AnomalyDetailsChart.tsx create mode 100644 public/pages/AnomalyCharts/containers/AnomalyHeatmapChart.tsx create mode 100644 public/pages/AnomalyCharts/containers/AnomalyOccurrenceChart.tsx diff --git a/package.json b/package.json index 1fd84722..987c169a 100644 --- a/package.json +++ b/package.json @@ -51,8 +51,10 @@ "@types/node": "^12.6.8", "@types/react": "^16.8.23", "@types/react-dom": "^16.8.4", + "@types/react-plotly.js": "^2.2.4", "@types/react-redux": "^7.1.1", "@types/react-router-dom": "^4.3.4", + "@types/react-vis": "^1.11.3", "@types/redux-mock-store": "^1.0.1", "babel-eslint": "^9.0.0", "babel-jest": "^24.8.0", @@ -82,8 +84,11 @@ "eslint-plugin-cypress": "^2.11.1", "formik": "^1.5.8", "lodash": "^4.17.19", + "plotly.js": "^1.55.2", "query-string": "^6.8.2", + "react-plotly.js": "^2.4.0", "react-redux": "^7.1.0", + "react-vis": "^1.11.7", "reselect": "^4.0.0" } } diff --git a/public/models/interfaces.ts b/public/models/interfaces.ts index f2648037..ae9163fb 100644 --- a/public/models/interfaces.ts +++ b/public/models/interfaces.ts @@ -127,6 +127,11 @@ export type DetectorListItem = { enabledTime?: number; }; +export type EntityData = { + name: string; + value: string; +}; + export type AnomalyData = { anomalyGrade: number; anomalyScore?: number; @@ -135,6 +140,8 @@ export type AnomalyData = { endTime: number; startTime: number; plotTime?: number; + entity?: EntityData[]; + features?: { [key: string]: FeatureAggregationData }; }; export type FeatureAggregationData = { diff --git a/public/pages/AnomalyCharts/components/FeatureChart/FeatureChart.tsx b/public/pages/AnomalyCharts/components/FeatureChart/FeatureChart.tsx index 42576f43..4aea90d5 100644 --- a/public/pages/AnomalyCharts/components/FeatureChart/FeatureChart.tsx +++ b/public/pages/AnomalyCharts/components/FeatureChart/FeatureChart.tsx @@ -40,9 +40,11 @@ import { darkModeEnabled } from '../../../../utils/kibanaUtils'; import { prepareDataForChart, getFeatureMissingDataAnnotations, + filterWithDateRange, } from '../../../utils/anomalyResultUtils'; import { CodeModal } from '../../../DetectorConfig/components/CodeModal/CodeModal'; import { CHART_FIELDS, FEATURE_CHART_THEME } from '../../utils/constants'; +import { isEmpty } from 'lodash'; interface FeatureChartProps { feature: FeatureAttributes; @@ -61,6 +63,7 @@ interface FeatureChartProps { showFeatureMissingDataPointAnnotation?: boolean; detectorEnabledTime?: number; rawFeatureData: FeatureAggregationData[]; + titlePrefix?: string; } const getDisabledChartBackground = () => darkModeEnabled() ? '#25262E' : '#F0F0F0'; @@ -137,12 +140,23 @@ export const FeatureChart = (props: FeatureChartProps) => { return undefined; }; + const getFeatureAnnotations = () => { + if (isEmpty(props.annotations)) { + return []; + } + return filterWithDateRange( + props.annotations, + props.dateRange, + 'coordinates.x0' + ); + }; return ( { /> {props.feature.featureEnabled ? ( { - const dispatch = useDispatch(); - const [anomalySummary, setAnomalySummary] = useState( - INITIAL_ANOMALY_SUMMARY - ); - const [showAlertsFlyout, setShowAlertsFlyout] = useState(false); - const [alertAnnotations, setAlertAnnotations] = useState([]); - const [isLoadingAlerts, setIsLoadingAlerts] = useState(false); - const [totalAlerts, setTotalAlerts] = useState(undefined); - const [alerts, setAlerts] = useState([]); - const [zoomRange, setZoomRange] = useState({ - ...props.dateRange, - }); - const [zoomedAnomalies, setZoomedAnomalies] = useState([]); +export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => { const [datePickerRange, setDatePickerRange] = useState({ start: 'now-7d', end: 'now', }); - useEffect(() => { - const anomalies = prepareDataForChart(props.anomalies, zoomRange); - setZoomedAnomalies(anomalies); - setAnomalySummary( - !props.bucketizedAnomalies - ? getAnomalySummary( - filterWithDateRange(props.anomalies, zoomRange, 'plotTime') - ) - : props.anomalySummary - ); - setTotalAlerts(filterWithDateRange(alerts, zoomRange, 'startTime').length); - }, [props.anomalies, zoomRange]); - - const handleZoomRangeChange = (start: number, end: number) => { - setZoomRange({ - startDate: start, - endDate: end, - }); - props.onZoomRangeChange(start, end); - }; - - useEffect(() => { - async function getMonitorAlerts(monitorId: string, startDateTime: number) { - try { - setIsLoadingAlerts(true); - const result = await dispatch( - searchES(getAlertsQuery(monitorId, startDateTime)) - ); - setIsLoadingAlerts(false); - setTotalAlerts( - get(result, 'data.response.aggregations.total_alerts.value') - ); - const monitorAlerts = convertAlerts(result); - setAlerts(monitorAlerts); - const annotations = generateAlertAnnotations(monitorAlerts); - setAlertAnnotations(annotations); - } catch (err) { - console.error(`Failed to get alerts for monitor ${monitorId}`, err); - setIsLoadingAlerts(false); - } - } - if (props.monitor && props.dateRange.startDate) { - getMonitorAlerts(props.monitor.id, props.dateRange.startDate); - } - }, [props.monitor, props.dateRange.startDate]); - - const anomalyChartTimeFormatter = niceTimeFormatter([ - zoomRange.startDate, - zoomRange.endDate, - ]); + const anomalies = get(props.anomaliesResult, 'anomalies', []); const handleDateRangeChange = (startDate: number, endDate: number) => { props.onDateRangeChange(startDate, endDate); - handleZoomRangeChange(startDate, endDate); + props.onZoomRangeChange(startDate, endDate); }; - const showLoader = useDelayedLoader(props.isLoading || isLoadingAlerts); + const showLoader = useDelayedLoader(props.isLoading); const handleDatePickerDateRangeChange = ( start: string, @@ -200,7 +113,7 @@ export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => { startTime.valueOf() >= props.dateRange.startDate && endTime.valueOf() <= props.dateRange.endDate ) { - handleZoomRangeChange(startTime.valueOf(), endTime.valueOf()); + props.onZoomRangeChange(startTime.valueOf(), endTime.valueOf()); } else { handleDateRangeChange(startTime.valueOf(), endTime.valueOf()); } @@ -209,9 +122,16 @@ export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => { } }; + const handleDatePickerRangeChange = (start: number, end: number) => { + setDatePickerRange({ + start: moment(start).format(), + end: moment(end).format(), + }); + }; + const datePicker = () => ( { @@ -240,6 +160,7 @@ export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => { return ( {datePicker()} + {setUpAlertsButton()} @@ -256,183 +177,129 @@ export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => { } > - - - - - - - - - - - - - - {props.showAlerts ? ( - - setShowAlertsFlyout(true)} - totalAlerts={totalAlerts} - isLoading={props.isLoading} - /> + {props.isHCDetector && + props.onHeatmapCellSelected && + props.detectorCategoryField ? ( + + +
+ {props.isLoading ? ( + + + + + + ) : ( + [ + , + props.showAlerts === undefined || !props.showAlerts + ? [ + , + , + , + , + ] + : null, + ] + )} +
- ) : null} -
- - -
- {props.isLoading || isLoadingAlerts ? ( - - - - - - ) : ( - - { - const start = get(brushArea, 'x.0', datePickerRange.start); - const end = get(brushArea,'x.1',datePickerRange.start); - !props.bucketizedAnomalies - ? handleZoomRangeChange(start, end) - : handleDateRangeChange(start, end); - setDatePickerRange({ - start: moment(start).format(), - end: moment(end).format(), - }); - }} - theme={ANOMALY_CHART_THEME} - /> - - {alertAnnotations ? ( - } - /> - ) : null} - - - - - - )} -
-
-
+
+ ) : ( + + )}
{props.children}
- - {showAlertsFlyout ? ( - setShowAlertsFlyout(false)} - /> - ) : null} ); }); diff --git a/public/pages/AnomalyCharts/containers/AnomalyDetailsChart.tsx b/public/pages/AnomalyCharts/containers/AnomalyDetailsChart.tsx new file mode 100644 index 00000000..6544156e --- /dev/null +++ b/public/pages/AnomalyCharts/containers/AnomalyDetailsChart.tsx @@ -0,0 +1,388 @@ +/* + * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import { + AnnotationDomainTypes, + Axis, + Chart, + LineAnnotation, + LineSeries, + niceTimeFormatter, + Position, + RectAnnotation, + ScaleType, + Settings, + XYBrushArea, +} from '@elastic/charts'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiIcon, + EuiLoadingChart, + EuiStat, +} from '@elastic/eui'; +import { get } from 'lodash'; +import moment from 'moment'; +import React, { useEffect, useState } from 'react'; +import { useDispatch } from 'react-redux'; +import { useDelayedLoader } from '../../../hooks/useDelayedLoader'; +import { + AnomalySummary, + DateRange, + Detector, + Monitor, + MonitorAlert, +} from '../../../models/interfaces'; +import { searchAlerts } from '../../../redux/reducers/alerting'; +import { darkModeEnabled } from '../../../utils/kibanaUtils'; +import { + filterWithDateRange, + prepareDataForChart, +} from '../../utils/anomalyResultUtils'; +import { AlertsFlyout } from '../components/AlertsFlyout/AlertsFlyout'; +import { + AlertsStat, + AnomalyStatWithTooltip, +} from '../components/AnomaliesStat/AnomalyStat'; +import { + convertAlerts, + disabledHistoryAnnotations, + generateAlertAnnotations, + getAnomalySummary, +} from '../utils/anomalyChartUtils'; +import { + ANOMALY_CHART_THEME, + CHART_FIELDS, + INITIAL_ANOMALY_SUMMARY, +} from '../utils/constants'; +import { HeatmapCell } from './AnomalyHeatmapChart'; + +interface AnomalyDetailsChartProps { + onDateRangeChange( + startDate: number, + endDate: number, + dateRangeOption?: string + ): void; + onZoomRangeChange(startDate: number, endDate: number): void; + anomalies: any[]; + bucketizedAnomalies: boolean; + anomalySummary: any; + dateRange: DateRange; + isLoading: boolean; + showAlerts?: boolean; + anomalyGradeSeriesName: string; + confidenceSeriesName: string; + detectorId: string; + detectorName: string; + detector?: Detector; + detectorInterval?: number; + unit?: string; + monitor?: Monitor; + isHCDetector?: boolean; + selectedHeatmapCell?: HeatmapCell; + onDatePickerRangeChange?(startDate: number, endDate: number): void; +} + +export const AnomalyDetailsChart = React.memo( + (props: AnomalyDetailsChartProps) => { + const dispatch = useDispatch(); + const [anomalySummary, setAnomalySummary] = useState( + INITIAL_ANOMALY_SUMMARY + ); + const [showAlertsFlyout, setShowAlertsFlyout] = useState(false); + const [alertAnnotations, setAlertAnnotations] = useState([]); + const [isLoadingAlerts, setIsLoadingAlerts] = useState(false); + const [totalAlerts, setTotalAlerts] = useState( + undefined + ); + const [alerts, setAlerts] = useState([]); + const [zoomRange, setZoomRange] = useState({ + ...props.dateRange, + }); + const [zoomedAnomalies, setZoomedAnomalies] = useState([]); + + const DEFAULT_DATE_PICKER_RANGE = { + start: moment().subtract(7, 'days').valueOf(), + end: moment().valueOf(), + }; + + useEffect(() => { + const anomalies = prepareDataForChart(props.anomalies, zoomRange); + setZoomedAnomalies(anomalies); + setAnomalySummary( + !props.bucketizedAnomalies + ? getAnomalySummary( + filterWithDateRange(props.anomalies, zoomRange, 'plotTime') + ) + : props.anomalySummary + ); + setTotalAlerts( + filterWithDateRange(alerts, zoomRange, 'startTime').length + ); + }, [props.anomalies, zoomRange, props.dateRange]); + + useEffect(() => { + setZoomRange(props.dateRange); + }, [props.dateRange]); + + const handleZoomRangeChange = (start: number, end: number) => { + setZoomRange({ + startDate: start, + endDate: end, + }); + props.onZoomRangeChange(start, end); + }; + + useEffect(() => { + async function getMonitorAlerts( + monitorId: string, + startDateTime: number, + endDateTime: number + ) { + try { + setIsLoadingAlerts(true); + const result = await dispatch( + searchAlerts(monitorId, startDateTime, endDateTime) + ); + setIsLoadingAlerts(false); + setTotalAlerts(get(result, 'data.response.totalAlerts')); + const monitorAlerts = convertAlerts(result); + setAlerts(monitorAlerts); + const annotations = generateAlertAnnotations(monitorAlerts); + setAlertAnnotations(annotations); + } catch (err) { + console.error(`Failed to get alerts for monitor ${monitorId}`, err); + setIsLoadingAlerts(false); + } + } + if ( + props.monitor && + props.dateRange.startDate && + // only load alert stats for non HC detector + props.isHCDetector != undefined && + !props.isHCDetector + ) { + getMonitorAlerts( + props.monitor.id, + props.dateRange.startDate, + props.dateRange.endDate + ); + } + }, [props.monitor, props.dateRange.startDate]); + + const anomalyChartTimeFormatter = niceTimeFormatter([ + zoomRange.startDate, + zoomRange.endDate, + ]); + + const handleDateRangeChange = (startDate: number, endDate: number) => { + props.onDateRangeChange(startDate, endDate); + handleZoomRangeChange(startDate, endDate); + }; + + const showLoader = useDelayedLoader(props.isLoading || isLoadingAlerts); + + return ( + + + + + + + + + + + + + + + {props.showAlerts && !props.isHCDetector ? ( + + setShowAlertsFlyout(true)} + totalAlerts={totalAlerts} + isLoading={props.isLoading} + /> + + ) : null} + + + +
+ {props.isLoading || isLoadingAlerts ? ( + + + + + + ) : ( + + { + const start = get( + brushArea, + 'x.0', + DEFAULT_DATE_PICKER_RANGE.start + ); + const end = get( + brushArea, + 'x.1', + DEFAULT_DATE_PICKER_RANGE.start + ); + !props.bucketizedAnomalies + ? handleZoomRangeChange(start, end) + : handleDateRangeChange(start, end); + if (props.onDatePickerRangeChange) { + props.onDatePickerRangeChange(start, end); + } + } + } + theme={ANOMALY_CHART_THEME} + /> + {props.isHCDetector && !props.selectedHeatmapCell ? null : ( + + )} + + {alertAnnotations ? ( + } + /> + ) : null} + + + + + + )} +
+
+
+ + {showAlertsFlyout ? ( + setShowAlertsFlyout(false)} + /> + ) : null} +
+ ); + } +); diff --git a/public/pages/AnomalyCharts/containers/AnomalyHeatmapChart.tsx b/public/pages/AnomalyCharts/containers/AnomalyHeatmapChart.tsx new file mode 100644 index 00000000..2e6ce964 --- /dev/null +++ b/public/pages/AnomalyCharts/containers/AnomalyHeatmapChart.tsx @@ -0,0 +1,514 @@ +/* + * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import React, { useState } from 'react'; + +import moment from 'moment'; +import { PlotData } from 'plotly.js'; +import Plot from 'react-plotly.js'; +import { get, isEmpty } from 'lodash'; +import { + EuiFlexItem, + EuiFlexGroup, + EuiLoadingChart, + EuiText, + EuiComboBox, + EuiSuperSelect, + EuiIconTip, + EuiCallOut, +} from '@elastic/eui'; +import { euiPaletteWarm } from '@elastic/eui/lib/services'; +import { useDelayedLoader } from '../../../hooks/useDelayedLoader'; +import { Monitor, DateRange } from '../../../models/interfaces'; +import { AlertsFlyout } from '../components/AlertsFlyout/AlertsFlyout'; +import { + getAnomaliesHeatmapData, + getSelectedHeatmapCellPlotData, + updateHeatmapPlotData, + HEATMAP_X_AXIS_DATE_FORMAT, + AnomalyHeatmapSortType, + sortHeatmapPlotData, + filterHeatmapPlotDataByY, +} from '../utils/anomalyChartUtils'; + +interface AnomalyHeatmapChartProps { + title: string; + detectorId: string; + detectorName: string; + anomalies: any[]; + dateRange: DateRange; + isLoading: boolean; + showAlerts?: boolean; + monitor?: Monitor; + detectorInterval?: number; + unit?: string; + onHeatmapCellSelected(cell: HeatmapCell | undefined): void; +} + +export interface HeatmapCell { + dateRange: DateRange; + entityValue: string; +} + +export const AnomalyHeatmapChart = React.memo( + (props: AnomalyHeatmapChartProps) => { + const showLoader = useDelayedLoader(props.isLoading); + const HEATMAP_ID = 'HEATMAP_DIV_ID'; + const CELL_HEIGHT = 40; + + const SORT_BY_FIELD_OPTIONS = [ + { + value: AnomalyHeatmapSortType.SEVERITY, + inputDisplay: 'By severity', + }, + { + value: AnomalyHeatmapSortType.OCCURRENCES, + inputDisplay: 'By occurrence', + }, + ]; + + const COMBINED_OPTIONS = { + label: 'Combined options', + options: [ + { label: 'Top 10', value: 10 }, + { label: 'Top 20', value: 20 }, + { label: 'Top 30', value: 30 }, + ], + }; + + const getViewEntityOptions = (inputHeatmapData: PlotData[]) => { + let individualEntities = []; + if (!isEmpty(inputHeatmapData)) { + //@ts-ignore + individualEntities = inputHeatmapData[0].y.filter( + //@ts-ignore + (entityValue) => entityValue && entityValue.trim().length > 0 + ); + } + const individualEntityOptions = [] as any[]; + //@ts-ignore + individualEntities.forEach((entityValue) => { + individualEntityOptions.push({ + label: entityValue, + }); + }); + + return [ + COMBINED_OPTIONS, + { + label: 'Individual entities', + options: individualEntityOptions, + }, + ]; + }; + + const [originalHeatmapData, setOriginalHeatmapData] = useState( + getAnomaliesHeatmapData( + props.anomalies, + props.dateRange, + AnomalyHeatmapSortType.SEVERITY, + COMBINED_OPTIONS.options[0].value + ) + ); + const [heatmapData, setHeatmapData] = useState( + originalHeatmapData + ); + + const [sortByFeildValue, setSortByFeildValue] = useState( + SORT_BY_FIELD_OPTIONS[0].value + ); + + const [currentViewOptions, setCurrentViewOptions] = useState([ + getViewEntityOptions(originalHeatmapData)[0].options[0], + ]); + + const [entityViewOptions, setEntityViewOptions] = useState( + getViewEntityOptions(originalHeatmapData) + ); + + const [showAlertsFlyout, setShowAlertsFlyout] = useState(false); + + const [numEntities, setNumEntities] = useState( + originalHeatmapData[0].y.length + ); + + const hasAnomalyInHeatmap = (): boolean => { + for (let entityAnomaliesOccurence of heatmapData[0].text) { + //@ts-ignore + const sum = entityAnomaliesOccurence.reduce((a, b) => { + return a + b; + }); + if (sum > 0) { + return true; + } + } + return false; + }; + + const handleHeatmapClick = (event: Plotly.PlotMouseEvent) => { + const selectedCellIndices = get(event, 'points[0].pointIndex', []); + const selectedEntity = get(event, 'points[0].y', ''); + if (!isEmpty(selectedCellIndices)) { + let anomalyCount = get(event, 'points[0].text', 0); + if ( + anomalyCount === 0 || + (heatmapData.length > 1 && + //@ts-ignore + heatmapData[1].z[selectedCellIndices[0]][selectedCellIndices[1]] != + null) + ) { + const transparentHeatmapData = updateHeatmapPlotData(heatmapData[0], { + opacity: 1, + }); + setHeatmapData([transparentHeatmapData]); + props.onHeatmapCellSelected(undefined); + } else { + const transparentHeatmapData = updateHeatmapPlotData(heatmapData[0], { + opacity: 0.3, + }); + + const selectedHeatmapData = getSelectedHeatmapCellPlotData( + heatmapData[0], + selectedCellIndices[1], + selectedCellIndices[0] + ); + setHeatmapData([transparentHeatmapData, ...selectedHeatmapData]); + + const selectedEndDate = moment( + //@ts-ignore + heatmapData[0].x[selectedCellIndices[1]], + HEATMAP_X_AXIS_DATE_FORMAT + ).valueOf(); + + const selectedStartDate = + selectedEndDate - + getHeatmapCellDateRangeInterval( + //@ts-ignore + heatmapData[0].x, + selectedCellIndices[1] + ); + props.onHeatmapCellSelected({ + dateRange: { + startDate: selectedStartDate, + endDate: selectedEndDate, + }, + entityValue: selectedEntity, + } as HeatmapCell); + } + } + }; + + const getHeatmapCellDateRangeInterval = ( + dates: string[], + index: number + ) => { + if (dates.length < 2) { + // if only less than 2 dates in X axis, it means the props.dateRange is too small. + // we can just use props.dateRange interval for heatmap cell + return props.dateRange.endDate - props.dateRange.startDate; + } + let prevIndex = index; + let nextIndex = index + 1; + if (nextIndex >= dates.length) { + nextIndex = index; + prevIndex = index - 1; + } + return ( + moment(dates[nextIndex], HEATMAP_X_AXIS_DATE_FORMAT).valueOf() - + moment(dates[prevIndex], HEATMAP_X_AXIS_DATE_FORMAT).valueOf() + ); + }; + + const getColorPaletteFlexItem = (hexCode: string) => { + return ( + + + + ); + }; + + const handleViewEntityOptionsChange = (selectedViewOptions: any[]) => { + props.onHeatmapCellSelected(undefined); + if (isEmpty(selectedViewOptions)) { + // when `clear` is hit for combo box + setCurrentViewOptions([COMBINED_OPTIONS.options[0]]); + const displayTopEntityNum = get(COMBINED_OPTIONS.options[0], 'value'); + + const updateHeatmapPlotData = getAnomaliesHeatmapData( + props.anomalies, + props.dateRange, + sortByFeildValue, + displayTopEntityNum + ); + setOriginalHeatmapData(updateHeatmapPlotData); + setHeatmapData(updateHeatmapPlotData); + setNumEntities(updateHeatmapPlotData[0].y.length); + setEntityViewOptions(getViewEntityOptions(updateHeatmapPlotData)); + return; + } + const nonCombinedOptions = [] as any[]; + for (let option of selectedViewOptions) { + if (currentViewOptions.includes(option)) { + if (!isCombinedViewEntityOption(option)) { + nonCombinedOptions.push(option); + } + continue; + } + if (isCombinedViewEntityOption(option)) { + // only allow 1 combined option + setCurrentViewOptions([option]); + const displayTopEntityNum = get(option, 'value'); + const updateHeatmapPlotData = getAnomaliesHeatmapData( + props.anomalies, + props.dateRange, + sortByFeildValue, + displayTopEntityNum + ); + setOriginalHeatmapData(updateHeatmapPlotData); + setHeatmapData(updateHeatmapPlotData); + setNumEntities(updateHeatmapPlotData[0].y.length); + setEntityViewOptions(getViewEntityOptions(updateHeatmapPlotData)); + return; + } else { + nonCombinedOptions.push(option); + } + } + setCurrentViewOptions(nonCombinedOptions); + + setNumEntities(nonCombinedOptions.length); + const selectedYs = nonCombinedOptions.map((option) => + get(option, 'label', '') + ); + + let selectedHeatmapData = filterHeatmapPlotDataByY( + originalHeatmapData[0], + selectedYs, + sortByFeildValue + ); + selectedHeatmapData.opacity = 1; + + setHeatmapData([selectedHeatmapData]); + }; + + const isCombinedViewEntityOption = (inputOption: any) => { + const combinedOptionsLabels = COMBINED_OPTIONS.options.map((option) => + get(option, 'label', '') + ); + return combinedOptionsLabels.includes(get(inputOption, 'label', '')); + }; + + const handleSortByFieldChange = (value: any) => { + setSortByFeildValue(value); + const sortedHeatmapData = sortHeatmapPlotData( + heatmapData[0], + value, + numEntities + ); + const updatedHeatmapData = updateHeatmapPlotData(sortedHeatmapData, { + opacity: 1, + }); + setHeatmapData([updatedHeatmapData]); + props.onHeatmapCellSelected(undefined); + }; + + return ( + + + + + + + + + + +

{props.title}

+
+
+
+ + + + + + + handleViewEntityOptionsChange(selectedOptions) + } + /> + + + handleSortByFieldChange(value)} + hasDividers + /> + + + + + + + + + + + Anomaly grade{' '} + + + + + + {euiPaletteWarm(5).map((hexCode) => { + return getColorPaletteFlexItem(hexCode); + })} + + + + + + + 0.0 (None) + + + + + (Critical) 1.0 + + + + + + + + + + + +
+ + +
+ {props.isLoading ? ( + + + + + + ) : ( + + )} +
+
+
+ {showAlertsFlyout ? ( + setShowAlertsFlyout(false)} + /> + ) : null} +
+ ); + } +); diff --git a/public/pages/AnomalyCharts/containers/AnomalyOccurrenceChart.tsx b/public/pages/AnomalyCharts/containers/AnomalyOccurrenceChart.tsx new file mode 100644 index 00000000..947066cd --- /dev/null +++ b/public/pages/AnomalyCharts/containers/AnomalyOccurrenceChart.tsx @@ -0,0 +1,121 @@ +/* + * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +import React from 'react'; +import { EuiBadge } from '@elastic/eui'; +import { get } from 'lodash'; +import ContentPanel from '../../../components/ContentPanel/ContentPanel'; +import { Monitor, Detector, DateRange } from '../../../models/interfaces'; +import { AnomalyDetailsChart } from './AnomalyDetailsChart'; +import { HeatmapCell } from './AnomalyHeatmapChart'; +import { filterWithHeatmapFilter } from '../../utils/anomalyResultUtils'; +import { getAnomalySummary } from '../utils/anomalyChartUtils'; + +interface AnomalyOccurrenceChartProps { + onDateRangeChange( + startDate: number, + endDate: number, + dateRangeOption?: string + ): void; + onZoomRangeChange(startDate: number, endDate: number): void; + title: string; + anomalies: any[]; + bucketizedAnomalies: boolean; + anomalySummary: any; + dateRange: DateRange; + isLoading: boolean; + showAlerts?: boolean; + anomalyGradeSeriesName: string; + confidenceSeriesName: string; + detectorId: string; + detectorName: string; + detector?: Detector; + detectorInterval?: number; + unit?: string; + monitor?: Monitor; + isHCDetector?: boolean; + selectedHeatmapCell?: HeatmapCell; +} + +export const AnomalyOccurrenceChart = React.memo( + (props: AnomalyOccurrenceChartProps) => { + const getAnomaliesForChart = () => { + if (props.isHCDetector) { + if (props.selectedHeatmapCell) { + return filterWithHeatmapFilter( + props.anomalies, + props.selectedHeatmapCell + ); + } else { + return []; + } + } else { + return props.anomalies; + } + }; + const getAnomalySummaryForChart = () => { + if (props.isHCDetector) { + if (props.selectedHeatmapCell) { + return getAnomalySummary( + filterWithHeatmapFilter(props.anomalies, props.selectedHeatmapCell) + ); + } else { + return []; + } + } else { + return props.anomalySummary; + } + }; + + const getDateRange = () => { + if (props.isHCDetector && props.selectedHeatmapCell) { + return props.selectedHeatmapCell.dateRange; + } + return props.dateRange; + }; + return ( + + + {props.isHCDetector && props.selectedHeatmapCell === undefined ? ( + + {'Click on an anomaly entity to view data'} + + ) : null} + + ); + } +); diff --git a/public/pages/AnomalyCharts/containers/FeatureBreakDown.tsx b/public/pages/AnomalyCharts/containers/FeatureBreakDown.tsx index a09321f0..a0b8b64e 100644 --- a/public/pages/AnomalyCharts/containers/FeatureBreakDown.tsx +++ b/public/pages/AnomalyCharts/containers/FeatureBreakDown.tsx @@ -14,7 +14,7 @@ */ import React from 'react'; -import { get } from 'lodash'; +import { get, isEmpty } from 'lodash'; import { EuiFlexItem, EuiFlexGroup, @@ -29,10 +29,13 @@ import { Anomalies, DateRange, FEATURE_TYPE, + EntityData, } from '../../../models/interfaces'; import { NoFeaturePrompt } from '../components/FeatureChart/NoFeaturePrompt'; import { focusOnFeatureAccordion } from '../../EditFeatures/utils/helpers'; import moment from 'moment'; +import { HeatmapCell } from './AnomalyHeatmapChart'; +import { filterWithHeatmapFilter } from '../../utils/anomalyResultUtils'; interface FeatureBreakDownProps { title?: string; @@ -45,9 +48,68 @@ interface FeatureBreakDownProps { showFeatureMissingDataPointAnnotation?: boolean; rawAnomalyResults?: Anomalies; isFeatureDataMissing?: boolean; + isHCDetector?: boolean; + selectedHeatmapCell?: HeatmapCell; } export const FeatureBreakDown = React.memo((props: FeatureBreakDownProps) => { + const getFeatureDataForChart = ( + anomaliesResult: Anomalies, + featureId: string + ) => { + const originalFeatureData = get( + anomaliesResult, + `featureData.${featureId}`, + [] + ); + if (props.isHCDetector) { + if (props.selectedHeatmapCell) { + const anomaliesFound = get(anomaliesResult, 'anomalies', []); + const filteredFeatureData = []; + for (let i = 0; i < anomaliesFound.length; i++) { + const currentAnomalyData = anomaliesResult.anomalies[i]; + if ( + !isEmpty(get(currentAnomalyData, 'entity', [] as EntityData[])) && + get(currentAnomalyData, 'entity', [] as EntityData[])[0].value === + props.selectedHeatmapCell.entityValue && + get(currentAnomalyData, 'plotTime', 0) >= + props.selectedHeatmapCell.dateRange.startDate && + get(currentAnomalyData, 'plotTime', 0) <= + props.selectedHeatmapCell.dateRange.endDate + ) { + filteredFeatureData.push(originalFeatureData[i]); + } + } + return filteredFeatureData; + } else { + return []; + } + } else { + return originalFeatureData; + } + }; + const getAnnotationData = () => { + if (props.isHCDetector) { + if (props.selectedHeatmapCell) { + return filterWithHeatmapFilter( + props.annotations, + props.selectedHeatmapCell, + true, + 'coordinates.x0' + ); + } else { + return []; + } + } else { + return props.annotations; + } + }; + const getDateRange = () => { + if (props.isHCDetector && props.selectedHeatmapCell) { + return props.selectedHeatmapCell.dateRange; + } + return props.dateRange; + }; return ( {props.title ? ( @@ -77,19 +139,18 @@ export const FeatureBreakDown = React.memo((props: FeatureBreakDownProps) => { { props.showFeatureMissingDataPointAnnotation } detectorEnabledTime={props.detector.enabledTime} + titlePrefix={ + props.selectedHeatmapCell + ? props.selectedHeatmapCell.entityValue + : undefined + } /> diff --git a/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx b/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx index 9b526179..6cb7da8b 100644 --- a/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx +++ b/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx @@ -35,6 +35,19 @@ const anomalies = [ plotTime: initialStartTime.add(90, 'seconds').valueOf(), }, ]; +const anomaliesResult = { + anomalies: anomalies, + featureData: { + testFeatureId: [ + { + data: 10, + endTime: anomalies[0].endTime, + startTime: anomalies[0].startTime, + plotTime: anomalies[0].plotTime, + }, + ], + }, +}; const renderDataFilter = () => ({ ...render( @@ -46,7 +59,7 @@ const renderDataFilter = () => ({ dataTypes: { keyword: ['cityName.keyword'], integer: ['age'], - text: ['cityName'], + text: ['cityName'], }, }, })} @@ -55,8 +68,7 @@ const renderDataFilter = () => ({ onDateRangeChange={jest.fn()} onZoomRangeChange={jest.fn()} title="test" - anomalies={anomalies} - atomicAnomalies={true} + bucketizedAnomalies={true} anomalySummary={undefined} dateRange={dateRange} isLoading={false} @@ -64,7 +76,7 @@ const renderDataFilter = () => ({ confidenceSeriesName="confidence" detectorId="testDetectorId" detectorName="testDetectorName" - annotations={[]} + anomaliesResult={anomaliesResult} /> ), diff --git a/public/pages/AnomalyCharts/containers/__tests__/FeatureBreakDown.test.tsx b/public/pages/AnomalyCharts/containers/__tests__/FeatureBreakDown.test.tsx index 223973e4..fe1f5a24 100644 --- a/public/pages/AnomalyCharts/containers/__tests__/FeatureBreakDown.test.tsx +++ b/public/pages/AnomalyCharts/containers/__tests__/FeatureBreakDown.test.tsx @@ -15,19 +15,18 @@ import React from 'react'; import { render } from '@testing-library/react'; -import moment from 'moment'; import { getRandomDetector } from '../../../../redux/reducers/__tests__/utils'; import { FeatureBreakDown } from '../FeatureBreakDown'; import { FeatureAggregationData } from 'public/models/interfaces'; describe(' spec', () => { const dateRange = { - startDate: moment(1587431440000), - endDate: moment(1587456780000), + startDate: 1587431440000, + endDate: 1587456780000, }; const detector = getRandomDetector(false); let featureData: { [key: string]: FeatureAggregationData[] } = {}; - detector.featureAttributes.forEach(feature => { + detector.featureAttributes.forEach((feature) => { if (feature.featureId) { featureData[feature.featureId] = [ { diff --git a/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts b/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts index 28c53620..2ebcac57 100644 --- a/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts +++ b/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts @@ -13,65 +13,33 @@ * permissions and limitations under the License. */ -import { get } from 'lodash'; +import { cloneDeep, get, isEmpty, orderBy } from 'lodash'; import { DateRange, Detector, MonitorAlert, AnomalySummary, + EntityData, } from '../../../models/interfaces'; import { dateFormatter, minuteDateFormatter } from '../../utils/helpers'; import { RectAnnotationDatum } from '@elastic/charts'; import { DEFAULT_ANOMALY_SUMMARY } from './constants'; - -export const getAlertsQuery = (monitorId: string, startTime: number) => { - return { - index: '.opendistro-alerting-alert*', - size: 1000, - rawQuery: { - aggregations: { - total_alerts: { - value_count: { - field: 'monitor_id', - }, - }, - }, - query: { - bool: { - filter: [ - { - term: { - monitor_id: monitorId, - }, - }, - { - range: { - start_time: { - gte: startTime, - format: 'epoch_millis', - }, - }, - }, - ], - }, - }, - sort: [{ start_time: { order: 'desc' } }], - }, - }; -}; +import { Datum, PlotData } from 'plotly.js'; +import moment, { Moment } from 'moment'; +import { calculateTimeWindowsWithMaxDataPoints } from '../../utils/anomalyResultUtils'; export const convertAlerts = (response: any): MonitorAlert[] => { - const hits = get(response, 'data.response.hits.hits', []); - return hits.map((alert: any) => { + const alerts = get(response, 'data.response.alerts', []); + return alerts.map((alert: any) => { return { - monitorName: get(alert, '_source.monitor_name'), - triggerName: get(alert, '_source.trigger_name'), - severity: get(alert, '_source.severity'), - state: get(alert, '_source.state'), - error: get(alert, '_source.error_message'), - startTime: get(alert, '_source.start_time'), - endTime: get(alert, '_source.end_time'), - acknowledgedTime: get(alert, '_source.acknowledged_time'), + monitorName: get(alert, 'monitor_name'), + triggerName: get(alert, 'trigger_name'), + severity: get(alert, 'severity'), + state: get(alert, 'state'), + error: get(alert, 'error_message'), + startTime: get(alert, 'start_time'), + endTime: get(alert, 'end_time'), + acknowledgedTime: get(alert, 'acknowledged_time'), }; }); }; @@ -108,22 +76,24 @@ export const getAnomalySummary = (totalAnomalies: any[]): AnomalySummary => { if (totalAnomalies == undefined || totalAnomalies.length === 0) { return DEFAULT_ANOMALY_SUMMARY; } - const anomalies = totalAnomalies.filter(anomaly => anomaly.anomalyGrade > 0); + const anomalies = totalAnomalies.filter( + (anomaly) => anomaly.anomalyGrade > 0 + ); const maxConfidence = Math.max( - ...anomalies.map(anomaly => anomaly.confidence), + ...anomalies.map((anomaly) => anomaly.confidence), 0.0 ); const minConfidence = Math.min( - ...anomalies.map(anomaly => anomaly.confidence), + ...anomalies.map((anomaly) => anomaly.confidence), 1.0 ); const maxAnomalyGrade = Math.max( - ...anomalies.map(anomaly => anomaly.anomalyGrade), + ...anomalies.map((anomaly) => anomaly.anomalyGrade), 0.0 ); const minAnomalyGrade = Math.min( - ...anomalies.map(anomaly => anomaly.anomalyGrade), + ...anomalies.map((anomaly) => anomaly.anomalyGrade), 1.0 ); @@ -146,7 +116,13 @@ export const disabledHistoryAnnotations = ( dateRange: DateRange, detector?: Detector ): RectAnnotationDatum[] => { - if (!detector || !detector.disabledTime) { + if ( + !detector || + !detector.disabledTime || + detector.disabledTime > dateRange.endDate.valueOf() || + !detector.enabledTime || + detector.enabledTime < dateRange.startDate.valueOf() + ) { return []; } const startTime = detector.disabledTime; @@ -174,3 +150,281 @@ export const disabledHistoryAnnotations = ( }, ]; }; + +export const ANOMALY_HEATMAP_COLORSCALE = [ + [0, '#F2F2F2'], + [0.2, '#F2F2F2'], + [0.2, '#F7E0B8'], + [0.4, '#F7E0B8'], + [0.4, '#F2C596'], + [0.6, '#F2C596'], + [0.6, '#ECA976'], + [0.8, '#ECA976'], + [0.8, '#E78D5B'], + [1, '#E8664C'], +]; + +export enum AnomalyHeatmapSortType { + SEVERITY = 'by_severity', + OCCURRENCES = 'by_occurrences', +} + +const getColorForValue = (value: number) => { + if ( + value >= + ANOMALY_HEATMAP_COLORSCALE[ANOMALY_HEATMAP_COLORSCALE.length - 1][0] + ) { + return ANOMALY_HEATMAP_COLORSCALE[ANOMALY_HEATMAP_COLORSCALE.length - 1][1]; + } + + if (value <= ANOMALY_HEATMAP_COLORSCALE[0][0]) { + return ANOMALY_HEATMAP_COLORSCALE[0][1]; + } + + for (let i = 0; i < ANOMALY_HEATMAP_COLORSCALE.length - 1; i++) { + if ( + value >= ANOMALY_HEATMAP_COLORSCALE[i][0] && + value < ANOMALY_HEATMAP_COLORSCALE[i + 1][0] + ) { + return ANOMALY_HEATMAP_COLORSCALE[i + 1][1]; + } + } +}; + +const NUM_CELLS = 20; + +export const HEATMAP_X_AXIS_DATE_FORMAT = 'MM-DD HH:mm YYYY'; + +const buildBlankStringWithLength = (length: number) => { + let result = ''; + for (let i = 0; i < length; i++) { + result += ' '; + } + return result; +}; + +export const getAnomaliesHeatmapData = ( + anomalies: any[], + dateRange: DateRange, + sortType: AnomalyHeatmapSortType = AnomalyHeatmapSortType.SEVERITY, + displayTopNum: number +): PlotData[] => { + const entityAnomaliesMap = getEntityAnomaliesMap(anomalies); + if (isEmpty(entityAnomaliesMap)) { + // put placeholder data so that heatmap won't look empty + for (let i = 0; i < displayTopNum; i++) { + const blankStrValue = buildBlankStringWithLength(i); + entityAnomaliesMap.set(blankStrValue, []); + } + } + + const entityValues = [] as string[]; + const maxAnomalyGrades = [] as any[]; + const numAnomalyGrades = [] as any[]; + + const timeWindows = calculateTimeWindowsWithMaxDataPoints( + NUM_CELLS, + dateRange + ); + + entityAnomaliesMap.forEach((entityAnomalies, entity) => { + const maxAnomalyGradesForEntity = [] as number[]; + const numAnomalyGradesForEntity = [] as number[]; + entityValues.push(entity); + timeWindows.forEach((timeWindow) => { + const anomaliesInWindow = entityAnomalies.filter( + (anomaly) => + get(anomaly, 'plotTime', 0) <= timeWindow.endDate && + get(anomaly, 'plotTime', 0) >= timeWindow.startDate + ); + const entityAnomalyGrades = anomaliesInWindow.map((anomaly) => + get(anomaly, 'anomalyGrade', 0) + ); + if (!isEmpty(entityAnomalyGrades)) { + maxAnomalyGradesForEntity.push(Math.max(...entityAnomalyGrades)); + numAnomalyGradesForEntity.push( + entityAnomalyGrades.filter((anomalyGrade) => anomalyGrade > 0).length + ); + } else { + maxAnomalyGradesForEntity.push(0); + numAnomalyGradesForEntity.push(0); + } + }); + + maxAnomalyGrades.push(maxAnomalyGradesForEntity); + numAnomalyGrades.push(numAnomalyGradesForEntity); + }); + + const plotTimes = timeWindows.map((timeWindow) => timeWindow.endDate); + const plotData = + //@ts-ignore + { + x: plotTimes.map((timestamp) => + moment(timestamp).format(HEATMAP_X_AXIS_DATE_FORMAT) + ), + y: entityValues, + z: maxAnomalyGrades, + colorscale: ANOMALY_HEATMAP_COLORSCALE, + //@ts-ignore + zmin: 0, + zmax: 1, + type: 'heatmap', + showscale: false, + xgap: 2, + ygap: 2, + opacity: 1, + text: numAnomalyGrades, + hovertemplate: + 'Time: %{x}
' + + 'Max anomaly grade: %{z}
' + + 'Anomaly occurrences: %{text}' + + '', + } as PlotData; + const resultPlotData = sortHeatmapPlotData(plotData, sortType, displayTopNum); + return [resultPlotData]; +}; + +const getEntityAnomaliesMap = (anomalies: any[]): Map => { + const entityAnomaliesMap = new Map(); + anomalies.forEach((anomaly) => { + const entity = get(anomaly, 'entity', [] as EntityData[]); + if (isEmpty(entity)) { + return; + } + const entityValue = entity[0].value; + let singleEntityAnomalies = []; + if (entityAnomaliesMap.has(entityValue)) { + //@ts-ignore + singleEntityAnomalies = entityAnomaliesMap.get(entityValue); + } + singleEntityAnomalies.push(anomaly); + entityAnomaliesMap.set(entityValue, singleEntityAnomalies); + }); + return entityAnomaliesMap; +}; + +export const filterHeatmapPlotDataByY = ( + heatmapData: PlotData, + selectedYs: Datum[], + sortType: AnomalyHeatmapSortType +) => { + const originalYs = cloneDeep(heatmapData.y); + const originalZs = cloneDeep(heatmapData.z); + const originalTexts = cloneDeep(heatmapData.text); + const resultYs = []; + const resultZs = []; + const resultTexts = []; + for (let i = 0; i < originalYs.length; i++) { + //@ts-ignore + if (selectedYs.includes(originalYs[i])) { + resultYs.push(originalYs[i]); + resultZs.push(originalZs[i]); + resultTexts.push(originalTexts[i]); + } + } + const updateHeatmapPlotData = { + ...cloneDeep(heatmapData), + y: resultYs, + z: resultZs, + text: resultTexts, + } as PlotData; + return sortHeatmapPlotData( + updateHeatmapPlotData, + sortType, + selectedYs.length + ); +}; + +export const sortHeatmapPlotData = ( + heatmapData: PlotData, + sortType: AnomalyHeatmapSortType, + topNum: number +) => { + const originalYs = cloneDeep(heatmapData.y); + const originalZs = cloneDeep(heatmapData.z); + const originalTexts = cloneDeep(heatmapData.text); + const originalValuesToSort = + sortType === AnomalyHeatmapSortType.SEVERITY + ? cloneDeep(originalZs) + : cloneDeep(originalTexts); + const funcToAggregate = + sortType === AnomalyHeatmapSortType.SEVERITY + ? (a: number, b: number) => { + return Math.max(a, b); + } + : (a: number, b: number) => { + return a + b; + }; + const yIndicesToSort = [] as object[]; + for (let i = 0; i < originalYs.length; i++) { + yIndicesToSort.push({ + index: i, + //@ts-ignore + value: originalValuesToSort[i].reduce(funcToAggregate), + }); + } + const sortedYIndices = orderBy(yIndicesToSort, ['value'], 'desc').slice( + 0, + topNum + ); + const resultYs = [] as any[]; + const resultZs = [] as any[]; + const resultTexts = [] as any[]; + for (let i = sortedYIndices.length - 1; i >= 0; i--) { + const index = get(sortedYIndices[i], 'index', 0); + resultYs.push(originalYs[index]); + resultZs.push(originalZs[index]); + resultTexts.push(originalTexts[index]); + } + return { + ...cloneDeep(heatmapData), + y: resultYs, + z: resultZs, + text: resultTexts, + } as PlotData; +}; + +export const updateHeatmapPlotData = (heatmapData: PlotData, update: any) => { + return { + ...cloneDeep(heatmapData), + ...update, + } as PlotData; +}; + +export const getSelectedHeatmapCellPlotData = ( + heatmapData: PlotData, + selectedX: number, + selectedY: number +) => { + const originalZ = cloneDeep(heatmapData.z); + const selectedZData = []; + //@ts-ignore + const selectedValue = originalZ[selectedY][selectedX]; + for (let i = 0; i < originalZ.length; i++) { + const row = []; + //@ts-ignore + for (let j = 0; j < originalZ[0].length; j++) { + if (i === selectedY && j === selectedX) { + row.push(selectedValue); + } else { + row.push(null); + } + } + selectedZData.push(row); + } + const colorForCell = getColorForValue(selectedValue); + //@ts-ignore + return [ + { + ...cloneDeep(heatmapData), + z: selectedZData, + colorscale: [ + [0, colorForCell], + [1, colorForCell], + ], + opacity: 1, + hoverinfo: 'skip', + hovertemplate: null, + }, + ] as PlotData[]; +}; diff --git a/public/pages/Dashboard/Components/AnomaliesDistribution.tsx b/public/pages/Dashboard/Components/AnomaliesDistribution.tsx index 1a8df49a..252000c9 100644 --- a/public/pages/Dashboard/Components/AnomaliesDistribution.tsx +++ b/public/pages/Dashboard/Components/AnomaliesDistribution.tsx @@ -34,8 +34,8 @@ import { Datum } from '@elastic/charts'; import React from 'react'; import { TIME_RANGE_OPTIONS } from '../../Dashboard/utils/constants'; import { get, isEmpty } from 'lodash'; -import { searchES } from '../../../redux/reducers/elasticsearch'; import { AD_DOC_FIELDS } from '../../../../server/utils/constants'; +import { searchResults } from '../../../redux/reducers/anomalyResults'; export interface AnomaliesDistributionChartProps { selectedDetectors: DetectorListItem[]; } @@ -66,7 +66,7 @@ export const AnomaliesDistributionChart = ( setAnomalyResultsLoading(true); const distributionResult = await getAnomalyDistributionForDetectorsByTimeRange( - searchES, + searchResults, props.selectedDetectors, timeRange, dispatch, diff --git a/public/pages/Dashboard/Components/AnomaliesLiveChart.tsx b/public/pages/Dashboard/Components/AnomaliesLiveChart.tsx index ea69cc31..03b70c87 100644 --- a/public/pages/Dashboard/Components/AnomaliesLiveChart.tsx +++ b/public/pages/Dashboard/Components/AnomaliesLiveChart.tsx @@ -29,7 +29,6 @@ import { //@ts-ignore EuiStat, } from '@elastic/eui'; -import { searchES } from '../../../redux/reducers/elasticsearch'; import { get, isEmpty } from 'lodash'; import moment, { Moment } from 'moment'; import ContentPanel from '../../../components/ContentPanel/ContentPanel'; @@ -58,6 +57,7 @@ import { getLatestAnomalyResultsByTimeRange, } from '../utils/utils'; import { MAX_ANOMALIES, SPACE_STR } from '../../../utils/constants'; +import { searchResults } from '../../../redux/reducers/anomalyResults'; export interface AnomaliesLiveChartProps { selectedDetectors: DetectorListItem[]; @@ -101,7 +101,7 @@ export const AnomaliesLiveChart = (props: AnomaliesLiveChartProps) => { let latestSingleLiveAnomalyResult = [] as any[]; try { latestSingleLiveAnomalyResult = await getLatestAnomalyResultsByTimeRange( - searchES, + searchResults, '30m', dispatch, -1, @@ -120,7 +120,7 @@ export const AnomaliesLiveChart = (props: AnomaliesLiveChartProps) => { // get anomalies(anomaly_grade>0) in last 30mins const latestLiveAnomalyResult = await getLatestAnomalyResultsForDetectorsByTimeRange( - searchES, + searchResults, props.selectedDetectors, '30m', dispatch, diff --git a/public/pages/Dashboard/utils/utils.tsx b/public/pages/Dashboard/utils/utils.tsx index 8f2b5e6c..7dae7acf 100644 --- a/public/pages/Dashboard/utils/utils.tsx +++ b/public/pages/Dashboard/utils/utils.tsx @@ -392,9 +392,6 @@ export const buildGetAnomalyResultQueryByRange = ( checkLastIndexOnly: boolean ) => { return { - index: checkLastIndexOnly - ? ANOMALY_RESULT_INDEX - : `${ANOMALY_RESULT_INDEX}*`, size: size, from: from, query: { @@ -453,6 +450,7 @@ export const getLatestAnomalyResultsByTimeRange = async ( ) ) ); + const searchAnomalyResponse = searchResponse.data.response; const numHits = get(searchAnomalyResponse, 'hits.total.value', 0); diff --git a/public/pages/DetectorResults/containers/AnomalyHistory.tsx b/public/pages/DetectorResults/containers/AnomalyHistory.tsx index 9b79b8b5..709fc615 100644 --- a/public/pages/DetectorResults/containers/AnomalyHistory.tsx +++ b/public/pages/DetectorResults/containers/AnomalyHistory.tsx @@ -14,12 +14,15 @@ */ import React, { useState, useEffect, useCallback, Fragment } from 'react'; + +import { isEmpty, get } from 'lodash'; import { EuiFlexItem, EuiFlexGroup, EuiTabs, EuiTab, EuiLoadingSpinner, + EuiSpacer, } from '@elastic/eui'; import moment from 'moment'; import { useDispatch } from 'react-redux'; @@ -30,6 +33,7 @@ import { DateRange, AnomalySummary, Anomalies, + FeatureAggregationData, } from '../../../models/interfaces'; import { filterWithDateRange, @@ -40,18 +44,20 @@ import { parsePureAnomalies, buildParamsForGetAnomalyResultsWithDateRange, FEATURE_DATA_CHECK_WINDOW_OFFSET, + filterWithHeatmapFilter, } from '../../utils/anomalyResultUtils'; -import { get } from 'lodash'; import { AnomalyResultsTable } from './AnomalyResultsTable'; import { AnomaliesChart } from '../../AnomalyCharts/containers/AnomaliesChart'; import { FeatureBreakDown } from '../../AnomalyCharts/containers/FeatureBreakDown'; import { minuteDateFormatter } from '../../utils/helpers'; import { ANOMALY_HISTORY_TABS } from '../utils/constants'; -import { searchES } from '../../../redux/reducers/elasticsearch'; +import { searchResults } from '../../../redux/reducers/anomalyResults'; import { MIN_IN_MILLI_SECS } from '../../../../server/utils/constants'; import { INITIAL_ANOMALY_SUMMARY } from '../../AnomalyCharts/utils/constants'; import { MAX_ANOMALIES } from '../../../utils/constants'; import { getDetectorResults } from '../../../redux/reducers/anomalyResults'; +import { AnomalyOccurrenceChart } from '../../AnomalyCharts/containers/AnomalyOccurrenceChart'; +import { HeatmapCell } from '../../AnomalyCharts/containers/AnomalyHeatmapChart'; interface AnomalyHistoryProps { detector: Detector; @@ -75,7 +81,7 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { endDate: initialEndDate.valueOf(), }); const [selectedTabId, setSelectedTabId] = useState( - ANOMALY_HISTORY_TABS.FEATURE_BREAKDOWN + ANOMALY_HISTORY_TABS.ANOMALY_OCCURRENCE ); const [isLoadingAnomalyResults, setIsLoadingAnomalyResults] = useState< @@ -89,6 +95,11 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { AnomalySummary >(INITIAL_ANOMALY_SUMMARY); + const [selectedHeatmapCell, setSelectedHeatmapCell] = useState(); + + const detectorCategoryField = get(props.detector, 'categoryField', []); + const isHCDetector = !isEmpty(detectorCategoryField); + useEffect(() => { // We load at most 10k AD result data points for one call. If user choose // a big time range which may have more than 10k AD results, will use bucket @@ -97,7 +108,7 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { try { setIsLoadingAnomalyResults(true); const anomalySummaryResult = await dispatch( - searchES( + searchResults( getAnomalySummaryQuery( dateRange.startDate, dateRange.endDate, @@ -105,10 +116,11 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { ) ) ); + setPureAnomalies(parsePureAnomalies(anomalySummaryResult)); setBucketizedAnomalySummary(parseAnomalySummary(anomalySummaryResult)); const result = await dispatch( - searchES( + searchResults( getBucketizedAnomalyResultsQuery( dateRange.startDate, dateRange.endDate, @@ -125,10 +137,11 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { ); } finally { setIsLoadingAnomalyResults(false); - fetchRawAnomalyResults(false); } } + fetchRawAnomalyResults(isHCDetector); + if ( dateRange.endDate - dateRange.startDate > detectorInterval * MIN_IN_MILLI_SECS * MAX_ANOMALIES @@ -136,7 +149,6 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { getBucketizedAnomalyResults(); } else { setBucketizedAnomalyResults(undefined); - fetchRawAnomalyResults(true); } }, [dateRange]); @@ -146,10 +158,8 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { 1 ); - const fetchRawAnomalyResults = async ( - shouldSetAtomicAnomalyResults: boolean - ) => { - if (shouldSetAtomicAnomalyResults) { + const fetchRawAnomalyResults = async (showLoading: boolean) => { + if (showLoading) { setIsLoading(true); } @@ -164,34 +174,65 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { const detectorResultResponse = await dispatch( getDetectorResults(props.detector.id, params) ); - const anomaliesData = get(detectorResultResponse, 'data.response', []); - - if (shouldSetAtomicAnomalyResults) { - setAtomicAnomalyResults({ - anomalies: get(anomaliesData, 'results', []), - featureData: get(anomaliesData, 'featureResults', []), - }); - } - setRawAnomalyResults({ - anomalies: get(anomaliesData, 'results', []), - featureData: get(anomaliesData, 'featureResults', []), - }); + const rawAnomaliesData = get(detectorResultResponse, 'data.response', []); + const rawAnomaliesResult = { + anomalies: get(rawAnomaliesData, 'results', []), + featureData: get(rawAnomaliesData, 'featureResults', []), + } as Anomalies; + setAtomicAnomalyResults(rawAnomaliesResult); + setRawAnomalyResults(rawAnomaliesResult); + setHCDetectorAnomalyResults(getAnomalyResultForHC(rawAnomaliesResult)); } catch (err) { console.error( `Failed to get atomic anomaly results for ${props.detector.id}`, err ); } finally { - if (shouldSetAtomicAnomalyResults) { + if (showLoading) { setIsLoading(false); } } }; + const getAnomalyResultForHC = (rawAnomalyResults: Anomalies) => { + const resultAnomaly = rawAnomalyResults.anomalies.filter( + (anomaly) => get(anomaly, 'anomalyGrade', 0) > 0 + ); + + const anomaliesFeatureData = resultAnomaly.map( + (anomaly) => anomaly.features + ); + + const resultAnomalyFeatureData: { + [key: string]: FeatureAggregationData[]; + } = {}; + anomaliesFeatureData.forEach((anomalyFeatureData) => { + if (anomalyFeatureData) { + for (const [featureId, featureAggData] of Object.entries( + anomalyFeatureData + )) { + if (!resultAnomalyFeatureData[featureId]) { + resultAnomalyFeatureData[featureId] = []; + } + resultAnomalyFeatureData[featureId].push(featureAggData); + } + } + }); + return { + anomalies: resultAnomaly, + featureData: resultAnomalyFeatureData, + } as Anomalies; + }; + const [atomicAnomalyResults, setAtomicAnomalyResults] = useState(); const [rawAnomalyResults, setRawAnomalyResults] = useState(); + const [hcDetectorAnomalyResults, setHCDetectorAnomalyResults] = useState< + Anomalies + >(); - const anomalyResults = bucketizedAnomalyResults + const anomalyResults = isHCDetector + ? hcDetectorAnomalyResults + : bucketizedAnomalyResults ? bucketizedAnomalyResults : atomicAnomalyResults; @@ -212,6 +253,10 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { }); }, []); + const handleHeatmapCellSelected = useCallback((heatmapCell: HeatmapCell) => { + setSelectedHeatmapCell(heatmapCell); + }, []); + const annotations = anomalyResults ? get(anomalyResults, 'anomalies', []) //@ts-ignore @@ -226,18 +271,19 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { } between ${minuteDateFormatter( anomaly.startTime )} and ${minuteDateFormatter(anomaly.endTime)}`, + entity: get(anomaly, 'entity', []), })) : []; const tabs = [ { - id: ANOMALY_HISTORY_TABS.FEATURE_BREAKDOWN, - name: 'Feature breakdown', + id: ANOMALY_HISTORY_TABS.ANOMALY_OCCURRENCE, + name: 'Anomaly occurrence', disabled: false, }, { - id: ANOMALY_HISTORY_TABS.ANOMALY_OCCURRENCE, - name: 'Anomaly occurrence', + id: ANOMALY_HISTORY_TABS.FEATURE_BREAKDOWN, + name: 'Feature breakdown', disabled: false, }, ]; @@ -266,7 +312,6 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { dateRange={dateRange} onDateRangeChange={handleDateRangeChange} onZoomRangeChange={handleZoomChange} - anomalies={anomalyResults ? anomalyResults.anomalies : []} bucketizedAnomalies={bucketizedAnomalyResults !== undefined} anomalySummary={bucketizedAnomalySummary} isLoading={isLoading || isLoadingAnomalyResults} @@ -282,6 +327,11 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { )} unit={get(props.detector, 'detectionInterval.period.unit')} monitor={props.monitor} + isHCDetector={isHCDetector} + detectorCategoryField={detectorCategoryField} + onHeatmapCellSelected={handleHeatmapCellSelected} + selectedHeatmapCell={selectedHeatmapCell} + anomaliesResult={anomalyResults} > {renderTabs()} @@ -296,7 +346,7 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { ) : (
- {selectedTabId === 'featureBreakdown' ? ( + {selectedTabId === ANOMALY_HISTORY_TABS.FEATURE_BREAKDOWN ? ( { isLoading={isLoading} dateRange={zoomRange} featureDataSeriesName="Feature output" - showFeatureMissingDataPointAnnotation={props.detector.enabled} + showFeatureMissingDataPointAnnotation={ + props.detector.enabled && + // disable showing missing feature alert when it is HC Detector + !isHCDetector + } isFeatureDataMissing={props.isFeatureDataMissing} + isHCDetector={isHCDetector} + selectedHeatmapCell={selectedHeatmapCell} /> ) : ( - + [ + isHCDetector + ? [ + , + , + ] + : null, + , + ] )}
)} diff --git a/public/pages/DetectorResults/containers/AnomalyResults.tsx b/public/pages/DetectorResults/containers/AnomalyResults.tsx index ded1707b..b30ded29 100644 --- a/public/pages/DetectorResults/containers/AnomalyResults.tsx +++ b/public/pages/DetectorResults/containers/AnomalyResults.tsx @@ -27,7 +27,7 @@ import { EuiText, EuiLoadingSpinner, } from '@elastic/eui'; -import { get } from 'lodash'; +import { get, isEmpty } from 'lodash'; import React, { useEffect, Fragment, useState } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { RouteComponentProps } from 'react-router'; @@ -199,6 +199,8 @@ export function AnomalyResults(props: AnomalyResultsProps) { isDetectorMissingData != undefined && !isDetectorMissingData; + const isHCDetector = !isEmpty(get(detector, 'categoryField', [])); + const checkLatestFeatureDataPoints = async () => { const featureDataPointsRange = { startDate: Math.max( @@ -266,7 +268,8 @@ export function AnomalyResults(props: AnomalyResultsProps) { return get( getFeatureDataMissingMessageAndActionItem( featureMissingSeverity, - featureNamesAtHighSev + featureNamesAtHighSev, + !isEmpty(detector.categoryField) ), 'message', '' @@ -354,7 +357,8 @@ export function AnomalyResults(props: AnomalyResultsProps) { {get( getFeatureDataMissingMessageAndActionItem( featureMissingSeverity, - featureNamesAtHighSev + featureNamesAtHighSev, + !isEmpty(detector.categoryField) ), 'actionItem', '' @@ -401,7 +405,8 @@ export function AnomalyResults(props: AnomalyResultsProps) { ) : null} {isDetectorUpdated || - isDetectorMissingData || + // don't show miss feature callout for HC detector + (isDetectorMissingData && !isHCDetector) || isInitializingNormally || isInitOvertime || isDetectorFailed ? ( diff --git a/public/pages/DetectorResults/containers/AnomalyResultsTable.tsx b/public/pages/DetectorResults/containers/AnomalyResultsTable.tsx index 6c1d6415..7011565b 100644 --- a/public/pages/DetectorResults/containers/AnomalyResultsTable.tsx +++ b/public/pages/DetectorResults/containers/AnomalyResultsTable.tsx @@ -25,14 +25,20 @@ import React, { useEffect, useState } from 'react'; import chrome from 'ui/chrome'; import { SORT_DIRECTION } from '../../../../server/utils/constants'; import ContentPanel from '../../../components/ContentPanel/ContentPanel'; -import { staticColumn } from '../utils/tableUtils'; +import { + entityValueColumn, + ENTITY_VALUE_FIELD, + staticColumn, +} from '../utils/tableUtils'; import { ListControls } from '../components/ListControls/ListControls'; import { DetectorResultsQueryParams } from 'server/models/types'; import { AnomalyData } from '../../../models/interfaces'; import { getTitleWithCount } from '../../../utils/utils'; +import { HeatmapCell } from '../../AnomalyCharts/containers/AnomalyHeatmapChart'; interface AnomalyResultsTableProps { anomalies: AnomalyData[]; + isHCDetector?: boolean; } interface ListState { @@ -51,9 +57,9 @@ export function AnomalyResultsTable(props: AnomalyResultsTableProps) { sortField: 'startTime', }, }); - const [targetAnomalies, setTargetAnomalies] = useState([]); + const [targetAnomalies, setTargetAnomalies] = useState([] as any[]); const totalAnomalies = props.anomalies - ? props.anomalies.filter(anomaly => anomaly.anomalyGrade > 0) + ? props.anomalies.filter((anomaly) => anomaly.anomalyGrade > 0) : []; const sortFiledCompare = (field: string, sortDirection: SORT_DIRECTION) => { @@ -68,7 +74,14 @@ export function AnomalyResultsTable(props: AnomalyResultsTableProps) { useEffect(() => { const anomalies = props.anomalies - ? props.anomalies.filter(anomaly => anomaly.anomalyGrade > 0) + ? props.anomalies + .filter((anomaly) => anomaly.anomalyGrade > 0) + .map((anomaly) => { + return { + ...anomaly, + [ENTITY_VALUE_FIELD]: get(anomaly, 'entity[0].value'), + }; + }) : []; anomalies.sort( @@ -134,7 +147,15 @@ export function AnomalyResultsTable(props: AnomalyResultsTableProps) { { return DEFAULT_EMPTY_DATA; }; +export const ENTITY_VALUE_FIELD = 'entityValue'; + export const staticColumn = [ { field: 'startTime', @@ -57,3 +59,11 @@ export const staticColumn = [ dataType: 'number', }, ] as EuiBasicTableColumn[]; + +export const entityValueColumn = { + field: ENTITY_VALUE_FIELD, + name: 'Entity', + sortable: true, + truncateText: false, + dataType: 'number', +} as EuiBasicTableColumn; diff --git a/public/pages/EditFeatures/components/AggregationSelector/AggregationSelector.tsx b/public/pages/EditFeatures/components/AggregationSelector/AggregationSelector.tsx index fb8b6b58..1104d3c6 100644 --- a/public/pages/EditFeatures/components/AggregationSelector/AggregationSelector.tsx +++ b/public/pages/EditFeatures/components/AggregationSelector/AggregationSelector.tsx @@ -25,8 +25,9 @@ import { import { Field, FieldProps } from 'formik'; import { AGGREGATION_TYPES } from '../../utils/constants'; import { - required, + requiredSelectField, requiredNonEmptyArray, + requiredNonEmptyFieldSelected, isInvalid, getError, } from '../../../../utils/utils'; @@ -42,7 +43,7 @@ export const AggregationSelector = (props: AggregationSelectorProps) => { {({ field, form }: FieldProps) => ( { {...field} name={`featureList.${props.index}.aggregationBy`} options={AGGREGATION_TYPES} - onChange={e => { + onChange={(e) => { const currentValue = field.value; const aggregationOf = get( form, @@ -82,7 +83,7 @@ export const AggregationSelector = (props: AggregationSelectorProps) => { {({ field, form }: FieldProps) => ( { key={props.index} buttonContent={featureButtonContent(props.feature, props.index)} //@ts-ignore - buttonClassName="euiAccordionForm__button" - className="euiAccordionForm" + buttonClassName={ + props.index === 0 + ? 'euiAccordionForm__noTopPaddingButton' + : 'euiAccordionForm__button' + } + className="euiAccordion__noTopBorder" paddingSize="l" initialIsOpen={initialIsOpen} extraAction={deleteAction(props.onDelete)} @@ -118,7 +122,7 @@ export const FeatureAccordion = (props: FeatureAccordionProps) => { {({ field, form }: FieldProps) => ( { ? FEATURE_TYPE.SIMPLE : FEATURE_TYPE.CUSTOM } - onChange={e => { + onChange={(e) => { props.handleChange(e); if ( e.currentTarget.value === FEATURE_TYPE.CUSTOM && diff --git a/public/pages/EditFeatures/containers/EditFeatures.tsx b/public/pages/EditFeatures/containers/EditFeatures.tsx index 922dd2e4..fda610fb 100644 --- a/public/pages/EditFeatures/containers/EditFeatures.tsx +++ b/public/pages/EditFeatures/containers/EditFeatures.tsx @@ -188,7 +188,7 @@ export function EditFeatures(props: EditFeaturesProps) { diff --git a/public/pages/EditFeatures/containers/SampleAnomalies.tsx b/public/pages/EditFeatures/containers/SampleAnomalies.tsx index be0d462d..58dba756 100644 --- a/public/pages/EditFeatures/containers/SampleAnomalies.tsx +++ b/public/pages/EditFeatures/containers/SampleAnomalies.tsx @@ -14,42 +14,44 @@ */ import { - EuiPageBody, - EuiFlexItem, + EuiButton, + EuiCallOut, EuiFlexGroup, - EuiText, + EuiFlexItem, + EuiIcon, EuiLink, + EuiLoadingSpinner, EuiPage, - EuiButton, - EuiCallOut, + EuiPageBody, EuiSpacer, - EuiLoadingSpinner, - EuiIcon, + EuiText, } from '@elastic/eui'; +import { get, isEmpty } from 'lodash'; import moment from 'moment'; -import { get } from 'lodash'; -import React, { Fragment, useState, useCallback, useEffect } from 'react'; +import React, { Fragment, useCallback, useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { previewDetector } from '../../../redux/reducers/anomalies'; -import { AppState } from '../../../redux/reducers'; -import ContentPanel from '../../../components/ContentPanel/ContentPanel'; // @ts-ignore import { toastNotifications } from 'ui/notify'; -import { Detector, DateRange } from '../../../models/interfaces'; -import { - FeaturesFormikValues, - prepareDetector, -} from './utils/formikToFeatures'; +import ContentPanel from '../../../components/ContentPanel/ContentPanel'; +import { DateRange, Detector } from '../../../models/interfaces'; +import { AppState } from '../../../redux/reducers'; +import { previewDetector } from '../../../redux/reducers/anomalies'; import { AnomaliesChart } from '../../AnomalyCharts/containers/AnomaliesChart'; +import { HeatmapCell } from '../../AnomalyCharts/containers/AnomalyHeatmapChart'; import { FeatureBreakDown } from '../../AnomalyCharts/containers/FeatureBreakDown'; import { useHideSideNavBar } from '../../main/hooks/useHideSideNavBar'; import { generateAnomalyAnnotations } from '../../utils/anomalyResultUtils'; import { focusOnFirstWrongFeature } from '../utils/helpers'; +import { + FeaturesFormikValues, + prepareDetector, +} from './utils/formikToFeatures'; interface SampleAnomaliesProps { detector: Detector; featureList: FeaturesFormikValues[]; shingleSize: number; + categoryFields: string[]; errors: any; setFieldTouched: any; } @@ -74,6 +76,10 @@ export function SampleAnomalies(props: SampleAnomaliesProps) { endDate: initialEndDate.valueOf(), }); + const [selectedHeatmapCell, setSelectedHeatmapCell] = useState(); + + const isHCDetector = !isEmpty(get(newDetector, 'categoryField', [])); + useEffect(() => { if (!firstPreview) { getSampleAnomalies(); @@ -97,6 +103,10 @@ export function SampleAnomalies(props: SampleAnomaliesProps) { }); }, []); + const handleHeatmapCellSelected = useCallback((heatmapCell: HeatmapCell) => { + setSelectedHeatmapCell(heatmapCell); + }, []); + const anomaliesResult = useSelector( (state: AppState) => state.anomalies.anomaliesResult ); @@ -135,13 +145,16 @@ export function SampleAnomalies(props: SampleAnomaliesProps) { } const getSampleAnomalies = () => { + setSelectedHeatmapCell(undefined); try { const updatedDetector = prepareDetector( props.featureList, props.shingleSize, + props.categoryFields, newDetector, true ); + console.log('updatedDetector in SampleAnomalies', updatedDetector); setPreviewDone(false); setZoomRange({ ...dateRange }); setNewDetector(updatedDetector); @@ -172,8 +185,7 @@ export function SampleAnomalies(props: SampleAnomaliesProps) { href="https://opendistro.github.io/for-elasticsearch-docs/docs/ad/" target="_blank" > - Learn more - + Learn more @@ -217,13 +229,20 @@ export function SampleAnomalies(props: SampleAnomaliesProps) { title="Sample anomaly history" onDateRangeChange={handleDateRangeChange} onZoomRangeChange={handleZoomChange} - anomalies={anomaliesResult.anomalies} isLoading={isLoading} dateRange={dateRange} anomalyGradeSeriesName="Sample anomaly grade" confidenceSeriesName="Sample confidence" detectorId={props.detector.id} detectorName={props.detector.name} + isHCDetector={isHCDetector} + detectorCategoryField={newDetector.categoryField} + onHeatmapCellSelected={handleHeatmapCellSelected} + selectedHeatmapCell={selectedHeatmapCell} + newDetector={newDetector} + zoomRange={zoomRange} + anomaliesResult={anomaliesResult} + showAlerts={false} /> {isLoading ? ( @@ -235,7 +254,7 @@ export function SampleAnomalies(props: SampleAnomaliesProps) { - ) : ( + ) : isHCDetector ? null : ( { hasError = true; // @ts-ignore return { - featureName: 'Required', + featureName: 'You must enter a feature name.', }; } }); diff --git a/public/pages/createDetector/components/DataFilters/dataFilter.scss b/public/pages/createDetector/components/DataFilters/dataFilter.scss index 6cd9b749..527c496d 100644 --- a/public/pages/createDetector/components/DataFilters/dataFilter.scss +++ b/public/pages/createDetector/components/DataFilters/dataFilter.scss @@ -19,3 +19,11 @@ -ms-flex-negative: 0; flex-shrink: 0; } + +.euiAccordion__noTopBorder { + border-bottom: 1px solid #d3dae6; +} + +.euiAccordionForm__noTopPaddingButton { + padding: 0 16px 16px 0; +} diff --git a/public/pages/createDetector/containers/CreateDetector.tsx b/public/pages/createDetector/containers/CreateDetector.tsx index 30203d95..c30c0b32 100644 --- a/public/pages/createDetector/containers/CreateDetector.tsx +++ b/public/pages/createDetector/containers/CreateDetector.tsx @@ -44,7 +44,7 @@ import { import { getIndices } from '../../../redux/reducers/elasticsearch'; import { AppState } from '../../../redux/reducers'; import { BREADCRUMBS, MAX_DETECTORS } from '../../../utils/constants'; -import { getErrorMessage, validateName } from '../../../utils/utils'; +import { getErrorMessage, validateDetectorName } from '../../../utils/utils'; import { DetectorInfo } from '../components/DetectorInfo'; import { useFetchDetectorInfo } from '../hooks/useFetchDetectorInfo'; import { DataSource } from './DataSource/index'; @@ -193,7 +193,7 @@ export function CreateDetector(props: CreateADProps) { if (isEmpty(detectorName)) { throw 'Detector name cannot be empty'; } else { - const error = validateName(detectorName); + const error = validateDetectorName(detectorName); if (error) { throw error; } diff --git a/public/pages/utils/anomalyResultUtils.ts b/public/pages/utils/anomalyResultUtils.ts index acf5a13d..6b5858fc 100644 --- a/public/pages/utils/anomalyResultUtils.ts +++ b/public/pages/utils/anomalyResultUtils.ts @@ -13,33 +13,33 @@ * permissions and limitations under the License. */ +import { get, isEmpty, orderBy } from 'lodash'; +import moment from 'moment'; +import { Dispatch } from 'redux'; import { - SORT_DIRECTION, AD_DOC_FIELDS, MIN_IN_MILLI_SECS, + SORT_DIRECTION, } from '../../../server/utils/constants'; -import { getDetectorResults } from '../../redux/reducers/anomalyResults'; -import { getDetectorLiveResults } from '../../redux/reducers/liveAnomalyResults'; -import moment from 'moment'; -import { Dispatch } from 'redux'; -import { get, orderBy, isEmpty } from 'lodash'; +import { toFixedNumberForAnomaly } from '../../../server/utils/helpers'; import { + Anomalies, AnomalyData, - DateRange, AnomalySummary, - FeatureAggregationData, - Anomalies, + DateRange, Detector, + FeatureAggregationData, FeatureAttributes, } from '../../models/interfaces'; +import { getDetectorResults } from '../../redux/reducers/anomalyResults'; +import { getDetectorLiveResults } from '../../redux/reducers/liveAnomalyResults'; import { MAX_ANOMALIES, MISSING_FEATURE_DATA_SEVERITY, } from '../../utils/constants'; -import { minuteDateFormatter, dateFormatter } from './helpers'; -import { toFixedNumberForAnomaly } from '../../../server/utils/helpers'; -import { getFloorPlotTime } from '../Dashboard/utils/utils'; +import { HeatmapCell } from '../AnomalyCharts/containers/AnomalyHeatmapChart'; import { DETECTOR_INIT_FAILURES } from '../DetectorDetail/utils/constants'; +import { dateFormatter, minuteDateFormatter } from './helpers'; export const getQueryParamsForLiveAnomalyResults = ( detectionInterval: number, @@ -111,7 +111,7 @@ const calculateStep = (total: number): number => { return Math.ceil(total / MAX_DATA_POINTS); }; -const calculateSampleWindowsWithMaxDataPoints = ( +export const calculateTimeWindowsWithMaxDataPoints = ( maxDataPoints: number, dateRange: DateRange ): DateRange[] => { @@ -202,11 +202,15 @@ export const prepareDataForLiveChart = ( return anomalies; }; -export const prepareDataForChart = (data: any[], dateRange: DateRange) => { +export const prepareDataForChart = ( + data: any[], + dateRange: DateRange, + withoutPadding?: boolean +) => { let anomalies = []; if (data && data.length > 0) { anomalies = data.filter( - anomaly => + (anomaly) => anomaly.plotTime >= dateRange.startDate && anomaly.plotTime <= dateRange.endDate ); @@ -214,6 +218,10 @@ export const prepareDataForChart = (data: any[], dateRange: DateRange) => { anomalies = sampleMaxAnomalyGrade(anomalies); } } + if (withoutPadding) { + // just return result if padding/placeholder data is not needed + return anomalies; + } anomalies.push({ startTime: dateRange.startDate, endTime: dateRange.startDate, @@ -244,6 +252,7 @@ export const generateAnomalyAnnotations = (anomalies: any[]): any[] => { } between ${moment(anomaly.startTime).format( 'MM/DD/YY h:mm A' )} and ${moment(anomaly.endTime).format('MM/DD/YY h:mm A')}`, + entity: get(anomaly, 'entity', []), })); }; @@ -253,7 +262,7 @@ export const filterWithDateRange = ( timeField: string ) => { const anomalies = data - ? data.filter(item => { + ? data.filter((item) => { const time = get(item, `${timeField}`); return time && time >= dateRange.startDate && time <= dateRange.endDate; }) @@ -267,6 +276,7 @@ export const RETURNED_AD_RESULT_FIELDS = [ 'anomaly_grade', 'confidence', 'feature_data', + 'entity', ]; export const getAnomalySummaryQuery = ( @@ -275,71 +285,68 @@ export const getAnomalySummaryQuery = ( detectorId: string ) => { return { - index: '.opendistro-anomaly-results*', size: MAX_ANOMALIES, - rawQuery: { - query: { - bool: { - filter: [ - { - range: { - data_end_time: { - gte: startTime, - lte: endTime, - }, + query: { + bool: { + filter: [ + { + range: { + data_end_time: { + gte: startTime, + lte: endTime, }, }, - { - range: { - anomaly_grade: { - gt: 0, - }, - }, - }, - { - term: { - detector_id: detectorId, + }, + { + range: { + anomaly_grade: { + gt: 0, }, }, - ], - }, - }, - aggs: { - count_anomalies: { - value_count: { - field: 'anomaly_grade', }, - }, - max_confidence: { - max: { - field: 'confidence', + { + term: { + detector_id: detectorId, + }, }, + ], + }, + }, + aggs: { + count_anomalies: { + value_count: { + field: 'anomaly_grade', }, - min_confidence: { - min: { - field: 'confidence', - }, + }, + max_confidence: { + max: { + field: 'confidence', }, - max_anomaly_grade: { - max: { - field: 'anomaly_grade', - }, + }, + min_confidence: { + min: { + field: 'confidence', }, - min_anomaly_grade: { - min: { - field: 'anomaly_grade', - }, + }, + max_anomaly_grade: { + max: { + field: 'anomaly_grade', }, - max_data_end_time: { - max: { - field: 'data_end_time', - }, + }, + min_anomaly_grade: { + min: { + field: 'anomaly_grade', }, }, - _source: { - includes: RETURNED_AD_RESULT_FIELDS, + max_data_end_time: { + max: { + field: 'data_end_time', + }, }, }, + _source: { + includes: RETURNED_AD_RESULT_FIELDS, + }, }; }; @@ -353,49 +360,46 @@ export const getBucketizedAnomalyResultsQuery = ( (endTime - startTime) / (interval * MIN_IN_MILLI_SECS * MAX_DATA_POINTS) ); return { - index: '.opendistro-anomaly-results*', size: 0, - rawQuery: { - query: { - bool: { - filter: [ - { - range: { - data_end_time: { - gte: startTime, - lte: endTime, - }, + query: { + bool: { + filter: [ + { + range: { + data_end_time: { + gte: startTime, + lte: endTime, }, }, - { - term: { - detector_id: detectorId, - }, + }, + { + term: { + detector_id: detectorId, }, - ], - }, - }, - aggs: { - bucketized_anomaly_grade: { - date_histogram: { - field: 'data_end_time', - fixed_interval: `${fixedInterval}m`, }, - aggs: { - top_anomaly_hits: { - top_hits: { - sort: [ - { - anomaly_grade: { - order: 'desc', - }, + ], + }, + }, + aggs: { + bucketized_anomaly_grade: { + date_histogram: { + field: 'data_end_time', + fixed_interval: `${fixedInterval}m`, + }, + aggs: { + top_anomaly_hits: { + top_hits: { + sort: [ + { + anomaly_grade: { + order: 'desc', }, - ], - _source: { - includes: RETURNED_AD_RESULT_FIELDS, }, - size: 1, + ], + _source: { + includes: RETURNED_AD_RESULT_FIELDS, }, + size: 1, }, }, }, @@ -412,10 +416,13 @@ export const parseBucketizedAnomalyResults = (result: any): Anomalies => { ) as any[]; let anomalies = [] as AnomalyData[]; let featureData = {} as { [key: string]: FeatureAggregationData[] }; - rawAnomalies.forEach(item => { + rawAnomalies.forEach((item) => { if (get(item, 'top_anomaly_hits.hits.hits', []).length > 0) { const rawAnomaly = get(item, 'top_anomaly_hits.hits.hits.0._source'); - if (get(rawAnomaly, 'anomaly_grade') !== undefined) { + if ( + get(rawAnomaly, 'anomaly_grade') !== undefined && + get(rawAnomaly, 'feature_data', []).length > 0 + ) { anomalies.push({ anomalyGrade: toFixedNumberForAnomaly( get(rawAnomaly, 'anomaly_grade') @@ -424,10 +431,9 @@ export const parseBucketizedAnomalyResults = (result: any): Anomalies => { startTime: get(rawAnomaly, 'data_start_time'), endTime: get(rawAnomaly, 'data_end_time'), plotTime: get(rawAnomaly, 'data_end_time'), + entity: get(rawAnomaly, 'entity'), }); - } - if (get(rawAnomaly, 'feature_data', []).length > 0) { - get(rawAnomaly, 'feature_data', []).forEach(feature => { + get(rawAnomaly, 'feature_data', []).forEach((feature) => { if (!get(featureData, get(feature, 'feature_id'))) { featureData[get(feature, 'feature_id')] = []; } @@ -518,6 +524,7 @@ export const parsePureAnomalies = ( startTime: get(rawAnomaly, 'data_start_time'), endTime: get(rawAnomaly, 'data_end_time'), plotTime: get(rawAnomaly, 'data_end_time'), + entity: get(rawAnomaly, 'entity'), }); }); } @@ -546,8 +553,8 @@ export const getFeatureDataPoints = ( const existingTimes = isEmpty(featureData) ? [] : featureData - .map(feature => getRoundedTimeInMin(feature.startTime)) - .filter(featureTime => featureTime != undefined); + .map((feature) => getRoundedTimeInMin(feature.startTime)) + .filter((featureTime) => featureTime != undefined); for ( let currentTime = getRoundedTimeInMin(dateRange.startDate); currentTime < @@ -614,7 +621,7 @@ const sampleFeatureMissingDataPoints = ( if (!dateRange) { return featureMissingDataPoints; } - const sampleTimeWindows = calculateSampleWindowsWithMaxDataPoints( + const sampleTimeWindows = calculateTimeWindowsWithMaxDataPoints( MAX_FEATURE_ANNOTATIONS, dateRange ); @@ -648,7 +655,7 @@ const getDataPointsInWindow = ( timeWindow: DateRange ) => { return dataPoints.filter( - dataPoint => + (dataPoint) => get(dataPoint, 'plotTime', 0) >= timeWindow.startDate && get(dataPoint, 'plotTime', 0) < timeWindow.endDate ); @@ -657,7 +664,7 @@ const getDataPointsInWindow = ( const generateFeatureMissingAnnotations = ( featureMissingDataPoints: FeatureDataPoint[] ) => { - return featureMissingDataPoints.map(feature => ({ + return featureMissingDataPoints.map((feature) => ({ dataValue: feature.plotTime, details: `There is feature data point missing between ${moment( feature.startTime @@ -690,7 +697,7 @@ export const getFeatureMissingDataAnnotations = ( featureData, interval, queryDateRange - ).filter(dataPoint => get(dataPoint, 'isMissing', false)); + ).filter((dataPoint) => get(dataPoint, 'isMissing', false)); const featureMissingAnnotations = finalizeFeatureMissingDataAnnotations( featureMissingDataPoints, @@ -718,7 +725,7 @@ export const getFeatureDataPointsForDetector = ( 'featureAttributes', [] as FeatureAttributes[] ); - allFeatures.forEach(feature => { + allFeatures.forEach((feature) => { //@ts-ignore const featureData = featuresData[feature.featureId]; const featureDataPoints = getFeatureDataPoints( @@ -769,7 +776,7 @@ export const getFeatureMissingSeverities = (featuresDataPoint: { const orderedFeatureDataPoints = orderBy( featureDataPoints, // sort by plot time in desc order - dataPoint => get(dataPoint, 'plotTime', 0), + (dataPoint) => get(dataPoint, 'plotTime', 0), SORT_DIRECTION.DESC ); // feature has >= 3 data points @@ -797,7 +804,8 @@ export const getFeatureMissingSeverities = (featuresDataPoint: { export const getFeatureDataMissingMessageAndActionItem = ( featureMissingSev: MISSING_FEATURE_DATA_SEVERITY | undefined, - featuresWithMissingData: string[] + featuresWithMissingData: string[], + hideFeatureMessage: boolean ) => { switch (featureMissingSev) { case MISSING_FEATURE_DATA_SEVERITY.YELLOW: @@ -808,7 +816,9 @@ export const getFeatureDataMissingMessageAndActionItem = ( ', ' )}. So, anomaly result is missing during this time.`, actionItem: - 'Make sure your data is ingested correctly. See the feature data shown below for more details.', + 'Make sure your data is ingested correctly.' + hideFeatureMessage + ? '' + : ' See the feature data shown below for more details.', }; case MISSING_FEATURE_DATA_SEVERITY.RED: return { @@ -817,7 +827,11 @@ export const getFeatureDataMissingMessageAndActionItem = ( }: ${featuresWithMissingData.join( ', ' )}. So, anomaly result is missing during this time.`, - actionItem: `${DETECTOR_INIT_FAILURES.NO_TRAINING_DATA.actionItem} See the feature data shown below for more details.`, + actionItem: + `${DETECTOR_INIT_FAILURES.NO_TRAINING_DATA.actionItem}` + + hideFeatureMessage + ? '' + : ' See the feature data shown below for more details.', }; default: return { @@ -826,3 +840,23 @@ export const getFeatureDataMissingMessageAndActionItem = ( }; } }; + +export const filterWithHeatmapFilter = ( + data: any[], + heatmapCell: HeatmapCell | undefined, + isFilteringWithEntity: boolean = true, + timeField: string = 'plotTime' +) => { + if (!heatmapCell) { + return data; + } + + if (isFilteringWithEntity) { + data = data + .filter((anomaly) => !isEmpty(get(anomaly, 'entity', []))) + .filter( + (anomaly) => get(anomaly, 'entity')[0].value === heatmapCell.entityValue + ); + } + return filterWithDateRange(data, heatmapCell.dateRange, timeField); +}; diff --git a/public/redux/reducers/alerting.ts b/public/redux/reducers/alerting.ts index 4e2de6d9..35ba6693 100644 --- a/public/redux/reducers/alerting.ts +++ b/public/redux/reducers/alerting.ts @@ -24,6 +24,7 @@ import { Monitor } from '../../../server/models/types'; import { get } from 'lodash'; const SEARCH_MONITORS = 'alerting/SEARCH_MONITORS'; +const SEARCH_ALERTS = 'alerting/SEARCH_ALERTS'; export interface Monitors { requesting: boolean; @@ -84,6 +85,18 @@ const reducer = handleActions( errorMessage: action.error, }), }, + + [SEARCH_ALERTS]: { + REQUEST: (state: Monitors): Monitors => ({ + ...state + }), + SUCCESS: (state: Monitors, action: APIResponseAction): Monitors => ({ + ...state + }), + FAILURE: (state: Monitors, action: APIResponseAction): Monitors => ({ + ...state + }), + }, }, initialDetectorsState ); @@ -94,4 +107,16 @@ export const searchMonitors = (): APIAction => ({ client.post(`..${ALERTING_NODE_API._SEARCH}`, {}), }); +export const searchAlerts = (monitorId: string, startTime: number, endTime: number): APIAction => ({ + type: SEARCH_ALERTS, + request: (client: IHttpService) => + client.get(`..${ALERTING_NODE_API.ALERTS}`,{ + params: { + monitorId: monitorId, + startTime: startTime, + endTime: endTime, + }, + }), +}); + export default reducer; diff --git a/public/redux/reducers/anomalies.ts b/public/redux/reducers/anomalies.ts index d869fe0c..3663fd63 100644 --- a/public/redux/reducers/anomalies.ts +++ b/public/redux/reducers/anomalies.ts @@ -24,12 +24,12 @@ import { Anomalies } from '../../models/interfaces'; const PREVIEW_DETECTOR = 'ad/PREVIEW_DETECTOR'; -export interface Anomalies { +export interface PreviewAnomalies { requesting: boolean; anomaliesResult: Anomalies; errorMessage: string; } -export const initialDetectorsState: Anomalies = { +export const initialDetectorsState: PreviewAnomalies = { requesting: false, anomaliesResult: { anomalies: [], @@ -38,20 +38,26 @@ export const initialDetectorsState: Anomalies = { errorMessage: '', }; -const reducer = handleActions( +const reducer = handleActions( { [PREVIEW_DETECTOR]: { - REQUEST: (state: Anomalies): Anomalies => ({ + REQUEST: (state: PreviewAnomalies): PreviewAnomalies => ({ ...state, requesting: true, errorMessage: '', }), - SUCCESS: (state: Anomalies, action: APIResponseAction): Anomalies => ({ + SUCCESS: ( + state: PreviewAnomalies, + action: APIResponseAction + ): PreviewAnomalies => ({ ...state, requesting: false, anomaliesResult: action.result.data.response, }), - FAILURE: (state: Anomalies, action: APIResponseAction): Anomalies => ({ + FAILURE: ( + state: PreviewAnomalies, + action: APIResponseAction + ): PreviewAnomalies => ({ ...state, requesting: false, errorMessage: action.error, diff --git a/public/redux/reducers/anomalyResults.ts b/public/redux/reducers/anomalyResults.ts index 65024533..f14fbce9 100644 --- a/public/redux/reducers/anomalyResults.ts +++ b/public/redux/reducers/anomalyResults.ts @@ -23,6 +23,7 @@ import { AD_NODE_API } from '../../../utils/constants'; import { AnomalyData } from '../../models/interfaces'; const DETECTOR_RESULTS = 'ad/DETECTOR_RESULTS'; +const SEARCH_ANOMALY_RESULTS = 'ad/SEARCH_ANOMALY_RESULTS'; export interface Anomalies { requesting: boolean; @@ -60,6 +61,18 @@ const reducer = handleActions( errorMessage: action.error.data.error, }), }, + + [SEARCH_ANOMALY_RESULTS]: { + REQUEST: (state: Anomalies): Anomalies => ({ + ...state + }), + SUCCESS: (state: Anomalies, action: APIResponseAction): Anomalies => ({ + ...state + }), + FAILURE: (state: Anomalies): Anomalies => ({ + ...state + }), + }, }, initialDetectorsState ); @@ -75,4 +88,10 @@ export const getDetectorResults = ( }), }); +export const searchResults = (requestBody: any): APIAction => ({ + type: SEARCH_ANOMALY_RESULTS, + request: (client: IHttpService) => + client.post(`..${AD_NODE_API.DETECTOR}/results/_search`, requestBody), +}); + export default reducer; diff --git a/public/utils/utils.tsx b/public/utils/utils.tsx index 80044869..93295884 100644 --- a/public/utils/utils.tsx +++ b/public/utils/utils.tsx @@ -24,36 +24,69 @@ import { darkModeEnabled } from '../utils/kibanaUtils'; import { ALERTING_PLUGIN_NAME, NAME_REGEX } from './constants'; import { MAX_FEATURE_NAME_SIZE } from './constants'; -export const validateName = (featureName: string): string | undefined => { - if (isEmpty(featureName)) { - return 'Required'; +export const validateFeatureName = ( + featureName: string +): string | undefined => { + return validateName(featureName, 'feature'); +}; + +export const validateDetectorName = ( + detectorName: string +): string | undefined => { + return validateName(detectorName, 'detector'); +}; + +export const validateName = ( + name: string, + fieldName: string +): string | undefined => { + if (isEmpty(name)) { + return `You must enter a ${fieldName} name.`; } - if (featureName.length > MAX_FEATURE_NAME_SIZE) { + if (name.length > MAX_FEATURE_NAME_SIZE) { return `Name is too big maximum limit is ${MAX_FEATURE_NAME_SIZE}`; } - if (!NAME_REGEX.test(featureName)) { + if (!NAME_REGEX.test(name)) { return 'Valid characters are a-z, A-Z, 0-9, -(hyphen) and _(underscore)'; } }; -export const validateCategoryField = (val: any): string | undefined => { - return !val || val.length === 0 - ? 'You must select a category field' - : undefined; -}; - export const isInvalid = (name: string, form: any) => !!get(form.touched, name, false) && !!get(form.errors, name, false); export const getError = (name: string, form: any) => get(form.errors, name); -export const required = (val: any): string | undefined => { +export const requiredSelectField = (val: any): string | undefined => { + return required(val, 'You must select a field.'); +}; + +export const required = ( + val: any, + customErrorMessage?: string +): string | undefined => { // if val is number, skip check as number value already exists - return typeof val !== 'number' && !val ? 'Required' : undefined; + const message = !isEmpty(customErrorMessage) + ? customErrorMessage + : 'Required.'; + return typeof val !== 'number' && !val ? message : undefined; +}; + +export const requiredNonEmptyArray = ( + val: any, + customErrorMessage?: string +): string | undefined => { + const message = !isEmpty(customErrorMessage) + ? customErrorMessage + : 'Required.'; + return !val || val.length === 0 ? message : undefined; }; -export const requiredNonEmptyArray = (val: any): string | undefined => { - return !val || val.length === 0 ? 'Required' : undefined; +export const requiredNonEmptyFieldSelected = (val: any): string | undefined => { + return requiredNonEmptyArray(val, 'You must select a field.'); +}; + +export const validateCategoryField = (val: any): string | undefined => { + return requiredNonEmptyArray(val, 'You must select a category field.'); }; export const validatePositiveInteger = (value: any) => { diff --git a/server/cluster/ad/alertingPlugin.ts b/server/cluster/ad/alertingPlugin.ts index 38d4a00d..cac7f2f0 100644 --- a/server/cluster/ad/alertingPlugin.ts +++ b/server/cluster/ad/alertingPlugin.ts @@ -13,7 +13,7 @@ * permissions and limitations under the License. */ -import { API } from '../../utils/constants'; +import { API, MAX_ALERTS } from '../../utils/constants'; export default function alertingPlugin(Client: any, config: any, components: any) { const ca = components.clientAction.factory; @@ -29,4 +29,25 @@ export default function alertingPlugin(Client: any, config: any, components: any method: 'POST', }); + alerting.searchAlerts = ca({ + url: { + fmt: `${API.ALERTING_BASE}/alerts?size=${MAX_ALERTS}&monitorId=<%=monitorId%>&sortString=start_time&sortOrder=desc&searchString=start_time:[<%=startTime%>%20TO%20<%=endTime%>]`, + req: { + monitorId: { + type: 'string', + required: true, + }, + startTime: { + type: 'number', + required: true, + }, + endTime: { + type: 'number', + required: true, + }, + }, + }, + method: 'GET', + }); + } diff --git a/server/models/interfaces.ts b/server/models/interfaces.ts index de86c3fa..075df7d5 100644 --- a/server/models/interfaces.ts +++ b/server/models/interfaces.ts @@ -40,7 +40,10 @@ export interface AlertingApis { [API_ROUTE: string]: string; readonly ALERTING_BASE: string; } - +export type Entity = { + name: string; + value: string; +}; export type Anomaly = { anomalyGrade: number; confidence: number; @@ -48,6 +51,7 @@ export type Anomaly = { startTime: number; endTime: number; plotTime: number; + entity?: Entity[]; }; //Plot time is middle of start and end time to provide better visualization to customers // Example, if window is 10 mins, in a given startTime and endTime of 12:10 to 12:20 respectively. diff --git a/server/models/types.ts b/server/models/types.ts index 6c9f58ee..4afe9a74 100644 --- a/server/models/types.ts +++ b/server/models/types.ts @@ -66,6 +66,7 @@ export type Detector = { enabled: boolean; enabledTime?: number; disabledTime?: number; + categoryField?: string[]; }; export type Monitor = { @@ -105,12 +106,19 @@ export type DetectorResultsQueryParams = { dateRangeFilter?: DateRangeFilter; }; +export type Entity = { + name: string; + value: string; +}; + export type AnomalyResult = { startTime: number; endTime: number; plotTime: number; anomalyGrade: number; confidence: number; + entity?: Entity[]; + features?: { [key: string]: FeatureResult }; }; export type FeatureResult = { @@ -134,4 +142,4 @@ export type DateRangeFilter = { startTime?: number; endTime?: number; fieldName: string; -} \ No newline at end of file +}; diff --git a/server/routes/ad.ts b/server/routes/ad.ts index f9ad1fe7..85fd0719 100644 --- a/server/routes/ad.ts +++ b/server/routes/ad.ts @@ -62,6 +62,7 @@ export default function (apiRouter: Router) { apiRouter.post('/detectors', putDetector); apiRouter.put('/detectors/{detectorId}', putDetector); apiRouter.post('/detectors/_search', searchDetector); + apiRouter.post('/detectors/results/_search', searchResults); apiRouter.get('/detectors/{detectorId}', getDetector); apiRouter.get('/detectors', getDetectors); apiRouter.post('/detectors/{detectorId}/preview', previewDetector); @@ -314,6 +315,33 @@ const searchDetector = async ( } }; +const searchResults = async ( + req: Request, + h: ResponseToolkit, + callWithRequest: CallClusterWithRequest +): Promise> => { + try { + //@ts-ignore + const requestBody = JSON.stringify(req.payload); + const response = await callWithRequest( + req, + 'ad.searchResults', + { body: requestBody } + ); + + return { + ok: true, + response, + }; + } catch (err) { + console.log('Anomaly detector - Unable to search anomaly result', err); + if (isIndexNotFoundError(err)) { + return { ok: true, response: { totalDetectors: 0, detectors: [] } }; + } + return { ok: false, error: err.message }; + } +}; + const getDetectors = async ( req: Request, h: ResponseToolkit, @@ -640,6 +668,10 @@ const getAnomalyResults = async ( Number.parseFloat(result._source.anomaly_grade) ) : 0, + ...(result._source.entity != null + ? { entity: result._source.entity } + : {}), + features: getFeatureData(result), }); result._source.feature_data.forEach((featureData: any) => { if (!featureResult[featureData.feature_id]) { @@ -669,3 +701,19 @@ const getAnomalyResults = async ( return { ok: false, error: err.message }; } }; + +const getFeatureData = (rawResult: any) => { + const featureResult: { [key: string]: FeatureResult } = {}; + rawResult._source.feature_data.forEach((featureData: any) => { + featureResult[featureData.feature_id] = { + startTime: rawResult._source.data_start_time, + endTime: rawResult._source.data_end_time, + plotTime: rawResult._source.data_end_time, + data: + featureData.data != null && featureData.data !== 'NaN' + ? toFixedNumberForAnomaly(Number.parseFloat(featureData.data)) + : 0, + }; + }); + return featureResult; +}; diff --git a/server/routes/alerting.ts b/server/routes/alerting.ts index b3809b63..9e79a68f 100644 --- a/server/routes/alerting.ts +++ b/server/routes/alerting.ts @@ -21,10 +21,11 @@ import { CallClusterWithRequest } from 'src/legacy/core_plugins/elasticsearch'; import { SearchResponse } from '../models/interfaces'; import { Monitor, ServerResponse } from '../models/types'; import { Router } from '../router'; -import { MAX_MONITORS } from '../utils/constants'; +import { MAX_MONITORS, MAX_ALERTS } from '../utils/constants'; export default function(apiRouter: Router) { apiRouter.post('/monitors/_search', searchMonitors); + apiRouter.get('/monitors/alerts', searchAlerts); } const searchMonitors = async ( @@ -89,3 +90,31 @@ const searchMonitors = async ( return { ok: false, error: err.message }; } }; + +const searchAlerts = async ( + req: Request, + h: ResponseToolkit, + callWithRequest: CallClusterWithRequest +): Promise> => { + try { + const { monitorId, startTime, endTime } = req.query as { + monitorId?: string; + startTime?: number; + endTime?: number; + }; + const response = await callWithRequest( + req, + 'alerting.searchAlerts', + { + monitorId: monitorId, startTime: startTime, endTime: endTime + } + ); + return { + ok: true, + response, + }; + } catch (err) { + console.log('Unable to search alerts', err); + return { ok: false, error: err.message }; + } +}; diff --git a/server/routes/utils/adHelpers.ts b/server/routes/utils/adHelpers.ts index 17cdffe7..0ec0d377 100644 --- a/server/routes/utils/adHelpers.ts +++ b/server/routes/utils/adHelpers.ts @@ -74,6 +74,7 @@ export const convertDetectorKeysToCamelCase = (response: object) => { enabled: get(response, 'adJob.enabled', false), enabledTime: get(response, 'adJob.enabled_time'), disabledTime: get(response, 'adJob.disabled_time'), + categoryField: get(response, 'category_field', []), }; }; @@ -151,6 +152,7 @@ export const anomalyResultMapper = (anomalyResults: any[]): AnomalyResults => { startTime: rest.dataStartTime, endTime: rest.dataEndTime, plotTime: rest.dataEndTime, + ...(rest.entity !== undefined ? { entity: rest.entity } : {}), }); featureData.forEach((feature: any) => { resultData.featureData[feature.featureId].push({ diff --git a/server/utils/constants.ts b/server/utils/constants.ts index 977ffca5..486d255e 100644 --- a/server/utils/constants.ts +++ b/server/utils/constants.ts @@ -56,3 +56,5 @@ export enum AD_DOC_FIELDS { } export const MAX_MONITORS = 1000; + +export const MAX_ALERTS = 1000; diff --git a/utils/constants.ts b/utils/constants.ts index e2d9b727..e4888baf 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -28,5 +28,6 @@ export const AD_NODE_API = Object.freeze({ }); export const ALERTING_NODE_API = Object.freeze({ _SEARCH: `${BASE_NODE_API_PATH}/monitors/_search`, + ALERTS: `${BASE_NODE_API_PATH}/monitors/alerts`, MONITORS: `${BASE_NODE_API_PATH}/monitors`, }); diff --git a/yarn.lock b/yarn.lock index 40cfb41a..18aa485f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,15 @@ # yarn lockfile v1 +"3d-view@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/3d-view/-/3d-view-2.0.0.tgz#831ae942d7508c50801e3e06fafe1e8c574e17be" + integrity sha1-gxrpQtdQjFCAHj4G+v4ejFdOF74= + dependencies: + matrix-camera-controller "^2.1.1" + orbit-camera-controller "^4.0.0" + turntable-camera-controller "^3.0.0" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" @@ -947,6 +956,13 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@choojs/findup@^0.2.0": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@choojs/findup/-/findup-0.2.1.tgz#ac13c59ae7be6e1da64de0779a0a7f03d75615a3" + integrity sha512-YstAqNb0MCN8PjdLCDfRsBcGVRN41f3vgLvaI0IrIcBp4AqILRSS0DeWNGkicC+f/zRIPJLc+9RURVSepwvfBw== + dependencies: + commander "^2.15.1" + "@cnakazawa/watch@^1.0.3": version "1.0.4" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" @@ -1111,6 +1127,56 @@ version "0.0.0" uid "" +"@mapbox/geojson-rewind@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@mapbox/geojson-rewind/-/geojson-rewind-0.5.0.tgz#91f0ad56008c120caa19414b644d741249f4f560" + integrity sha512-73l/qJQgj/T/zO1JXVfuVvvKDgikD/7D/rHAD28S9BG1OTstgmftrmqfCx4U+zQAmtsB6HcDA3a7ymdnJZAQgg== + dependencies: + concat-stream "~2.0.0" + minimist "^1.2.5" + +"@mapbox/geojson-types@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@mapbox/geojson-types/-/geojson-types-1.0.2.tgz#9aecf642cb00eab1080a57c4f949a65b4a5846d6" + integrity sha512-e9EBqHHv3EORHrSfbR9DqecPNn+AmuAoQxV6aL8Xu30bJMJR1o8PZLZzpk1Wq7/NfCbuhmakHTPYRhoqLsXRnw== + +"@mapbox/jsonlint-lines-primitives@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz#ce56e539f83552b58d10d672ea4d6fc9adc7b234" + integrity sha1-zlblOfg1UrWNENZy6k1vya3HsjQ= + +"@mapbox/mapbox-gl-supported@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.5.0.tgz#f60b6a55a5d8e5ee908347d2ce4250b15103dc8e" + integrity sha512-/PT1P6DNf7vjEEiPkVIRJkvibbqWtqnyGaBz3nfRdcxclNSnSdaLU5tfAgcD7I8Yt5i+L19s406YLl1koLnLbg== + +"@mapbox/point-geometry@0.1.0", "@mapbox/point-geometry@^0.1.0", "@mapbox/point-geometry@~0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz#8a83f9335c7860effa2eeeca254332aa0aeed8f2" + integrity sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI= + +"@mapbox/tiny-sdf@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@mapbox/tiny-sdf/-/tiny-sdf-1.1.1.tgz#16a20c470741bfe9191deb336f46e194da4a91ff" + integrity sha512-Ihn1nZcGIswJ5XGbgFAvVumOgWpvIjBX9jiRlIl46uQG9vJOF51ViBYHF95rEZupuyQbEmhLaDPLQlU7fUTsBg== + +"@mapbox/unitbezier@^0.0.0": + version "0.0.0" + resolved "https://registry.yarnpkg.com/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz#15651bd553a67b8581fb398810c98ad86a34524e" + integrity sha1-FWUb1VOme4WB+zmIEMmK2Go0Uk4= + +"@mapbox/vector-tile@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz#d3a74c90402d06e89ec66de49ec817ff53409666" + integrity sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw== + dependencies: + "@mapbox/point-geometry" "~0.1.0" + +"@mapbox/whoots-js@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz#497c67a1cef50d1a2459ba60f315e448d2ad87fe" + integrity sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q== + "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" @@ -1145,6 +1211,41 @@ "@nodelib/fs.scandir" "2.1.3" fastq "^1.6.0" +"@plotly/d3-sankey-circular@0.33.1": + version "0.33.1" + resolved "https://registry.yarnpkg.com/@plotly/d3-sankey-circular/-/d3-sankey-circular-0.33.1.tgz#15d1e0337e0e4b1135bdf0e2195c88adacace1a7" + integrity sha512-FgBV1HEvCr3DV7RHhDsPXyryknucxtfnLwPtCKKxdolKyTFYoLX/ibEfX39iFYIL7DYbVeRtP43dbFcrHNE+KQ== + dependencies: + d3-array "^1.2.1" + d3-collection "^1.0.4" + d3-shape "^1.2.0" + elementary-circuits-directed-graph "^1.0.4" + +"@plotly/d3-sankey@0.7.2": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@plotly/d3-sankey/-/d3-sankey-0.7.2.tgz#ddd5290d3b02c60037ced018a162644a2ccef33b" + integrity sha512-2jdVos1N3mMp3QW0k2q1ph7Gd6j5PY1YihBrwpkFnKqO+cqtZq3AdEYUeSGXMeLsBDQYiqTVcihYfk8vr5tqhw== + dependencies: + d3-array "1" + d3-collection "1" + d3-shape "^1.2.0" + +"@plotly/point-cluster@^3.1.9": + version "3.1.9" + resolved "https://registry.yarnpkg.com/@plotly/point-cluster/-/point-cluster-3.1.9.tgz#8ffec77fbf5041bf15401079e4fdf298220291c1" + integrity sha512-MwaI6g9scKf68Orpr1pHZ597pYx9uP8UEFXLPbsCmuw3a84obwz6pnMXGc90VhgDNeNiLEdlmuK7CPo+5PIxXw== + dependencies: + array-bounds "^1.0.1" + binary-search-bounds "^2.0.4" + clamp "^1.0.1" + defined "^1.0.0" + dtype "^2.0.0" + flatten-vertex-data "^1.0.2" + is-obj "^1.0.1" + math-log2 "^1.0.1" + parse-rect "^1.2.0" + pick-by-alias "^1.2.0" + "@samverschueren/stream-to-observable@^0.3.0": version "0.3.1" resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.1.tgz#a21117b19ee9be70c379ec1877537ef2e1c63301" @@ -1196,6 +1297,42 @@ resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-4.2.4.tgz#9029bdf35d7f0557954452916f22ba0e9f11eff9" integrity sha512-Hi74+nCCjTM+HFRmN1CASq3Y1DC8XZk/oF0Ov/sIRXS5izvXCXtjxJcpPNzyi7YL5jGjWuldzsQTiPPtYbudwg== +"@turf/area@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@turf/area/-/area-6.0.1.tgz#50ed63c70ef2bdb72952384f1594319d94f3b051" + integrity sha512-Zv+3N1ep9P5JvR0YOYagLANyapGWQBh8atdeR3bKpWcigVXFsEKNUw03U/5xnh+cKzm7yozHD6MFJkqQv55y0g== + dependencies: + "@turf/helpers" "6.x" + "@turf/meta" "6.x" + +"@turf/bbox@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@turf/bbox/-/bbox-6.0.1.tgz#b966075771475940ee1c16be2a12cf389e6e923a" + integrity sha512-EGgaRLettBG25Iyx7VyUINsPpVj1x3nFQFiGS3ER8KCI1MximzNLsam3eXRabqQDjyAKyAE1bJ4EZEpGvspQxw== + dependencies: + "@turf/helpers" "6.x" + "@turf/meta" "6.x" + +"@turf/centroid@^6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@turf/centroid/-/centroid-6.0.2.tgz#c4eb16b4bc60b692f74e1809cf9a7c4a4f5ba1cc" + integrity sha512-auyDauOtC4eddH7GC3CHFTDu2PKhpSeKCRhwhHhXtJqn2dWCJQNIoCeJRmfXRIbzCWhWvgvQafvvhq8HNvmvWw== + dependencies: + "@turf/helpers" "6.x" + "@turf/meta" "6.x" + +"@turf/helpers@6.x": + version "6.1.4" + resolved "https://registry.yarnpkg.com/@turf/helpers/-/helpers-6.1.4.tgz#d6fd7ebe6782dd9c87dca5559bda5c48ae4c3836" + integrity sha512-vJvrdOZy1ngC7r3MDA7zIGSoIgyrkWcGnNIEaqn/APmw+bVLF2gAW7HIsdTxd12s5wQMqEpqIQrmrbRRZ0xC7g== + +"@turf/meta@6.x": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@turf/meta/-/meta-6.0.2.tgz#eb92951126d24a613ac1b7b99d733fcc20fd30cf" + integrity sha512-VA7HJkx7qF1l3+GNGkDVn2oXy4+QoLP6LktXAaZKjuT1JI0YESat7quUkbCMy4zP9lAUuvS4YMslLyTtr919FA== + dependencies: + "@turf/helpers" "6.x" + "@types/angular@^1.6.55": version "1.7.2" resolved "https://registry.yarnpkg.com/@types/angular/-/angular-1.7.2.tgz#e996f4a5dc184dfe8c076c6ddbbe0d60caab639e" @@ -1254,6 +1391,11 @@ resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +"@types/d3@^3": + version "3.5.43" + resolved "https://registry.yarnpkg.com/@types/d3/-/d3-3.5.43.tgz#e9b4992817e0b6c5efaa7d6e5bb2cee4d73eab58" + integrity sha512-t9ZmXOcpVxywRw86YtIC54g7M9puRh8hFedRvVfHKf5YyOP6pSxA0TvpXpfseXSCInoW4P7bggTrSDiUOs4g5w== + "@types/elasticsearch@^5.0.34": version "5.0.36" resolved "https://registry.yarnpkg.com/@types/elasticsearch/-/elasticsearch-5.0.36.tgz#5799894db7d83a478d19dc36127957579071702c" @@ -1375,6 +1517,13 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.54.tgz#a4b58d8df3a4677b6c08bfbc94b7ad7a7a5f82d1" integrity sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w== +"@types/plotly.js@*": + version "1.50.18" + resolved "https://registry.yarnpkg.com/@types/plotly.js/-/plotly.js-1.50.18.tgz#12b37e3026af9b91a1f93a5e6b936fcaff54e347" + integrity sha512-DMIovwLr/PRRzCJNNdBVToci3G/y1AhuiBJI9HB92Rsql8MRCDdVdwFWgQbcsULaSN2kBJbaZLyWLgYjpt6MFA== + dependencies: + "@types/d3" "^3" + "@types/podium@*": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/podium/-/podium-1.0.0.tgz#bfaa2151be2b1d6109cc69f7faa9dac2cba3bb20" @@ -1392,6 +1541,14 @@ dependencies: "@types/react" "*" +"@types/react-plotly.js@^2.2.4": + version "2.2.4" + resolved "https://registry.yarnpkg.com/@types/react-plotly.js/-/react-plotly.js-2.2.4.tgz#360fcfcace64d0ef173cf0c7d67fc2441b39f659" + integrity sha512-dsvngno7Ar13XoF2eJXM609Msoc5DPboNp8x4NE4L+rsBEEsu16/0b0Fze8REx3fA4HEUk4rcn3uJsx48m2sew== + dependencies: + "@types/plotly.js" "*" + "@types/react" "*" + "@types/react-redux@^7.1.1": version "7.1.9" resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.9.tgz#280c13565c9f13ceb727ec21e767abe0e9b4aec3" @@ -1419,6 +1576,13 @@ "@types/history" "*" "@types/react" "*" +"@types/react-vis@^1.11.3": + version "1.11.3" + resolved "https://registry.yarnpkg.com/@types/react-vis/-/react-vis-1.11.3.tgz#b5e4a4b914290fc746724929cb499e2f4d85e937" + integrity sha512-2fbSqnKVaACu0T9o8TrluxuZvVOdyzaqJjDJm5DCrCfPr3eRAqK4LLIddW3NlLiHUW4O/6dI0TbeEOWyZ9QmgA== + dependencies: + "@types/react" "*" + "@types/react@*", "@types/react@^16.8.23": version "16.9.47" resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.47.tgz#fb092936f0b56425f874d0ff1b08051fdf70c1ba" @@ -1640,11 +1804,25 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== +a-big-triangle@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/a-big-triangle/-/a-big-triangle-1.0.3.tgz#eefd30b02a8f525e8b1f72bb6bb1b0c16751c794" + integrity sha1-7v0wsCqPUl6LH3K7a7GwwWdRx5Q= + dependencies: + gl-buffer "^2.1.1" + gl-vao "^1.2.0" + weak-map "^1.0.5" + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abs-svg-path@^0.1.1, abs-svg-path@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/abs-svg-path/-/abs-svg-path-0.1.1.tgz#df601c8e8d2ba10d4a76d625e236a9a39c2723bf" + integrity sha1-32Acjo0roQ1KdtYl4japo5wnI78= + acorn-jsx@^5.0.0: version "5.2.0" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" @@ -1655,6 +1833,25 @@ acorn@^6.0.7, acorn@^6.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== +acorn@^7.1.1: + version "7.4.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c" + integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w== + +add-line-numbers@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/add-line-numbers/-/add-line-numbers-1.0.1.tgz#48dbbdea47dbd234deafeac6c93cea6f70b4b7e3" + integrity sha1-SNu96kfb0jTer+rGyTzqb3C0t+M= + dependencies: + pad-left "^1.0.2" + +affine-hull@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/affine-hull/-/affine-hull-1.0.0.tgz#763ff1d38d063ceb7e272f17ee4d7bbcaf905c5d" + integrity sha1-dj/x040GPOt+Jy8X7k17vK+QXF0= + dependencies: + robust-orientation "^1.1.3" + aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -1683,6 +1880,27 @@ ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.9.1: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +almost-equal@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/almost-equal/-/almost-equal-1.1.0.tgz#f851c631138757994276aa2efbe8dfa3066cccdd" + integrity sha1-+FHGMROHV5lCdqou++jfowZszN0= + +alpha-complex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/alpha-complex/-/alpha-complex-1.0.0.tgz#90865870d6b0542ae73c0c131d4ef989669b72d2" + integrity sha1-kIZYcNawVCrnPAwTHU75iWabctI= + dependencies: + circumradius "^1.0.0" + delaunay-triangulate "^1.1.6" + +alpha-shape@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/alpha-shape/-/alpha-shape-1.0.0.tgz#c83109923ecfda667d2163fe4f26fe24726f64a9" + integrity sha1-yDEJkj7P2mZ9IWP+Tyb+JHJvZKk= + dependencies: + alpha-complex "^1.0.0" + simplicial-complex-boundary "^1.0.0" + amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" @@ -1839,6 +2057,11 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= +array-bounds@^1.0.0, array-bounds@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-bounds/-/array-bounds-1.0.1.tgz#da11356b4e18e075a4f0c86e1f179a67b7d7ea31" + integrity sha512-8wdW3ZGk6UjMPJx/glyEt0sLzzwAE1bhToPsO1W2pbpR2gULyxe3BjSiuJFheP50T/GgODVPz2fuMUmIywt8cQ== + array-find-index@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" @@ -1858,6 +2081,23 @@ array-includes@^3.1.1: es-abstract "^1.17.0" is-string "^1.0.5" +array-normalize@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/array-normalize/-/array-normalize-1.1.4.tgz#d75cec57383358af38efdf6a78071aa36ae4174c" + integrity sha512-fCp0wKFLjvSPmCn4F5Tiw4M3lpMZoHlCjfcs7nNzuj3vqQQ1/a8cgB9DXcpDSn18c+coLnaW7rqfcYCvKbyJXg== + dependencies: + array-bounds "^1.0.0" + +array-range@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-range/-/array-range-1.0.1.tgz#f56e46591843611c6a56f77ef02eda7c50089bfc" + integrity sha1-9W5GWRhDYRxqVvd+8C7afFAIm/w= + +array-rearrange@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/array-rearrange/-/array-rearrange-2.2.2.tgz#fa1a2acf8d02e88dd0c9602aa0e06a79158b2283" + integrity sha512-UfobP5N12Qm4Qu4fwLDIi2v6+wZsSf6snYSxAMeKhrh37YGnNWZPRmVEKc/2wfms53TLQnzfpG8wCx2Y/6NG1w== + array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -1972,6 +2212,16 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +atob-lite@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/atob-lite/-/atob-lite-1.0.0.tgz#b88dca6006922b962094f7556826bab31c4a296b" + integrity sha1-uI3KYAaSK5YglPdVaCa6sxxKKWs= + +atob-lite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/atob-lite/-/atob-lite-2.0.0.tgz#0fef5ad46f1bd7a8502c65727f0367d5ee43d696" + integrity sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY= + atob@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" @@ -2083,6 +2333,13 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +barycentric@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/barycentric/-/barycentric-1.0.1.tgz#f1562bb891b26f4fec463a82eeda3657800ec688" + integrity sha1-8VYruJGyb0/sRjqC7to2V4AOxog= + dependencies: + robust-linear-solve "^1.0.0" + base64-js@^1.0.2: version "1.3.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" @@ -2108,6 +2365,15 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +big-rat@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/big-rat/-/big-rat-1.0.4.tgz#768d093bb57930dd18ed575c7fca27dc5391adea" + integrity sha1-do0JO7V5MN0Y7Vdcf8on3FORreo= + dependencies: + bit-twiddle "^1.0.2" + bn.js "^4.11.6" + double-bits "^1.1.1" + big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -2123,6 +2389,16 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== +binary-search-bounds@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/binary-search-bounds/-/binary-search-bounds-1.0.0.tgz#323ca317e3f2a40f4244c7255f5384a5b207bb69" + integrity sha1-MjyjF+PypA9CRMclX1OEpbIHu2k= + +binary-search-bounds@^2.0.3, binary-search-bounds@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/binary-search-bounds/-/binary-search-bounds-2.0.4.tgz#eea0e4081da93baa851c7d851a7e636c3d51307f" + integrity sha512-2hg5kgdKql5ClF2ErBcSx0U5bnl5hgS4v7wMnLFodyR47yMtj2w+UAZB+0CiqyHct2q543i7Bi4/aMIegorCCg== + bindings@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" @@ -2130,6 +2406,31 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" +bit-twiddle@^1.0.0, bit-twiddle@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bit-twiddle/-/bit-twiddle-1.0.2.tgz#0c6c1fabe2b23d17173d9a61b7b7093eb9e1769e" + integrity sha1-DGwfq+KyPRcXPZpht7cJPrnhdp4= + +bit-twiddle@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/bit-twiddle/-/bit-twiddle-0.0.2.tgz#c2eaebb952a3b94acc140497e1cdcd2f1a33f58e" + integrity sha1-wurruVKjuUrMFASX4c3NLxoz9Y4= + +bitmap-sdf@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/bitmap-sdf/-/bitmap-sdf-1.0.3.tgz#c99913e5729357a6fd350de34158180c013880b2" + integrity sha512-ojYySSvWTx21cbgntR942zgEgqj38wHctN64vr4vYRFf3GKVmI23YlA94meWGkFslidwLwGCsMy2laJ3g/94Sg== + dependencies: + clamp "^1.0.1" + +bl@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/bl/-/bl-2.2.1.tgz#8c11a7b730655c5d56898cdc871224f40fd901d5" + integrity sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + block-stream@*: version "0.0.9" resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" @@ -2142,7 +2443,7 @@ bluebird@3.7.2, bluebird@^3.5.5, bluebird@^3.7.2: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.6, bn.js@^4.4.0: version "4.11.9" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== @@ -2152,6 +2453,21 @@ bn.js@^5.1.1: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== +boundary-cells@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/boundary-cells/-/boundary-cells-2.0.1.tgz#e905a8d1419cf47cb36be3dbf525db5e24de0042" + integrity sha1-6QWo0UGc9Hyza+Pb9SXbXiTeAEI= + dependencies: + tape "^4.0.0" + +box-intersect@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/box-intersect/-/box-intersect-1.0.2.tgz#4693ad63e828868d0654b114e09364d6281f3fbd" + integrity sha512-yJeMwlmFPG1gIa7Rs/cGXeI6iOj6Qz5MG5PE61xLKpElUGzmJ4abm+qsLpzxKJFpsSDq742BQEocr8dI2t8Nxw== + dependencies: + bit-twiddle "^1.0.2" + typedarray-pool "^1.1.0" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -2398,6 +2714,13 @@ caniuse-lite@^1.0.30001111: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001117.tgz#69a9fae5d480eaa9589f7641a83842ad396d17c4" integrity sha512-4tY0Fatzdx59kYjQs+bNxUwZB03ZEBgVmJ1UkFPz/Q8OLiUUbjct2EdpnXj0fvFTPej2EkbPIG0w8BWsjAyk1Q== +canvas-fit@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/canvas-fit/-/canvas-fit-1.5.0.tgz#ae13be66ade42f5be0e487e345fce30a5e5b5e5f" + integrity sha1-rhO+Zq3kL1vg5IfjRfzjCl5bXl8= + dependencies: + element-size "^1.1.1" + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -2410,6 +2733,20 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +cdt2d@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cdt2d/-/cdt2d-1.0.0.tgz#4f212434bcd67bdb3d68b8fef4acdc2c54415141" + integrity sha1-TyEkNLzWe9s9aLj+9KzcLFRBUUE= + dependencies: + binary-search-bounds "^2.0.3" + robust-in-sphere "^1.1.3" + robust-orientation "^1.1.3" + +cell-orientation@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cell-orientation/-/cell-orientation-1.0.1.tgz#b504ad96a66ad286d9edd985a2253d03b80d2850" + integrity sha1-tQStlqZq0obZ7dmFoiU9A7gNKFA= + chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -2504,6 +2841,26 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" +circumcenter@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/circumcenter/-/circumcenter-1.0.0.tgz#20d7aa13b17fbac52f52da4f54c6ac8b906ee529" + integrity sha1-INeqE7F/usUvUtpPVMasi5Bu5Sk= + dependencies: + dup "^1.0.0" + robust-linear-solve "^1.0.0" + +circumradius@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/circumradius/-/circumradius-1.0.0.tgz#706c447e3e55cd1ed3d11bd133e37c252cc305b5" + integrity sha1-cGxEfj5VzR7T0RvRM+N8JSzDBbU= + dependencies: + circumcenter "^1.0.0" + +clamp@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/clamp/-/clamp-1.0.1.tgz#66a0e64011816e37196828fdc8c8c147312c8634" + integrity sha1-ZqDmQBGBbjcZaCj9yMjBRzEshjQ= + class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -2514,6 +2871,19 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +clean-pslg@^1.1.0, clean-pslg@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/clean-pslg/-/clean-pslg-1.1.2.tgz#bd35c7460b7e8ab5a9f761a5ed51796aa3c86c11" + integrity sha1-vTXHRgt+irWp92Gl7VF5aqPIbBE= + dependencies: + big-rat "^1.0.3" + box-intersect "^1.0.1" + nextafter "^1.0.0" + rat-vec "^1.1.1" + robust-segment-intersect "^1.0.1" + union-find "^1.0.2" + uniq "^1.0.1" + clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" @@ -2611,6 +2981,13 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" +color-alpha@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/color-alpha/-/color-alpha-1.0.4.tgz#c141dc926e95fc3db647d0e14e5bc3651c29e040" + integrity sha512-lr8/t5NPozTSqli+duAN+x+no/2WaKTeWvxhHGN+aXT6AJ8vPlzLa7UriyjWak0pSC2jHol9JgjBYnnHsGha9A== + dependencies: + color-parse "^1.3.8" + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -2625,16 +3002,65 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" +color-id@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/color-id/-/color-id-1.1.0.tgz#5e9159b99a73ac98f74820cb98a15fde3d7e034c" + integrity sha512-2iRtAn6dC/6/G7bBIo0uupVrIne1NsQJvJxZOBCzQOfk7jRq97feaDZ3RdzuHakRXXnHGNwglto3pqtRx1sX0g== + dependencies: + clamp "^1.0.1" + color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@~1.1.4: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-normalize@1.5.0, color-normalize@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/color-normalize/-/color-normalize-1.5.0.tgz#ee610af9acb15daf73e77a945a847b18e40772da" + integrity sha512-rUT/HDXMr6RFffrR53oX3HGWkDOP9goSAQGBkUaAYKjOE2JxozccdGyufageWDlInRAjm/jYPrf/Y38oa+7obw== + dependencies: + clamp "^1.0.1" + color-rgba "^2.1.1" + dtype "^2.0.0" + +color-parse@^1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/color-parse/-/color-parse-1.3.8.tgz#eaf54cd385cb34c0681f18c218aca38478082fa3" + integrity sha512-1Y79qFv0n1xair3lNMTNeoFvmc3nirMVBij24zbs1f13+7fPpQClMg5b4AuKXLt3szj7BRlHMCXHplkce6XlmA== + dependencies: + color-name "^1.0.0" + defined "^1.0.0" + is-plain-obj "^1.1.0" + +color-rgba@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/color-rgba/-/color-rgba-2.1.1.tgz#4633b83817c7406c90b3d7bf4d1acfa48dde5c83" + integrity sha512-VaX97wsqrMwLSOR6H7rU1Doa2zyVdmShabKrPEIFywLlHoibgD3QW9Dw6fSqM4+H/LfjprDNAUUW31qEQcGzNw== + dependencies: + clamp "^1.0.1" + color-parse "^1.3.8" + color-space "^1.14.6" + +color-space@^1.14.6: + version "1.16.0" + resolved "https://registry.yarnpkg.com/color-space/-/color-space-1.16.0.tgz#611781bca41cd8582a1466fd9e28a7d3d89772a2" + integrity sha512-A6WMiFzunQ8KEPFmj02OnnoUnqhmSaHaZ/0LVFcPTdlvm8+3aMJ5x1HRHy3bDHPkovkf4sS0f4wsVvwk71fKkg== + dependencies: + hsluv "^0.0.3" + mumath "^3.3.4" + +colormap@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/colormap/-/colormap-2.3.1.tgz#9f2ab643591c0728d32332d5480b2487a4e0f249" + integrity sha512-TEzNlo/qYp6pBoR2SK9JiV+DG1cmUcVO/+DEJqVPSHIKNlWh5L5L4FYog7b/h0bAnhKhpOAvx/c1dFp2QE9sFw== + dependencies: + lerp "^1.0.3" + colors@^1.1.2: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" @@ -2647,7 +3073,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@^2.11.0, commander@^2.20.0, commander@^2.9.0: +commander@2, commander@^2.11.0, commander@^2.15.1, commander@^2.20.0, commander@^2.9.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -2667,17 +3093,52 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= +compare-angle@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/compare-angle/-/compare-angle-1.0.1.tgz#a4eb63416ea3c747fc6bd6c8b63668b4de4fa129" + integrity sha1-pOtjQW6jx0f8a9bItjZotN5PoSk= + dependencies: + robust-orientation "^1.0.2" + robust-product "^1.0.0" + robust-sum "^1.0.0" + signum "^0.0.0" + two-sum "^1.0.0" + +compare-cell@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/compare-cell/-/compare-cell-1.0.0.tgz#a9eb708f6e0e41aef7aa566b130f1968dc9e1aaa" + integrity sha1-qetwj24OQa73qlZrEw8ZaNyeGqo= + +compare-oriented-cell@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/compare-oriented-cell/-/compare-oriented-cell-1.0.1.tgz#6a149feef9dfc4f8fc62358e51dd42effbbdc39e" + integrity sha1-ahSf7vnfxPj8YjWOUd1C7/u9w54= + dependencies: + cell-orientation "^1.0.1" + compare-cell "^1.0.0" + component-emitter@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== +compute-dims@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/compute-dims/-/compute-dims-1.1.0.tgz#6d5b712929b6c531af3b4d580ed5adacbbd77e0c" + integrity sha512-YHMiIKjH/8Eom8zATk3g8/lH3HxGCZcVQyEfEoVrfWI7od/WRpTgRGShnei3jArYSx77mQqPxZNokjGHCdLfxg== + dependencies: + utils-copy "^1.0.0" + validate.io-array "^1.0.6" + validate.io-matrix-like "^1.0.2" + validate.io-ndarray-like "^1.0.0" + validate.io-positive-integer "^1.0.0" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concat-stream@^1.4.7, concat-stream@^1.5.0, concat-stream@^1.6.2: +concat-stream@^1.4.7, concat-stream@^1.5.0, concat-stream@^1.5.2, concat-stream@^1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== @@ -2687,6 +3148,16 @@ concat-stream@^1.4.7, concat-stream@^1.5.0, concat-stream@^1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" +concat-stream@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" + integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.0.2" + typedarray "^0.0.6" + console-browserify@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" @@ -2697,6 +3168,16 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= +const-max-uint32@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/const-max-uint32/-/const-max-uint32-1.0.2.tgz#f009bb6230e678ed874dd2d6a9cd9e3cbfabb676" + integrity sha1-8Am7YjDmeO2HTdLWqc2ePL+rtnY= + +const-pinf-float64@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/const-pinf-float64/-/const-pinf-float64-1.0.0.tgz#f6efb0d79f9c0986d3e79f2923abf9b70b63d726" + integrity sha1-9u+w15+cCYbT558pI6v5twtj1yY= + constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -2714,6 +3195,15 @@ convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.7.0: dependencies: safe-buffer "~5.1.1" +convex-hull@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/convex-hull/-/convex-hull-1.0.3.tgz#20a3aa6ce87f4adea2ff7d17971c9fc1c67e1fff" + integrity sha1-IKOqbOh/St6i/30XlxyfwcZ+H/8= + dependencies: + affine-hull "^1.0.0" + incremental-convex-hull "^1.0.1" + monotone-convex-hull-2d "^1.0.1" + copy-concurrently@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" @@ -2769,6 +3259,11 @@ cosmiconfig@^5.2.1: js-yaml "^3.13.1" parse-json "^4.0.0" +country-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/country-regex/-/country-regex-1.1.0.tgz#51c333dcdf12927b7e5eeb9c10ac8112a6120896" + integrity sha1-UcMz3N8Sknt+XuucEKyBEqYSCJY= + create-ecdh@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" @@ -2853,6 +3348,51 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" +css-font-size-keywords@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/css-font-size-keywords/-/css-font-size-keywords-1.0.0.tgz#854875ace9aca6a8d2ee0d345a44aae9bb6db6cb" + integrity sha1-hUh1rOmspqjS7g00WkSq6btttss= + +css-font-stretch-keywords@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/css-font-stretch-keywords/-/css-font-stretch-keywords-1.0.1.tgz#50cee9b9ba031fb5c952d4723139f1e107b54b10" + integrity sha1-UM7puboDH7XJUtRyMTnx4Qe1SxA= + +css-font-style-keywords@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/css-font-style-keywords/-/css-font-style-keywords-1.0.1.tgz#5c3532813f63b4a1de954d13cea86ab4333409e4" + integrity sha1-XDUygT9jtKHelU0TzqhqtDM0CeQ= + +css-font-weight-keywords@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/css-font-weight-keywords/-/css-font-weight-keywords-1.0.0.tgz#9bc04671ac85bc724b574ef5d3ac96b0d604fd97" + integrity sha1-m8BGcayFvHJLV07106yWsNYE/Zc= + +css-font@^1.0.0, css-font@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-font/-/css-font-1.2.0.tgz#e73cbdc11fd87c8e6c928ad7098a9771c8c2b6e3" + integrity sha512-V4U4Wps4dPDACJ4WpgofJ2RT5Yqwe1lEH6wlOOaIxMi0gTjdIijsc5FmxQlZ7ZZyKQkkutqqvULOp07l9c7ssA== + dependencies: + css-font-size-keywords "^1.0.0" + css-font-stretch-keywords "^1.0.1" + css-font-style-keywords "^1.0.1" + css-font-weight-keywords "^1.0.0" + css-global-keywords "^1.0.1" + css-system-font-keywords "^1.0.0" + pick-by-alias "^1.2.0" + string-split-by "^1.0.0" + unquote "^1.1.0" + +css-global-keywords@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/css-global-keywords/-/css-global-keywords-1.0.1.tgz#72a9aea72796d019b1d2a3252de4e5aaa37e4a69" + integrity sha1-cqmupyeW0Bmx0qMlLeTlqqN+Smk= + +css-system-font-keywords@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/css-system-font-keywords/-/css-system-font-keywords-1.0.0.tgz#85c6f086aba4eb32c571a3086affc434b84823ed" + integrity sha1-hcbwhquk6zLFcaMIav/ENLhII+0= + css.escape@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" @@ -2868,11 +3408,21 @@ css@^2.2.3: source-map-resolve "^0.5.2" urix "^0.1.0" +csscolorparser@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/csscolorparser/-/csscolorparser-1.0.3.tgz#b34f391eea4da8f3e98231e2ccd8df9c041f171b" + integrity sha1-s085HupNqPPpgjHizNjfnAQfFxs= + csstype@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.3.tgz#2b410bbeba38ba9633353aff34b05d9755d065f8" integrity sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag== +cubic-hermite@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cubic-hermite/-/cubic-hermite-1.0.0.tgz#84e3b2f272b31454e8393b99bb6aed45168c14e5" + integrity sha1-hOOy8nKzFFToOTuZu2rtRRaMFOU= + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -2880,6 +3430,13 @@ currently-unhandled@^0.4.1: dependencies: array-find-index "^1.0.1" +cwise-compiler@^1.0.0, cwise-compiler@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/cwise-compiler/-/cwise-compiler-1.1.3.tgz#f4d667410e850d3a313a7d2db7b1e505bb034cc5" + integrity sha1-9NZnQQ6FDToxOn0tt7HlBbsDTMU= + dependencies: + uniq "^1.0.0" + cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" @@ -2928,6 +3485,146 @@ cypress@^4.11.0: url "^0.11.0" yauzl "^2.10.0" +d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0, d3-array@^1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" + integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw== + +d3-collection@1, d3-collection@^1.0.3, d3-collection@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.7.tgz#349bd2aa9977db071091c13144d5e4f16b5b310e" + integrity sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A== + +d3-color@1, d3-color@^1.0.3: + version "1.4.1" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.4.1.tgz#c52002bf8846ada4424d55d97982fef26eb3bc8a" + integrity sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q== + +d3-contour@^1.1.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/d3-contour/-/d3-contour-1.3.2.tgz#652aacd500d2264cb3423cee10db69f6f59bead3" + integrity sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg== + dependencies: + d3-array "^1.1.1" + +d3-dispatch@1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.6.tgz#00d37bcee4dd8cd97729dd893a0ac29caaba5d58" + integrity sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA== + +d3-force@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/d3-force/-/d3-force-1.2.1.tgz#fd29a5d1ff181c9e7f0669e4bd72bdb0e914ec0b" + integrity sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg== + dependencies: + d3-collection "1" + d3-dispatch "1" + d3-quadtree "1" + d3-timer "1" + +d3-format@1, d3-format@^1.2.0: + version "1.4.5" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.4.5.tgz#374f2ba1320e3717eb74a9356c67daee17a7edb4" + integrity sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ== + +d3-geo@^1.6.4: + version "1.12.1" + resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.12.1.tgz#7fc2ab7414b72e59fbcbd603e80d9adc029b035f" + integrity sha512-XG4d1c/UJSEX9NfU02KwBL6BYPj8YKHxgBEw5om2ZnTRSbIcego6dhHwcxuSR3clxh0EpE38os1DVPOmnYtTPg== + dependencies: + d3-array "1" + +d3-hexbin@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/d3-hexbin/-/d3-hexbin-0.2.2.tgz#9c5837dacfd471ab05337a9e91ef10bfc4f98831" + integrity sha1-nFg32s/UcasFM3qeke8Qv8T5iDE= + +d3-hierarchy@^1.1.4, d3-hierarchy@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz#2f6bee24caaea43f8dc37545fa01628559647a83" + integrity sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ== + +d3-interpolate@1, d3-interpolate@^1.1.4, d3-interpolate@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.4.0.tgz#526e79e2d80daa383f9e0c1c1c7dcc0f0583e987" + integrity sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA== + dependencies: + d3-color "1" + +d3-path@1: + version "1.0.9" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf" + integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== + +d3-quadtree@1: + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-quadtree/-/d3-quadtree-1.0.7.tgz#ca8b84df7bb53763fe3c2f24bd435137f4e53135" + integrity sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA== + +d3-sankey@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/d3-sankey/-/d3-sankey-0.7.1.tgz#d229832268fc69a7fec84803e96c2256a614c521" + integrity sha1-0imDImj8aaf+yEgD6WwiVqYUxSE= + dependencies: + d3-array "1" + d3-collection "1" + d3-shape "^1.2.0" + +d3-scale@^1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-1.0.7.tgz#fa90324b3ea8a776422bd0472afab0b252a0945d" + integrity sha512-KvU92czp2/qse5tUfGms6Kjig0AhHOwkzXG0+PqIJB3ke0WUv088AHMZI0OssO9NCkXt4RP8yju9rpH8aGB7Lw== + dependencies: + d3-array "^1.2.0" + d3-collection "1" + d3-color "1" + d3-format "1" + d3-interpolate "1" + d3-time "1" + d3-time-format "2" + +d3-shape@^1.1.0, d3-shape@^1.2.0: + version "1.3.7" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7" + integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== + dependencies: + d3-path "1" + +d3-time-format@2, d3-time-format@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.3.0.tgz#107bdc028667788a8924ba040faf1fbccd5a7850" + integrity sha512-guv6b2H37s2Uq/GefleCDtbe0XZAuy7Wa49VGkPVPMfLL9qObgBST3lEHJBMUp8S7NdLQAGIvr2KXk8Hc98iKQ== + dependencies: + d3-time "1" + +d3-time@1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.1.0.tgz#b1e19d307dae9c900b7e5b25ffc5dcc249a8a0f1" + integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA== + +d3-timer@1: + version "1.0.10" + resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-1.0.10.tgz#dfe76b8a91748831b13b6d9c793ffbd508dd9de5" + integrity sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw== + +d3-voronoi@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.4.tgz#dd3c78d7653d2bb359284ae478645d95944c8297" + integrity sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg== + +d3@^3.5.17: + version "3.5.17" + resolved "https://registry.yarnpkg.com/d3/-/d3-3.5.17.tgz#bc46748004378b21a360c9fc7cf5231790762fb8" + integrity sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g= + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + damerau-levenshtein@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz#143c1641cb3d85c60c32329e26899adea8701791" @@ -2988,6 +3685,18 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= +deep-equal@^1.0.1, deep-equal@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -3027,6 +3736,11 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +defined@^1.0.0, defined@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= + del@^5.0.0, del@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/del/-/del-5.1.0.tgz#d9487c94e367410e6eff2925ee58c0c84a75b3a7" @@ -3041,6 +3755,14 @@ del@^5.0.0, del@^5.1.0: rimraf "^3.0.0" slash "^3.0.0" +delaunay-triangulate@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/delaunay-triangulate/-/delaunay-triangulate-1.1.6.tgz#5bbca21b078198d4bc3c75796a35cbb98c25954c" + integrity sha1-W7yiGweBmNS8PHV5ajXLuYwllUw= + dependencies: + incremental-convex-hull "^1.0.1" + uniq "^1.0.1" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -3059,6 +3781,11 @@ des.js@^1.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" +detect-kerning@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/detect-kerning/-/detect-kerning-2.1.2.tgz#4ecd548e4a5a3fc880fe2a50609312d000fa9fc2" + integrity sha512-I3JIbrnKPAntNLl1I6TpSQQdQ4AutYzv/sKMFKbepawV/hlH0GmYKhUoOEMd4xqaUHT+Bm0f4127lh5qs1m1tw== + diff-sequences@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" @@ -3110,17 +3837,52 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -domain-browser@^1.1.1: +dom-walk@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== + +domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== +dotignore@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dotignore/-/dotignore-0.1.2.tgz#f942f2200d28c3a76fbdd6f0ee9f3257c8a2e905" + integrity sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw== + dependencies: + minimatch "^3.0.4" + +double-bits@^1.1.0, double-bits@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/double-bits/-/double-bits-1.1.1.tgz#58abba45494da4d0fa36b73ad11a286c9184b1c6" + integrity sha1-WKu6RUlNpND6Nrc60RoobJGEscY= + +draw-svg-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/draw-svg-path/-/draw-svg-path-1.0.0.tgz#6f116d962dd314b99ea534d6f58dd66cdbd69379" + integrity sha1-bxFtli3TFLmepTTW9Y3WbNvWk3k= + dependencies: + abs-svg-path "~0.1.1" + normalize-svg-path "~0.1.0" + +dtype@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dtype/-/dtype-2.0.0.tgz#cd052323ce061444ecd2e8f5748f69a29be28434" + integrity sha1-zQUjI84GFETs0uj1dI9popvihDQ= + +dup@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dup/-/dup-1.0.0.tgz#51fc5ac685f8196469df0b905e934b20af5b4029" + integrity sha1-UfxaxoX4GWRp3wuQXpNLIK9bQCk= + duplexer@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== -duplexify@^3.4.2, duplexify@^3.6.0: +duplexify@^3.4.2, duplexify@^3.4.5, duplexify@^3.6.0: version "3.7.1" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== @@ -3130,6 +3892,11 @@ duplexify@^3.4.2, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" +earcut@^2.1.5, earcut@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.2.tgz#41b0bc35f63e0fe80da7cddff28511e7e2e80d11" + integrity sha512-eZoZPPJcUHnfRZ0PjLvx2qBordSiO8ofC3vt+qACLM95u+4DovnbYNpQtJh0DNsWj8RnxrQytD4WA8gj5cRIaQ== + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -3138,6 +3905,13 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" +edges-to-adjacency-list@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/edges-to-adjacency-list/-/edges-to-adjacency-list-1.0.0.tgz#c146d2e084addfba74a51293c6e0199a49f757f1" + integrity sha1-wUbS4ISt37p0pRKTxuAZmkn3V/E= + dependencies: + uniq "^1.0.0" + electron-to-chromium@^1.3.523: version "1.3.546" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.546.tgz#058c8f2f1a64f71127e7993b60ff4be85aa9bab4" @@ -3148,6 +3922,18 @@ elegant-spinner@^1.0.1: resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= +element-size@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/element-size/-/element-size-1.1.1.tgz#64e5f159d97121631845bcbaecaf279c39b5e34e" + integrity sha1-ZOXxWdlxIWMYRby67K8nnDm1404= + +elementary-circuits-directed-graph@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/elementary-circuits-directed-graph/-/elementary-circuits-directed-graph-1.2.0.tgz#c6507f42566507c646b5bb144b892fbce1656371" + integrity sha512-eOQofnrNqebPtC29PvyNMGUBdMrIw5i8nOoC/2VOlSF84tf5+ZXnRkIk7TgdT22jFXK68CC7aA881KRmNYf/Pg== + dependencies: + strongly-connected-components "^1.0.1" + elliptic@^6.5.3: version "6.5.3" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" @@ -3271,6 +4057,47 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@^2.0.3, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-promise@^4.2.8: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-symbol@^3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +es6-weak-map@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + escalade@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4" @@ -3281,6 +4108,18 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escodegen@^1.11.1: + version "1.14.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" + integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + eslint-import-resolver-node@0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" @@ -3496,7 +4335,7 @@ espree@^5.0.1: acorn-jsx "^5.0.0" eslint-visitor-keys "^1.0.0" -esprima@^4.0.0: +esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -3515,7 +4354,7 @@ esrecurse@^4.1.0: dependencies: estraverse "^4.1.0" -estraverse@^4.1.0, estraverse@^4.1.1: +estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== @@ -3548,6 +4387,11 @@ eventemitter2@^6.4.2: resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.3.tgz#35c563619b13f3681e7eb05cbdaf50f56ba58820" integrity sha512-t0A2msp6BzOf+QAcI6z9XMktLj52OjGQg+8SJH6v5+3uxNpWYRR3wQmfA+6xtMU9kOC59qk9licus5dYcrYkMQ== +events@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= + events@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" @@ -3650,6 +4494,13 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +ext@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" + integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== + dependencies: + type "^2.0.0" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -3702,6 +4553,11 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" +extract-frustum-planes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/extract-frustum-planes/-/extract-frustum-planes-1.0.0.tgz#97d5703ff0564c8c3c6838cac45f9e7bc52c9ef5" + integrity sha1-l9VwP/BWTIw8aDjKxF+ee8UsnvU= + extract-zip@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927" @@ -3722,6 +4578,16 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= +falafel@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/falafel/-/falafel-2.2.4.tgz#b5d86c060c2412a43166243cb1bce44d1abd2819" + integrity sha512-0HXjo8XASWRmsS0X1EkhwEMZaD3Qvp7FfURwjLKjG1ghfRm/MGZl2r4cWUTv41KdNghTw4OUMmVtdGQp3+H+uQ== + dependencies: + acorn "^7.1.1" + foreach "^2.0.5" + isarray "^2.0.1" + object-keys "^1.0.6" + fast-deep-equal@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -3751,6 +4617,13 @@ fast-glob@^3.0.3: micromatch "^4.0.2" picomatch "^2.2.1" +fast-isnumeric@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/fast-isnumeric/-/fast-isnumeric-1.1.4.tgz#e165786ff471c439e9ace2b8c8e66cceb47e2ea4" + integrity sha512-1mM8qOr2LYz8zGaUdmiqRDiuue00Dxjgcb1NQR7TnhLVh6sQyngP9xvLo7Sl7LZpP/sk5eb+bcyWXw530NTBZw== + dependencies: + is-string-blank "^1.0.1" + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -3844,6 +4717,14 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +filtered-vector@^1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/filtered-vector/-/filtered-vector-1.2.4.tgz#56453c034df4302d293ca8ecdeac3f90abc678d3" + integrity sha1-VkU8A030MC0pPKjs3qw/kKvGeNM= + dependencies: + binary-search-bounds "^1.0.0" + cubic-hermite "^1.0.0" + find-cache-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" @@ -3902,6 +4783,18 @@ flatted@^2.0.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== +flatten-vertex-data@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/flatten-vertex-data/-/flatten-vertex-data-1.0.2.tgz#889fd60bea506006ca33955ee1105175fb620219" + integrity sha512-BvCBFK2NZqerFTdMDgqfHBwxYWnxeCkwONsw6PvBMcUXqo8U/KDWwmXhqx1x2kLIg7DqIsJfOaJFOmlua3Lxuw== + dependencies: + dtype "^2.0.0" + +flip-pixels@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/flip-pixels/-/flip-pixels-1.0.2.tgz#aad7b7d9fc65932d5f27e2e4dac4b494140845e4" + integrity sha512-oXbJGbjDnfJRWPC7Va38EFhd+A8JWE5/hCiKcK8qjCdbLj9DTpsq6MEudwpRTH+V4qq+Jw7d3pUgQdSr3x3mTA== + flush-write-stream@^1.0.0, flush-write-stream@^1.0.2: version "1.1.1" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" @@ -3917,11 +4810,37 @@ follow-redirects@1.5.10: dependencies: debug "=3.1.0" +font-atlas@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/font-atlas/-/font-atlas-2.1.0.tgz#aa2d6dcf656a6c871d66abbd3dfbea2f77178348" + integrity sha512-kP3AmvX+HJpW4w3d+PiPR2X6E1yvsBXt2yhuCw+yReO9F1WYhvZwx3c95DGZGwg9xYzDGrgJYa885xmVA+28Cg== + dependencies: + css-font "^1.0.0" + +font-measure@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/font-measure/-/font-measure-1.2.2.tgz#41dbdac5d230dbf4db08865f54da28a475e83026" + integrity sha512-mRLEpdrWzKe9hbfaF3Qpr06TAjquuBVP5cHy4b3hyeNdjc9i0PO6HniGsX5vjL5OWv7+Bd++NiooNpT/s8BvIA== + dependencies: + css-font "^1.2.0" + +for-each@~0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -3958,7 +4877,7 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -from2@^2.1.0: +from2@^2.1.0, from2@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= @@ -4026,16 +4945,21 @@ fstream@^1.0.0, fstream@^1.0.12: mkdirp ">=0.5 0" rimraf "2" -function-bind@^1.1.1: +function-bind@^1.1.1, function-bind@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -functional-red-black-tree@^1.0.1: +functional-red-black-tree@^1.0.0, functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +gamma@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/gamma/-/gamma-0.1.0.tgz#3315643403bf27906ca80ab37c36ece9440ef330" + integrity sha1-MxVkNAO/J5BsqAqzfDbs6UQO8zA= + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -4062,11 +4986,21 @@ gensync@^1.0.0-beta.1: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== +geojson-vt@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/geojson-vt/-/geojson-vt-3.2.1.tgz#f8adb614d2c1d3f6ee7c4265cad4bbf3ad60c8b7" + integrity sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg== + get-caller-file@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-canvas-context@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-canvas-context/-/get-canvas-context-1.0.2.tgz#d6e7b50bc4e4c86357cd39f22647a84b73601e93" + integrity sha1-1ue1C8TkyGNXzTnyJkeoS3NgHpM= + get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" @@ -4110,6 +5044,378 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +gl-axes3d@^1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/gl-axes3d/-/gl-axes3d-1.5.3.tgz#47e3dd6c21356a59349910ec01af58e28ea69fe9" + integrity sha512-KRYbguKQcDQ6PcB9g1pgqB8Ly4TY1DQODpPKiDTasyWJ8PxQk0t2Q7XoQQijNqvsguITCpVVCzNb5GVtIWiVlQ== + dependencies: + bit-twiddle "^1.0.2" + dup "^1.0.0" + extract-frustum-planes "^1.0.0" + gl-buffer "^2.1.2" + gl-mat4 "^1.2.0" + gl-shader "^4.2.1" + gl-state "^1.0.0" + gl-vao "^1.3.0" + gl-vec4 "^1.0.1" + glslify "^7.0.0" + robust-orientation "^1.1.3" + split-polygon "^1.0.0" + vectorize-text "^3.2.1" + +gl-buffer@^2.1.1, gl-buffer@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/gl-buffer/-/gl-buffer-2.1.2.tgz#2db8d9c1a5527fba0cdb91289c206e882b889cdb" + integrity sha1-LbjZwaVSf7oM25EonCBuiCuInNs= + dependencies: + ndarray "^1.0.15" + ndarray-ops "^1.1.0" + typedarray-pool "^1.0.0" + +gl-cone3d@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/gl-cone3d/-/gl-cone3d-1.5.2.tgz#66af5c33b7d5174034dfa3654a88e995998d92bc" + integrity sha512-1JNeHH4sUtUmDA4ZK7Om8/kShwb8IZVAsnxaaB7IPRJsNGciLj1sTpODrJGeMl41RNkex5kXD2SQFrzyEAR2Rw== + dependencies: + colormap "^2.3.1" + gl-buffer "^2.1.2" + gl-mat4 "^1.2.0" + gl-shader "^4.2.1" + gl-texture2d "^2.1.0" + gl-vao "^1.3.0" + gl-vec3 "^1.1.3" + glsl-inverse "^1.0.0" + glsl-out-of-range "^1.0.4" + glsl-specular-cook-torrance "^2.0.1" + glslify "^7.0.0" + ndarray "^1.0.18" + +gl-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gl-constants/-/gl-constants-1.0.0.tgz#597a504e364750ff50253aa35f8dea7af4a5d233" + integrity sha1-WXpQTjZHUP9QJTqjX43qevSl0jM= + +gl-contour2d@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/gl-contour2d/-/gl-contour2d-1.1.7.tgz#ca330cf8449673a9ca0b3f6726c83f8d35c7a50c" + integrity sha512-GdebvJ9DtT3pJDpoE+eU2q+Wo9S3MijPpPz5arZbhK85w2bARmpFpVfPaDlZqWkB644W3BlH8TVyvAo1KE4Bhw== + dependencies: + binary-search-bounds "^2.0.4" + cdt2d "^1.0.0" + clean-pslg "^1.1.2" + gl-buffer "^2.1.2" + gl-shader "^4.2.1" + glslify "^7.0.0" + iota-array "^1.0.0" + ndarray "^1.0.18" + surface-nets "^1.0.2" + +gl-error3d@^1.0.16: + version "1.0.16" + resolved "https://registry.yarnpkg.com/gl-error3d/-/gl-error3d-1.0.16.tgz#88a94952f5303d9cf5cb86806789a360777c5446" + integrity sha512-TGJewnKSp7ZnqGgG3XCF9ldrDbxZrO+OWlx6oIet4OdOM//n8xJ5isArnIV/sdPJnFbhfoLxWrW9f5fxHFRQ1A== + dependencies: + gl-buffer "^2.1.2" + gl-shader "^4.2.1" + gl-vao "^1.3.0" + glsl-out-of-range "^1.0.4" + glslify "^7.0.0" + +gl-fbo@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/gl-fbo/-/gl-fbo-2.0.5.tgz#0fa75a497cf787695530691c8f04abb6fb55fa22" + integrity sha1-D6daSXz3h2lVMGkcjwSrtvtV+iI= + dependencies: + gl-texture2d "^2.0.0" + +gl-format-compiler-error@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/gl-format-compiler-error/-/gl-format-compiler-error-1.0.3.tgz#0c79b1751899ce9732e86240f090aa41e98471a8" + integrity sha1-DHmxdRiZzpcy6GJA8JCqQemEcag= + dependencies: + add-line-numbers "^1.0.1" + gl-constants "^1.0.0" + glsl-shader-name "^1.0.0" + sprintf-js "^1.0.3" + +gl-heatmap2d@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/gl-heatmap2d/-/gl-heatmap2d-1.1.0.tgz#01e52a62ae2154e775ab362850235789af44cefe" + integrity sha512-0FLXyxv6UBCzzhi4Q2u+9fUs6BX1+r5ZztFe27VikE9FUVw7hZiuSHmgDng92EpydogcSYHXCIK8+58RagODug== + dependencies: + binary-search-bounds "^2.0.4" + gl-buffer "^2.1.2" + gl-shader "^4.2.1" + glslify "^7.0.0" + iota-array "^1.0.0" + typedarray-pool "^1.2.0" + +gl-line3d@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/gl-line3d/-/gl-line3d-1.2.1.tgz#632fc5b931a84a315995322b271aaf497e292609" + integrity sha512-eeb0+RI2ZBRqMYJK85SgsRiJK7c4aiOjcnirxv0830A3jmOc99snY3AbPcV8KvKmW0Yaf3KA4e+qNCbHiTOTnA== + dependencies: + binary-search-bounds "^2.0.4" + gl-buffer "^2.1.2" + gl-shader "^4.2.1" + gl-texture2d "^2.1.0" + gl-vao "^1.3.0" + glsl-out-of-range "^1.0.4" + glslify "^7.0.0" + ndarray "^1.0.18" + +gl-mat3@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gl-mat3/-/gl-mat3-1.0.0.tgz#89633219ca429379a16b9185d95d41713453b912" + integrity sha1-iWMyGcpCk3mha5GF2V1BcTRTuRI= + +gl-mat4@^1.0.1, gl-mat4@^1.0.2, gl-mat4@^1.0.3, gl-mat4@^1.1.2, gl-mat4@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gl-mat4/-/gl-mat4-1.2.0.tgz#49d8a7636b70aa00819216635f4a3fd3f4669b26" + integrity sha512-sT5C0pwB1/e9G9AvAoLsoaJtbMGjfd/jfxo8jMCKqYYEnjZuFvqV5rehqar0538EmssjdDeiEWnKyBSTw7quoA== + +gl-matrix@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/gl-matrix/-/gl-matrix-3.3.0.tgz#232eef60b1c8b30a28cbbe75b2caf6c48fd6358b" + integrity sha512-COb7LDz+SXaHtl/h4LeaFcNdJdAQSDeVqjiIihSXNrkWObZLhDI4hIkZC11Aeqp7bcE72clzB0BnDXr2SmslRA== + +gl-mesh3d@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/gl-mesh3d/-/gl-mesh3d-2.3.1.tgz#087a93c5431df923570ca51cfc691bab0d21a6b8" + integrity sha512-pXECamyGgu4/9HeAQSE5OEUuLBGS1aq9V4BCsTcxsND4fNLaajEkYKUz/WY2QSYElqKdsMBVsldGiKRKwlybqA== + dependencies: + barycentric "^1.0.1" + colormap "^2.3.1" + gl-buffer "^2.1.2" + gl-mat4 "^1.2.0" + gl-shader "^4.2.1" + gl-texture2d "^2.1.0" + gl-vao "^1.3.0" + glsl-out-of-range "^1.0.4" + glsl-specular-cook-torrance "^2.0.1" + glslify "^7.0.0" + ndarray "^1.0.18" + normals "^1.1.0" + polytope-closest-point "^1.0.0" + simplicial-complex-contour "^1.0.2" + typedarray-pool "^1.1.0" + +gl-plot2d@^1.4.5: + version "1.4.5" + resolved "https://registry.yarnpkg.com/gl-plot2d/-/gl-plot2d-1.4.5.tgz#6412b8b3f8df3e7d89c5955daac7059e04d657d4" + integrity sha512-6GmCN10SWtV+qHFQ1gjdnVubeHFVsm6P4zmo0HrPIl9TcdePCUHDlBKWAuE6XtFhiMKMj7R8rApOX8O8uXUYog== + dependencies: + binary-search-bounds "^2.0.4" + gl-buffer "^2.1.2" + gl-select-static "^2.0.7" + gl-shader "^4.2.1" + glsl-inverse "^1.0.0" + glslify "^7.0.0" + text-cache "^4.2.2" + +gl-plot3d@^2.4.6: + version "2.4.6" + resolved "https://registry.yarnpkg.com/gl-plot3d/-/gl-plot3d-2.4.6.tgz#69518759c473e3a8c1c76974472836f6500daf50" + integrity sha512-CkrNvDKu0p74Di2g2Oc9kU+s1Oe+wi4cIfHzXABp8DvfoRl0/bayqJ9q8EcRAqMeQQxQZYGvJkk4hlBwI758Jw== + dependencies: + "3d-view" "^2.0.0" + a-big-triangle "^1.0.3" + gl-axes3d "^1.5.3" + gl-fbo "^2.0.5" + gl-mat4 "^1.2.0" + gl-select-static "^2.0.7" + gl-shader "^4.2.1" + gl-spikes3d "^1.0.10" + glslify "^7.0.0" + has-passive-events "^1.0.0" + is-mobile "^2.2.1" + mouse-change "^1.4.0" + mouse-event-offset "^3.0.2" + mouse-wheel "^1.2.0" + ndarray "^1.0.19" + right-now "^1.0.0" + +gl-pointcloud2d@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/gl-pointcloud2d/-/gl-pointcloud2d-1.0.3.tgz#f37e215f21ccb2e17f0604664e99fc3d6a4e611d" + integrity sha512-OS2e1irvJXVRpg/GziXj10xrFJm9kkRfFoB6BLUvkjCQV7ZRNNcs2CD+YSK1r0gvMwTg2T3lfLM3UPwNtz+4Xw== + dependencies: + gl-buffer "^2.1.2" + gl-shader "^4.2.1" + glslify "^7.0.0" + typedarray-pool "^1.1.0" + +gl-quat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gl-quat/-/gl-quat-1.0.0.tgz#0945ec923386f45329be5dc357b1c8c2d47586c5" + integrity sha1-CUXskjOG9FMpvl3DV7HIwtR1hsU= + dependencies: + gl-mat3 "^1.0.0" + gl-vec3 "^1.0.3" + gl-vec4 "^1.0.0" + +gl-scatter3d@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/gl-scatter3d/-/gl-scatter3d-1.2.3.tgz#83d63700ec2fe4e95b3d1cd613e86de9a6b5f603" + integrity sha512-nXqPlT1w5Qt51dTksj+DUqrZqwWAEWg0PocsKcoDnVNv0X8sGA+LBZ0Y+zrA+KNXUL0PPCX9WR9cF2uJAZl1Sw== + dependencies: + gl-buffer "^2.1.2" + gl-mat4 "^1.2.0" + gl-shader "^4.2.1" + gl-vao "^1.3.0" + glsl-out-of-range "^1.0.4" + glslify "^7.0.0" + is-string-blank "^1.0.1" + typedarray-pool "^1.1.0" + vectorize-text "^3.2.1" + +gl-select-box@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/gl-select-box/-/gl-select-box-1.0.4.tgz#47c11caa2b84f81e8bbfde08c6e39eeebb53d3d8" + integrity sha512-mKsCnglraSKyBbQiGq0Ila0WF+m6Tr+EWT2yfaMn/Sh9aMHq5Wt0F/l6Cf/Ed3CdERq5jHWAY5yxLviZteYu2w== + dependencies: + gl-buffer "^2.1.2" + gl-shader "^4.2.1" + glslify "^7.0.0" + +gl-select-static@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/gl-select-static/-/gl-select-static-2.0.7.tgz#ce7eb05ae0139009c15e2d2d0d731600b3dae5c0" + integrity sha512-OvpYprd+ngl3liEatBTdXhSyNBjwvjMSvV2rN0KHpTU+BTi4viEETXNZXFgGXY37qARs0L28ybk3UQEW6C5Nnw== + dependencies: + bit-twiddle "^1.0.2" + gl-fbo "^2.0.5" + ndarray "^1.0.18" + typedarray-pool "^1.1.0" + +gl-shader@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/gl-shader/-/gl-shader-4.2.1.tgz#bc9b808e9293c51b668e88de615b0c113708dc2f" + integrity sha1-vJuAjpKTxRtmjojeYVsMETcI3C8= + dependencies: + gl-format-compiler-error "^1.0.2" + weakmap-shim "^1.1.0" + +gl-spikes2d@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/gl-spikes2d/-/gl-spikes2d-1.0.2.tgz#ef8dbcff6c7451dec2b751d7a3c593d09ad5457f" + integrity sha512-QVeOZsi9nQuJJl7NB3132CCv5KA10BWxAY2QgJNsKqbLsG53B/TrGJpjIAohnJftdZ4fT6b3ZojWgeaXk8bOOA== + +gl-spikes3d@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/gl-spikes3d/-/gl-spikes3d-1.0.10.tgz#e3b2b677a6f51750f23c064447af4f093da79305" + integrity sha512-lT3xroowOFxMvlhT5Mof76B2TE02l5zt/NIWljhczV2FFHgIVhA4jMrd5dIv1so1RXMBDJIKu0uJI3QKliDVLg== + dependencies: + gl-buffer "^2.1.2" + gl-shader "^4.2.1" + gl-vao "^1.3.0" + glslify "^7.0.0" + +gl-state@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gl-state/-/gl-state-1.0.0.tgz#262faa75835b0b9c532c12f38adc425d1d30cd17" + integrity sha1-Ji+qdYNbC5xTLBLzitxCXR0wzRc= + dependencies: + uniq "^1.0.0" + +gl-streamtube3d@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/gl-streamtube3d/-/gl-streamtube3d-1.4.1.tgz#bd2b725e00aa96989ce34b06ebf66a76f93e35ae" + integrity sha512-rH02v00kgwgdpkXVo7KsSoPp38bIAYR9TE1iONjcQ4cQAlDhrGRauqT/P5sUaOIzs17A2DxWGcXM+EpNQs9pUA== + dependencies: + gl-cone3d "^1.5.2" + gl-vec3 "^1.1.3" + gl-vec4 "^1.0.1" + glsl-inverse "^1.0.0" + glsl-out-of-range "^1.0.4" + glsl-specular-cook-torrance "^2.0.1" + glslify "^7.0.0" + +gl-surface3d@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/gl-surface3d/-/gl-surface3d-1.5.2.tgz#a283b98d3473fca4e8552f0f6ac40a6f0dc88b00" + integrity sha512-rWSQwEQDkB0T5CDEDFJwJc4VgwwJaAyFRSJ92NJlrTSwDlsEsWdzG9+APx6FWJMwkOpIoZGWqv+csswK2kMMLQ== + dependencies: + binary-search-bounds "^2.0.4" + bit-twiddle "^1.0.2" + colormap "^2.3.1" + dup "^1.0.0" + gl-buffer "^2.1.2" + gl-mat4 "^1.2.0" + gl-shader "^4.2.1" + gl-texture2d "^2.1.0" + gl-vao "^1.3.0" + glsl-out-of-range "^1.0.4" + glsl-specular-beckmann "^1.1.2" + glslify "^7.0.0" + ndarray "^1.0.18" + ndarray-gradient "^1.0.0" + ndarray-ops "^1.2.2" + ndarray-pack "^1.2.1" + ndarray-scratch "^1.2.0" + surface-nets "^1.0.2" + typedarray-pool "^1.1.0" + +gl-text@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/gl-text/-/gl-text-1.1.8.tgz#67a19bec72915acc422300aad8f727a09f98b550" + integrity sha512-whnq9DEFYbW92C4ONwk2eT0YkzmVPHoADnEtuzMOmit87XhgAhBrNs3lK9EgGjU/MoWYvlF6RkI8Kl7Yuo1hUw== + dependencies: + bit-twiddle "^1.0.2" + color-normalize "^1.5.0" + css-font "^1.2.0" + detect-kerning "^2.1.2" + es6-weak-map "^2.0.3" + flatten-vertex-data "^1.0.2" + font-atlas "^2.1.0" + font-measure "^1.2.2" + gl-util "^3.1.2" + is-plain-obj "^1.1.0" + object-assign "^4.1.1" + parse-rect "^1.2.0" + parse-unit "^1.0.1" + pick-by-alias "^1.2.0" + regl "^1.3.11" + to-px "^1.0.1" + typedarray-pool "^1.1.0" + +gl-texture2d@^2.0.0, gl-texture2d@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/gl-texture2d/-/gl-texture2d-2.1.0.tgz#ff6824e7e7c31a8ba6fdcdbe9e5c695d7e2187c7" + integrity sha1-/2gk5+fDGoum/c2+nlxpXX4hh8c= + dependencies: + ndarray "^1.0.15" + ndarray-ops "^1.2.2" + typedarray-pool "^1.1.0" + +gl-util@^3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/gl-util/-/gl-util-3.1.3.tgz#1e9a724f844b802597c6e30565d4c1e928546861" + integrity sha512-dvRTggw5MSkJnCbh74jZzSoTOGnVYK+Bt+Ckqm39CVcl6+zSsxqWk4lr5NKhkqXHL6qvZAU9h17ZF8mIskY9mA== + dependencies: + is-browser "^2.0.1" + is-firefox "^1.0.3" + is-plain-obj "^1.1.0" + number-is-integer "^1.0.1" + object-assign "^4.1.0" + pick-by-alias "^1.2.0" + weak-map "^1.0.5" + +gl-vao@^1.2.0, gl-vao@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/gl-vao/-/gl-vao-1.3.0.tgz#e9e92aa95588cab9d5c2f04b693440c3df691923" + integrity sha1-6ekqqVWIyrnVwvBLaTRAw99pGSM= + +gl-vec3@^1.0.2, gl-vec3@^1.0.3, gl-vec3@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/gl-vec3/-/gl-vec3-1.1.3.tgz#a47c62f918774a06cbed1b65bcd0288ecbb03826" + integrity sha512-jduKUqT0SGH02l8Yl+mV1yVsDfYgQAJyXGxkJQGyxPLHRiW25DwVIRPt6uvhrEMHftJfqhqKthRcyZqNEl9Xdw== + +gl-vec4@^1.0.0, gl-vec4@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gl-vec4/-/gl-vec4-1.0.1.tgz#97d96878281b14b532cbce101785dfd1cb340964" + integrity sha1-l9loeCgbFLUyy84QF4Xf0cs0CWQ= + glob-all@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.2.1.tgz#082ca81afd2247cbd3ed2149bb2630f4dc877d95" @@ -4154,7 +5460,7 @@ glob-to-regexp@^0.3.0: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= -glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@~7.1.1: +glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@~7.1.1, glob@~7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -4173,6 +5479,14 @@ global-dirs@^2.0.1: dependencies: ini "^1.3.5" +global@^4.3.1: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + globals@^11.1.0, globals@^11.12.0, globals@^11.7.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -4214,11 +5528,173 @@ globule@^1.0.0: lodash "~4.17.10" minimatch "~3.0.2" +glsl-inject-defines@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/glsl-inject-defines/-/glsl-inject-defines-1.0.3.tgz#dd1aacc2c17fcb2bd3fc32411c6633d0d7b60fd4" + integrity sha1-3RqswsF/yyvT/DJBHGYz0Ne2D9Q= + dependencies: + glsl-token-inject-block "^1.0.0" + glsl-token-string "^1.0.1" + glsl-tokenizer "^2.0.2" + +glsl-inverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/glsl-inverse/-/glsl-inverse-1.0.0.tgz#12c0b1d065f558444d1e6feaf79b5ddf8a918ae6" + integrity sha1-EsCx0GX1WERNHm/q95td34qRiuY= + +glsl-out-of-range@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/glsl-out-of-range/-/glsl-out-of-range-1.0.4.tgz#3d73d083bc9ecc73efd45dfc7063c29e92c9c873" + integrity sha512-fCcDu2LCQ39VBvfe1FbhuazXEf0CqMZI9OYXrYlL6uUARG48CTAbL04+tZBtVM0zo1Ljx4OLu2AxNquq++lxWQ== + +glsl-resolve@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/glsl-resolve/-/glsl-resolve-0.0.1.tgz#894bef73910d792c81b5143180035d0a78af76d3" + integrity sha1-iUvvc5ENeSyBtRQxgANdCnivdtM= + dependencies: + resolve "^0.6.1" + xtend "^2.1.2" + +glsl-shader-name@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/glsl-shader-name/-/glsl-shader-name-1.0.0.tgz#a2c30b3ba73499befb0cc7184d7c7733dd4b487d" + integrity sha1-osMLO6c0mb77DMcYTXx3M91LSH0= + dependencies: + atob-lite "^1.0.0" + glsl-tokenizer "^2.0.2" + +glsl-specular-beckmann@^1.1.1, glsl-specular-beckmann@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/glsl-specular-beckmann/-/glsl-specular-beckmann-1.1.2.tgz#fce9056933ecdf2456278376a54d082893e775f1" + integrity sha1-/OkFaTPs3yRWJ4N2pU0IKJPndfE= + +glsl-specular-cook-torrance@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/glsl-specular-cook-torrance/-/glsl-specular-cook-torrance-2.0.1.tgz#a891cc06c8c7b4f4728702b4824fdacbb967d78f" + integrity sha1-qJHMBsjHtPRyhwK0gk/ay7ln148= + dependencies: + glsl-specular-beckmann "^1.1.1" + +glsl-token-assignments@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/glsl-token-assignments/-/glsl-token-assignments-2.0.2.tgz#a5d82ab78499c2e8a6b83cb69495e6e665ce019f" + integrity sha1-pdgqt4SZwuimuDy2lJXm5mXOAZ8= + +glsl-token-defines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/glsl-token-defines/-/glsl-token-defines-1.0.0.tgz#cb892aa959936231728470d4f74032489697fa9d" + integrity sha1-y4kqqVmTYjFyhHDU90AySJaX+p0= + dependencies: + glsl-tokenizer "^2.0.0" + +glsl-token-depth@^1.1.0, glsl-token-depth@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/glsl-token-depth/-/glsl-token-depth-1.1.2.tgz#23c5e30ee2bd255884b4a28bc850b8f791e95d84" + integrity sha1-I8XjDuK9JViEtKKLyFC495HpXYQ= + +glsl-token-descope@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/glsl-token-descope/-/glsl-token-descope-1.0.2.tgz#0fc90ab326186b82f597b2e77dc9e21efcd32076" + integrity sha1-D8kKsyYYa4L1l7LnfcniHvzTIHY= + dependencies: + glsl-token-assignments "^2.0.0" + glsl-token-depth "^1.1.0" + glsl-token-properties "^1.0.0" + glsl-token-scope "^1.1.0" + +glsl-token-inject-block@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/glsl-token-inject-block/-/glsl-token-inject-block-1.1.0.tgz#e1015f5980c1091824adaa2625f1dfde8bd00034" + integrity sha1-4QFfWYDBCRgkraomJfHf3ovQADQ= + +glsl-token-properties@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/glsl-token-properties/-/glsl-token-properties-1.0.1.tgz#483dc3d839f0d4b5c6171d1591f249be53c28a9e" + integrity sha1-SD3D2Dnw1LXGFx0VkfJJvlPCip4= + +glsl-token-scope@^1.1.0, glsl-token-scope@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/glsl-token-scope/-/glsl-token-scope-1.1.2.tgz#a1728e78df24444f9cb93fd18ef0f75503a643b1" + integrity sha1-oXKOeN8kRE+cuT/RjvD3VQOmQ7E= + +glsl-token-string@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/glsl-token-string/-/glsl-token-string-1.0.1.tgz#59441d2f857de7c3449c945666021ece358e48ec" + integrity sha1-WUQdL4V958NEnJRWZgIezjWOSOw= + +glsl-token-whitespace-trim@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/glsl-token-whitespace-trim/-/glsl-token-whitespace-trim-1.0.0.tgz#46d1dfe98c75bd7d504c05d7d11b1b3e9cc93b10" + integrity sha1-RtHf6Yx1vX1QTAXX0RsbPpzJOxA= + +glsl-tokenizer@^2.0.0, glsl-tokenizer@^2.0.2: + version "2.1.5" + resolved "https://registry.yarnpkg.com/glsl-tokenizer/-/glsl-tokenizer-2.1.5.tgz#1c2e78c16589933c274ba278d0a63b370c5fee1a" + integrity sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA== + dependencies: + through2 "^0.6.3" + +glslify-bundle@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glslify-bundle/-/glslify-bundle-5.1.1.tgz#30d2ddf2e6b935bf44d1299321e3b729782c409a" + integrity sha512-plaAOQPv62M1r3OsWf2UbjN0hUYAB7Aph5bfH58VxJZJhloRNbxOL9tl/7H71K7OLJoSJ2ZqWOKk3ttQ6wy24A== + dependencies: + glsl-inject-defines "^1.0.1" + glsl-token-defines "^1.0.0" + glsl-token-depth "^1.1.1" + glsl-token-descope "^1.0.2" + glsl-token-scope "^1.1.1" + glsl-token-string "^1.0.1" + glsl-token-whitespace-trim "^1.0.0" + glsl-tokenizer "^2.0.2" + murmurhash-js "^1.0.0" + shallow-copy "0.0.1" + +glslify-deps@^1.2.5: + version "1.3.1" + resolved "https://registry.yarnpkg.com/glslify-deps/-/glslify-deps-1.3.1.tgz#dfa6962322454a91ecc4de25b5e710415b0c89ad" + integrity sha512-Ogm179MCazwIRyEqs3g3EOY4Y3XIAa0yl8J5RE9rJC6QH1w8weVOp2RZu0mvnYy/2xIas1w166YR2eZdDkWQxg== + dependencies: + "@choojs/findup" "^0.2.0" + events "^1.0.2" + glsl-resolve "0.0.1" + glsl-tokenizer "^2.0.0" + graceful-fs "^4.1.2" + inherits "^2.0.1" + map-limit "0.0.1" + resolve "^1.0.0" + +glslify@^7.0.0, glslify@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glslify/-/glslify-7.1.1.tgz#454d9172b410cb49864029c86d5613947fefd30b" + integrity sha512-bud98CJ6kGZcP9Yxcsi7Iz647wuDz3oN+IZsjCRi5X1PI7t/xPKeL0mOwXJjo+CRZMqvq0CkSJiywCcY7kVYog== + dependencies: + bl "^2.2.1" + concat-stream "^1.5.2" + duplexify "^3.4.5" + falafel "^2.1.0" + from2 "^2.3.0" + glsl-resolve "0.0.1" + glsl-token-whitespace-trim "^1.0.0" + glslify-bundle "^5.0.0" + glslify-deps "^1.2.5" + minimist "^1.2.5" + resolve "^1.1.5" + stack-trace "0.0.9" + static-eval "^2.0.5" + through2 "^2.0.1" + xtend "^4.0.0" + graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== +grid-index@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/grid-index/-/grid-index-1.1.0.tgz#97f8221edec1026c8377b86446a7c71e79522ea7" + integrity sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA== + gud@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0" @@ -4280,6 +5756,20 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-hover@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-hover/-/has-hover-1.0.1.tgz#3d97437aeb199c62b8ac08acbdc53d3bc52c17f7" + integrity sha1-PZdDeusZnGK4rAisvcU9O8UsF/c= + dependencies: + is-browser "^2.0.1" + +has-passive-events@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-passive-events/-/has-passive-events-1.0.0.tgz#75fc3dc6dada182c58f24ebbdc018276d1ea3515" + integrity sha512-2vSj6IeIsgvsRMyeQ0JaCX5Q3lX4zMn5HpoVc7MEhQ6pv8Iq9rsXjsp+E5ZwaT7T0xhMT0KmU8gtt1EFVdbJiw== + dependencies: + is-browser "^2.0.1" + has-symbols@^1.0.0, has-symbols@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" @@ -4321,7 +5811,7 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.1, has@^1.0.3: +has@^1.0.1, has@^1.0.3, has@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== @@ -4366,6 +5856,11 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" +hoek@4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" + integrity sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA== + hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" @@ -4378,6 +5873,11 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== +hsluv@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/hsluv/-/hsluv-0.0.3.tgz#829107dafb4a9f8b52a1809ed02e091eade6754c" + integrity sha1-gpEH2vtKn4tSoYCe0C4JHq3mdUw= + http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -4411,7 +5911,7 @@ iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -ieee754@^1.1.4: +ieee754@^1.1.12, ieee754@^1.1.4: version "1.1.13" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== @@ -4436,6 +5936,20 @@ ignore@^5.1.1: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +image-palette@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/image-palette/-/image-palette-2.1.0.tgz#d976525a1df75964ca125d2dba2741e92905547f" + integrity sha512-3ImSEWD26+xuQFdP0RWR4WSXadZwvgrFhjGNpMEapTG1tf2XrBFS2dlKK5hNgH4UIaSQlSUFRn1NeA+zULIWbQ== + dependencies: + color-id "^1.1.0" + pxls "^2.0.0" + quantize "^1.0.2" + +image-size@^0.7.5: + version "0.7.5" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.7.5.tgz#269f357cf5797cb44683dfa99790e54c705ead04" + integrity sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g== + import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" @@ -4462,6 +5976,14 @@ in-publish@^2.0.0: resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.1.tgz#948b1a535c8030561cea522f73f78f4be357e00c" integrity sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ== +incremental-convex-hull@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/incremental-convex-hull/-/incremental-convex-hull-1.0.1.tgz#51428c14cb9d9a6144bfe69b2851fb377334be1e" + integrity sha1-UUKMFMudmmFEv+abKFH7N3M0vh4= + dependencies: + robust-orientation "^1.1.2" + simplicial-complex "^1.0.0" + indent-string@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" @@ -4492,7 +6014,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -4565,6 +6087,13 @@ interpret@^1.0.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== +interval-tree-1d@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/interval-tree-1d/-/interval-tree-1d-1.0.3.tgz#8fdbde02b6b2c7dbdead636bcbed8e08710d85c1" + integrity sha1-j9veArayx9verWNry+2OCHENhcE= + dependencies: + binary-search-bounds "^1.0.0" + invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -4572,6 +6101,16 @@ invariant@^2.2.2, invariant@^2.2.4: dependencies: loose-envify "^1.0.0" +invert-permutation@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-permutation/-/invert-permutation-1.0.0.tgz#a0a78042eadb36bc17551e787efd1439add54933" + integrity sha1-oKeAQurbNrwXVR54fv0UOa3VSTM= + +iota-array@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/iota-array/-/iota-array-1.0.0.tgz#81ef57fe5d05814cd58c2483632a99c30a0e8087" + integrity sha1-ge9X/l0FgUzVjCSDYyqZwwoOgIc= + is-absolute@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" @@ -4594,11 +6133,21 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-arguments@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" + integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= +is-base64@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-base64/-/is-base64-0.1.0.tgz#a6f20610c6ef4863a51cba32bc0222544b932622" + integrity sha512-WRRyllsGXJM7ZN7gPTCCQ/6wNPTRDwiWdPK66l5sJzcU/oOzcIcRRf0Rux8bkpox/1yjt0F6VJRsQOIG2qz5sg== + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -4613,11 +6162,31 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-buffer@^1.1.5: +is-blob@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-blob/-/is-blob-2.1.0.tgz#e36cd82c90653f1e1b930f11baf9c64216a05385" + integrity sha512-SZ/fTft5eUhQM6oF/ZaASFDEdbFVe89Imltn9uZr03wdKMcWNVYSMjQPFtg05QuNkt5l5c135ElvXEQG0rk4tw== + +is-browser@^2.0.1, is-browser@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-browser/-/is-browser-2.1.0.tgz#fc084d59a5fced307d6708c59356bad7007371a9" + integrity sha512-F5rTJxDQ2sW81fcfOR1GnCXT6sVJC104fCyfj+mjpwNEwaPYSn5fte5jiHmBg3DHsIoL/l8Kvw5VN5SsTRcRFQ== + +is-buffer@^1.0.2, is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-buffer@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" + integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== + +is-callable@^1.1.3: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.1.tgz#4d1e21a4f437509d25ce55f8184350771421c96d" + integrity sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg== + is-callable@^1.1.4, is-callable@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" @@ -4689,11 +6258,21 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= -is-finite@^1.0.0: +is-finite@^1.0.0, is-finite@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== +is-firefox@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-firefox/-/is-firefox-1.0.3.tgz#2a2a1567783a417f6e158323108f3861b0918562" + integrity sha1-KioVZ3g6QX9uFYMjEI84YbCRhWI= + +is-float-array@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-float-array/-/is-float-array-1.0.0.tgz#96d67b1cbadf47ab1e05be208933acd386978a09" + integrity sha512-4ew1Sx6B6kEAl3T3NOM0yB94J3NZnBdNt4paw0e8nY73yHHTeTEhyQ3Lj7EQEnv5LD+GxNTaT4L46jcKjjpLiQ== + is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -4725,6 +6304,11 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-iexplorer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-iexplorer/-/is-iexplorer-1.0.0.tgz#1d72bc66d3fe22eaf6170dda8cf10943248cfc76" + integrity sha1-HXK8ZtP+Iur2Fw3ajPEJQySM/HY= + is-installed-globally@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" @@ -4733,6 +6317,11 @@ is-installed-globally@^0.3.2: global-dirs "^2.0.1" is-path-inside "^3.0.1" +is-mobile@^2.2.1, is-mobile@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-mobile/-/is-mobile-2.2.2.tgz#f6c9c5d50ee01254ce05e739bdd835f1ed4e9954" + integrity sha512-wW/SXnYJkTjs++tVK5b6kVITZpAZPtUrt9SF80vvxGiF/Oywal+COk1jlRkiVq15RFNEQKQY31TkV24/1T5cVg== + is-negated-glob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" @@ -4777,6 +6366,11 @@ is-path-inside@^3.0.1: resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -4789,13 +6383,20 @@ is-promise@^2.1.0: resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== -is-regex@^1.1.0, is-regex@^1.1.1: +is-regex@^1.0.4, is-regex@^1.1.0, is-regex@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== dependencies: has-symbols "^1.0.1" +is-regex@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" + integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== + dependencies: + has "^1.0.3" + is-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" @@ -4818,11 +6419,21 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== +is-string-blank@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-string-blank/-/is-string-blank-1.0.1.tgz#866dca066d41d2894ebdfd2d8fe93e586e583a03" + integrity sha512-9H+ZBCVs3L9OYqv8nuUAzpcT9OTgMD1yAWrG7ihlnibdkbtB850heAmYWxHuXc4CHy4lKeK69tN+ny1K7gBIrw== + is-string@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== +is-svg-path@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-svg-path/-/is-svg-path-1.0.2.tgz#77ab590c12b3d20348e5c7a13d0040c87784dda0" + integrity sha1-d6tZDBKz0gNI5cehPQBAyHeE3aA= + is-symbol@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" @@ -4872,6 +6483,11 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= +isarray@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -5129,6 +6745,11 @@ jsx-ast-utils@^2.4.1: array-includes "^3.1.1" object.assign "^4.1.0" +kdbush@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/kdbush/-/kdbush-3.0.0.tgz#f8484794d47004cc2d85ed3a79353dbe0abc2bf0" + integrity sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew== + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -5184,6 +6805,11 @@ lead@^1.0.0: dependencies: flush-write-stream "^1.0.2" +lerp@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/lerp/-/lerp-1.0.3.tgz#a18c8968f917896de15ccfcc28d55a6b731e776e" + integrity sha1-oYyJaPkXiW3hXM/MKNVaa3Med24= + leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -5434,6 +7060,13 @@ map-cache@^0.2.2: resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= +map-limit@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/map-limit/-/map-limit-0.0.1.tgz#eb7961031c0f0e8d001bf2d56fab685d58822f38" + integrity sha1-63lhAxwPDo0AG/LVb6toXViCLzg= + dependencies: + once "~1.3.0" + map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" @@ -5451,6 +7084,83 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +mapbox-gl@1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/mapbox-gl/-/mapbox-gl-1.10.1.tgz#7dbd53bdf2f78e45e125c1115e94dea286ef663c" + integrity sha512-0aHt+lFUpYfvh0kMIqXqNXqoYMuhuAsMlw87TbhWrw78Tx2zfuPI0Lx31/YPUgJ+Ire0tzQ4JnuBL7acDNXmMg== + dependencies: + "@mapbox/geojson-rewind" "^0.5.0" + "@mapbox/geojson-types" "^1.0.2" + "@mapbox/jsonlint-lines-primitives" "^2.0.2" + "@mapbox/mapbox-gl-supported" "^1.5.0" + "@mapbox/point-geometry" "^0.1.0" + "@mapbox/tiny-sdf" "^1.1.1" + "@mapbox/unitbezier" "^0.0.0" + "@mapbox/vector-tile" "^1.3.1" + "@mapbox/whoots-js" "^3.1.0" + csscolorparser "~1.0.3" + earcut "^2.2.2" + geojson-vt "^3.2.1" + gl-matrix "^3.2.1" + grid-index "^1.1.0" + minimist "^1.2.5" + murmurhash-js "^1.0.0" + pbf "^3.2.1" + potpack "^1.0.1" + quickselect "^2.0.0" + rw "^1.3.3" + supercluster "^7.0.0" + tinyqueue "^2.0.3" + vt-pbf "^3.1.1" + +marching-simplex-table@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/marching-simplex-table/-/marching-simplex-table-1.0.0.tgz#bc16256e0f8f9b558aa9b2872f8832d9433f52ea" + integrity sha1-vBYlbg+Pm1WKqbKHL4gy2UM/Uuo= + dependencies: + convex-hull "^1.0.3" + +mat4-decompose@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mat4-decompose/-/mat4-decompose-1.0.4.tgz#65eb4fe39d70878f7a444eb4624d52f7e7eb2faf" + integrity sha1-ZetP451wh496RE60Yk1S9+frL68= + dependencies: + gl-mat4 "^1.0.1" + gl-vec3 "^1.0.2" + +mat4-interpolate@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mat4-interpolate/-/mat4-interpolate-1.0.4.tgz#55ffe9eb3c35295e2c0d5a9f7725d9068a89ff74" + integrity sha1-Vf/p6zw1KV4sDVqfdyXZBoqJ/3Q= + dependencies: + gl-mat4 "^1.0.1" + gl-vec3 "^1.0.2" + mat4-decompose "^1.0.3" + mat4-recompose "^1.0.3" + quat-slerp "^1.0.0" + +mat4-recompose@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mat4-recompose/-/mat4-recompose-1.0.4.tgz#3953c230ff2473dc772ee014a52c925cf81b0e4d" + integrity sha1-OVPCMP8kc9x3LuAUpSySXPgbDk0= + dependencies: + gl-mat4 "^1.0.1" + +math-log2@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/math-log2/-/math-log2-1.0.1.tgz#fb8941be5f5ebe8979e718e6273b178e58694565" + integrity sha1-+4lBvl9evol55xjmJzsXjlhpRWU= + +matrix-camera-controller@^2.1.1, matrix-camera-controller@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/matrix-camera-controller/-/matrix-camera-controller-2.1.3.tgz#35e5260cc1cd550962ba799f2d8d4e94b1a39370" + integrity sha1-NeUmDMHNVQliunmfLY1OlLGjk3A= + dependencies: + binary-search-bounds "^1.0.0" + gl-mat4 "^1.1.2" + gl-vec3 "^1.0.3" + mat4-interpolate "^1.0.3" + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -5564,6 +7274,13 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + min-indent@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" @@ -5594,7 +7311,7 @@ minimatch@^3.0.4, minimatch@~3.0.2: dependencies: brace-expansion "^1.1.7" -minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: +minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5, minimist@~1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== @@ -5642,6 +7359,39 @@ moment-timezone@^0.5.26: resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d" integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ== +monotone-convex-hull-2d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/monotone-convex-hull-2d/-/monotone-convex-hull-2d-1.0.1.tgz#47f5daeadf3c4afd37764baa1aa8787a40eee08c" + integrity sha1-R/Xa6t88Sv03dkuqGqh4ekDu4Iw= + dependencies: + robust-orientation "^1.1.3" + +mouse-change@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/mouse-change/-/mouse-change-1.4.0.tgz#c2b77e5bfa34a43ce1445c8157a4e4dc9895c14f" + integrity sha1-wrd+W/o0pDzhRFyBV6Tk3JiVwU8= + dependencies: + mouse-event "^1.0.0" + +mouse-event-offset@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/mouse-event-offset/-/mouse-event-offset-3.0.2.tgz#dfd86a6e248c6ba8cad53b905d5037a2063e9984" + integrity sha1-39hqbiSMa6jK1TuQXVA3ogY+mYQ= + +mouse-event@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/mouse-event/-/mouse-event-1.0.5.tgz#b3789edb7109997d5a932d1d01daa1543a501732" + integrity sha1-s3ie23EJmX1aky0dAdqhVDpQFzI= + +mouse-wheel@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mouse-wheel/-/mouse-wheel-1.2.0.tgz#6d2903b1ea8fb48e61f1b53b9036773f042cdb5c" + integrity sha1-bSkDseqPtI5h8bU7kDZ3PwQs21w= + dependencies: + right-now "^1.0.0" + signum "^1.0.0" + to-px "^1.0.1" + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -5664,6 +7414,18 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +mumath@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/mumath/-/mumath-3.3.4.tgz#48d4a0f0fd8cad4e7b32096ee89b161a63d30bbf" + integrity sha1-SNSg8P2MrU57Mglu6JsWGmPTC78= + dependencies: + almost-equal "^1.1.0" + +murmurhash-js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/murmurhash-js/-/murmurhash-js-1.0.0.tgz#b06278e21fc6c37fa5313732b0412bcb6ae15f51" + integrity sha1-sGJ44h/Gw3+lMTcysEEry2rhX1E= + mute-stream@0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.6.tgz#48962b19e169fd1dfc240b3f1e7317627bbc47db" @@ -5701,11 +7463,82 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +ndarray-extract-contour@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ndarray-extract-contour/-/ndarray-extract-contour-1.0.1.tgz#0aee113a3a33b226b90c4888cf877bf4751305e4" + integrity sha1-Cu4ROjozsia5DEiIz4d79HUTBeQ= + dependencies: + typedarray-pool "^1.0.0" + +ndarray-gradient@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ndarray-gradient/-/ndarray-gradient-1.0.0.tgz#b7491a515c6a649f19a62324fff6f27fc8c25393" + integrity sha1-t0kaUVxqZJ8ZpiMk//byf8jCU5M= + dependencies: + cwise-compiler "^1.0.0" + dup "^1.0.0" + +ndarray-linear-interpolate@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ndarray-linear-interpolate/-/ndarray-linear-interpolate-1.0.0.tgz#78bc92b85b9abc15b6e67ee65828f9e2137ae72b" + integrity sha1-eLySuFuavBW25n7mWCj54hN65ys= + +ndarray-ops@^1.1.0, ndarray-ops@^1.2.1, ndarray-ops@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/ndarray-ops/-/ndarray-ops-1.2.2.tgz#59e88d2c32a7eebcb1bc690fae141579557a614e" + integrity sha1-WeiNLDKn7ryxvGkPrhQVeVV6YU4= + dependencies: + cwise-compiler "^1.0.0" + +ndarray-pack@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ndarray-pack/-/ndarray-pack-1.2.1.tgz#8caebeaaa24d5ecf70ff86020637977da8ee585a" + integrity sha1-jK6+qqJNXs9w/4YCBjeXfajuWFo= + dependencies: + cwise-compiler "^1.1.2" + ndarray "^1.0.13" + +ndarray-scratch@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ndarray-scratch/-/ndarray-scratch-1.2.0.tgz#6304636d62eba93db4727ac13c693341dba50e01" + integrity sha1-YwRjbWLrqT20cnrBPGkzQdulDgE= + dependencies: + ndarray "^1.0.14" + ndarray-ops "^1.2.1" + typedarray-pool "^1.0.2" + +ndarray-sort@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ndarray-sort/-/ndarray-sort-1.0.1.tgz#fea05b4cb834c7f4e0216a354f3ca751300dfd6a" + integrity sha1-/qBbTLg0x/TgIWo1TzynUTAN/Wo= + dependencies: + typedarray-pool "^1.0.0" + +ndarray@^1.0.11, ndarray@^1.0.13, ndarray@^1.0.14, ndarray@^1.0.15, ndarray@^1.0.18, ndarray@^1.0.19: + version "1.0.19" + resolved "https://registry.yarnpkg.com/ndarray/-/ndarray-1.0.19.tgz#6785b5f5dfa58b83e31ae5b2a058cfd1ab3f694e" + integrity sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ== + dependencies: + iota-array "^1.0.0" + is-buffer "^1.0.2" + neo-async@^2.5.0, neo-async@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +nextafter@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/nextafter/-/nextafter-1.0.0.tgz#b7d77b535310e3e097e6025abb0a903477ec1a3a" + integrity sha1-t9d7U1MQ4+CX5gJauwqQNHfsGjo= + dependencies: + double-bits "^1.1.0" + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -5833,6 +7666,23 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +normalize-svg-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/normalize-svg-path/-/normalize-svg-path-1.0.1.tgz#6f729ad6b70bb4ca4eff2fe4b107489efe1d56fe" + integrity sha1-b3Ka1rcLtMpO/y/ksQdInv4dVv4= + dependencies: + svg-arc-to-cubic-bezier "^3.0.0" + +normalize-svg-path@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/normalize-svg-path/-/normalize-svg-path-0.1.0.tgz#456360e60ece75fbef7b5d7e160480e7ffd16fe5" + integrity sha1-RWNg5g7Odfvve11+FgSA5//Rb+U= + +normals@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/normals/-/normals-1.1.0.tgz#325b595ed34afe467a6c55a14fd9085787ff59c0" + integrity sha1-MltZXtNK/kZ6bFWhT9kIV4f/WcA= + now-and-later@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.1.tgz#8e579c8685764a7cc02cb680380e94f43ccb1f7c" @@ -5871,11 +7721,23 @@ npm-run-path@^4.0.0: gauge "~2.7.3" set-blocking "~2.0.0" +number-is-integer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-integer/-/number-is-integer-1.0.1.tgz#e59bca172ffed27318e79c7ceb6cb72c095b2152" + integrity sha1-5ZvKFy/+0nMY55x862y3LAlbIVI= + dependencies: + is-finite "^1.0.1" + number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= +numeric@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/numeric/-/numeric-1.2.6.tgz#765b02bef97988fcf880d4eb3f36b80fa31335aa" + integrity sha1-dlsCvvl5iPz4gNTrPza4D6MTNao= + oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -5900,7 +7762,20 @@ object-inspect@^1.7.0, object-inspect@^1.8.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: +object-inspect@~1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + +object-is@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.2.tgz#c5d2e87ff9e119f78b7a088441519e2eec1573b6" + integrity sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.0.6, object-keys@^1.0.9, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -5973,6 +7848,13 @@ once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: dependencies: wrappy "1" +once@~1.3.0: + version "1.3.3" + resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" + integrity sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA= + dependencies: + wrappy "1" + onetime@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" @@ -5992,7 +7874,7 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" -optionator@^0.8.2: +optionator@^0.8.1, optionator@^0.8.2: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== @@ -6004,6 +7886,14 @@ optionator@^0.8.2: type-check "~0.3.2" word-wrap "~1.2.3" +orbit-camera-controller@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/orbit-camera-controller/-/orbit-camera-controller-4.0.0.tgz#6e2b36f0e7878663c330f50da9b7ce686c277005" + integrity sha1-bis28OeHhmPDMPUNqbfOaGwncAU= + dependencies: + filtered-vector "^1.2.1" + gl-mat4 "^1.0.3" + ordered-read-streams@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" @@ -6111,6 +8001,13 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +pad-left@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pad-left/-/pad-left-1.0.2.tgz#19e5735ea98395a26cedc6ab926ead10f3100d4c" + integrity sha1-GeVzXqmDlaJs7carkm6tEPMQDUw= + dependencies: + repeat-string "^1.3.0" + pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" @@ -6132,6 +8029,11 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parenthesis@^3.1.5: + version "3.1.7" + resolved "https://registry.yarnpkg.com/parenthesis/-/parenthesis-3.1.7.tgz#01c89b603a2a6a262ec47554e74ed154a9be2aa6" + integrity sha512-iMtu+HCbLXVrpf6Ys/4YKhcFxbux3xK4ZVB9r+a2kMSqeeQWQoDNYlXIsOjwlT2ldYXZ3k5PVeBnYn7fbAo/Bg== + parse-asn1@^5.0.0, parse-asn1@^5.1.5: version "5.1.6" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" @@ -6158,6 +8060,23 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" +parse-rect@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parse-rect/-/parse-rect-1.2.0.tgz#e0a5b0dbaaaee637a0a1eb9779969e19399d8dec" + integrity sha512-4QZ6KYbnE6RTwg9E0HpLchUM9EZt6DnDxajFZZDSV4p/12ZJEvPO702DZpGvRYEPo00yKDys7jASi+/w7aO8LA== + dependencies: + pick-by-alias "^1.2.0" + +parse-svg-path@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/parse-svg-path/-/parse-svg-path-0.1.2.tgz#7a7ec0d1eb06fa5325c7d3e009b859a09b5d49eb" + integrity sha1-en7A0esG+lMlx9PgCbhZoJtdSes= + +parse-unit@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-unit/-/parse-unit-1.0.1.tgz#7e1bb6d5bef3874c28e392526a2541170291eecf" + integrity sha1-fhu21b7zh0wo45JSaiVBFwKR7s8= + pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" @@ -6257,6 +8176,14 @@ pause-stream@0.0.11: dependencies: through "~2.3" +pbf@^3.0.5, pbf@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/pbf/-/pbf-3.2.1.tgz#b4c1b9e72af966cd82c6531691115cc0409ffe2a" + integrity sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ== + dependencies: + ieee754 "^1.1.12" + resolve-protobuf-schema "^2.1.0" + pbkdf2@^3.0.3: version "3.1.1" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" @@ -6273,11 +8200,36 @@ pend@~1.2.0: resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + integrity sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU= + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +permutation-parity@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/permutation-parity/-/permutation-parity-1.0.0.tgz#0174d51fca704b11b9a4b152b23d537fdc6b5ef4" + integrity sha1-AXTVH8pwSxG5pLFSsj1Tf9xrXvQ= + dependencies: + typedarray-pool "^1.0.0" + +permutation-rank@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/permutation-rank/-/permutation-rank-1.0.0.tgz#9fd98bbcecf08fbf5994b5eadc94a62e679483b5" + integrity sha1-n9mLvOzwj79ZlLXq3JSmLmeUg7U= + dependencies: + invert-permutation "^1.0.0" + typedarray-pool "^1.0.0" + +pick-by-alias@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pick-by-alias/-/pick-by-alias-1.2.0.tgz#5f7cb2b1f21a6e1e884a0c87855aa4a37361107b" + integrity sha1-X3yysfIabh6ISgyHhVqko3NhEHs= + picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" @@ -6331,6 +8283,27 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" +planar-dual@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/planar-dual/-/planar-dual-1.0.2.tgz#b6a4235523b1b0cb79e5f926f8ea335dd982d563" + integrity sha1-tqQjVSOxsMt55fkm+OozXdmC1WM= + dependencies: + compare-angle "^1.0.0" + dup "^1.0.0" + +planar-graph-to-polyline@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/planar-graph-to-polyline/-/planar-graph-to-polyline-1.0.5.tgz#882b8605199ba88bfd464c9553303556c52b988a" + integrity sha1-iCuGBRmbqIv9RkyVUzA1VsUrmIo= + dependencies: + edges-to-adjacency-list "^1.0.0" + planar-dual "^1.0.0" + point-in-big-polygon "^2.0.0" + robust-orientation "^1.0.1" + robust-sum "^1.0.0" + two-product "^1.0.0" + uniq "^1.0.0" + please-upgrade-node@^3.1.1: version "3.2.0" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" @@ -6338,6 +8311,78 @@ please-upgrade-node@^3.1.1: dependencies: semver-compare "^1.0.0" +plotly.js@^1.55.2: + version "1.55.2" + resolved "https://registry.yarnpkg.com/plotly.js/-/plotly.js-1.55.2.tgz#65875d3b2b2a53fa9acfa74a3f7764595df46276" + integrity sha512-bphh7nlQOa1j2t7X+4vdGBSz/QME4Puk+Cuj7n/mYThPVxJkPtBFsTForCrgg4tLJWucY5TV+6F3zHNr4hyWZw== + dependencies: + "@plotly/d3-sankey" "0.7.2" + "@plotly/d3-sankey-circular" "0.33.1" + "@plotly/point-cluster" "^3.1.9" + "@turf/area" "^6.0.1" + "@turf/bbox" "^6.0.1" + "@turf/centroid" "^6.0.2" + alpha-shape "^1.0.0" + canvas-fit "^1.5.0" + color-normalize "^1.5.0" + color-rgba "^2.1.1" + convex-hull "^1.0.3" + country-regex "^1.1.0" + d3 "^3.5.17" + d3-force "^1.2.1" + d3-hierarchy "^1.1.9" + d3-interpolate "^1.4.0" + d3-time-format "^2.2.3" + delaunay-triangulate "^1.1.6" + es6-promise "^4.2.8" + fast-isnumeric "^1.1.4" + gl-cone3d "^1.5.2" + gl-contour2d "^1.1.7" + gl-error3d "^1.0.16" + gl-heatmap2d "^1.1.0" + gl-line3d "1.2.1" + gl-mat4 "^1.2.0" + gl-mesh3d "^2.3.1" + gl-plot2d "^1.4.5" + gl-plot3d "^2.4.6" + gl-pointcloud2d "^1.0.3" + gl-scatter3d "^1.2.3" + gl-select-box "^1.0.4" + gl-spikes2d "^1.0.2" + gl-streamtube3d "^1.4.1" + gl-surface3d "^1.5.2" + gl-text "^1.1.8" + glslify "^7.1.1" + has-hover "^1.0.1" + has-passive-events "^1.0.0" + image-size "^0.7.5" + is-mobile "^2.2.2" + mapbox-gl "1.10.1" + matrix-camera-controller "^2.1.3" + mouse-change "^1.4.0" + mouse-event-offset "^3.0.2" + mouse-wheel "^1.2.0" + ndarray "^1.0.19" + ndarray-linear-interpolate "^1.0.0" + parse-svg-path "^0.1.2" + polybooljs "^1.2.0" + regl "^1.6.1" + regl-error2d "^2.0.11" + regl-line2d "^3.0.18" + regl-scatter2d "3.2.0" + regl-splom "^1.0.12" + right-now "^1.0.0" + robust-orientation "^1.1.3" + sane-topojson "^4.0.0" + strongly-connected-components "^1.0.1" + superscript-text "^1.0.0" + svg-path-sdf "^1.1.3" + tinycolor2 "^1.4.1" + to-px "1.0.1" + topojson-client "^3.1.0" + webgl-context "^2.2.0" + world-calendars "^1.0.3" + plugin-error@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" @@ -6348,11 +8393,38 @@ plugin-error@^1.0.1: arr-union "^3.1.0" extend-shallow "^3.0.2" +point-in-big-polygon@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/point-in-big-polygon/-/point-in-big-polygon-2.0.0.tgz#39b613ea6cf17d6b43e188f77f34c44c6b33ba55" + integrity sha1-ObYT6mzxfWtD4Yj3fzTETGszulU= + dependencies: + binary-search-bounds "^1.0.0" + interval-tree-1d "^1.0.1" + robust-orientation "^1.1.3" + slab-decomposition "^1.0.1" + +polybooljs@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/polybooljs/-/polybooljs-1.2.0.tgz#b4390c2e079d4c262d3b2504c6288d95ba7a4758" + integrity sha1-tDkMLgedTCYtOyUExiiNlbp6R1g= + +polytope-closest-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/polytope-closest-point/-/polytope-closest-point-1.0.0.tgz#e6e57f4081ab5e8c778b811ef06e2c48ae338c3f" + integrity sha1-5uV/QIGrXox3i4Ee8G4sSK4zjD8= + dependencies: + numeric "^1.2.6" + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= +potpack@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/potpack/-/potpack-1.0.1.tgz#d1b1afd89e4c8f7762865ec30bd112ab767e2ebf" + integrity sha512-15vItUAbViaYrmaB/Pbw7z6qX2xENbFSTA7Ii4tgbPtasxm5v6ryKhKtL91tpWovDJzTiZqdwzhcFBCwiMVdVw== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -6400,7 +8472,7 @@ promise@^7.1.1: dependencies: asap "~2.0.3" -prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -6409,6 +8481,11 @@ prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: object-assign "^4.1.1" react-is "^16.8.1" +protocol-buffers-schema@^3.3.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-3.4.0.tgz#2f0ea31ca96627d680bf2fefae7ebfa2b6453eae" + integrity sha512-G/2kcamPF2S49W5yaMGdIpkG6+5wZF0fzBteLKgEHjbNzqjZQ85aAs1iJGto31EJaSTkNvHs5IXuHSaTLWBAiA== + prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" @@ -6483,11 +8560,35 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +pxls@^2.0.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/pxls/-/pxls-2.3.2.tgz#79100d2cc95089fc6e00053a9d93c1ddddb2c7b4" + integrity sha512-pQkwgbLqWPcuES5iEmGa10OlCf5xG0blkIF3dg7PpRZShbTYcvAdfFfGL03SMrkaSUaa/V0UpN9HWg40O2AIIw== + dependencies: + arr-flatten "^1.1.0" + compute-dims "^1.1.0" + flip-pixels "^1.0.2" + is-browser "^2.1.0" + is-buffer "^2.0.3" + to-uint8 "^1.4.1" + qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +quantize@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/quantize/-/quantize-1.0.2.tgz#d25ac200a77b6d70f40127ca171a10e33c8546de" + integrity sha1-0lrCAKd7bXD0ASfKFxoQ4zyFRt4= + +quat-slerp@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/quat-slerp/-/quat-slerp-1.0.1.tgz#2baa15ce3a6bbdc3241d972eb17283139ed69f29" + integrity sha1-K6oVzjprvcMkHZcusXKDE57Wnyk= + dependencies: + gl-quat "^1.0.0" + query-string@^6.8.2: version "6.13.1" resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.13.1.tgz#d913ccfce3b4b3a713989fe6d39466d92e71ccad" @@ -6507,6 +8608,18 @@ querystring@0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= +quickselect@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-2.0.0.tgz#f19680a486a5eefb581303e023e98faaf25dd018" + integrity sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw== + +raf@^3.1.0, raf@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" + integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== + dependencies: + performance-now "^2.1.0" + ramda@^0.26.1, ramda@~0.26.1: version "0.26.1" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" @@ -6527,6 +8640,13 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" +rat-vec@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/rat-vec/-/rat-vec-1.1.1.tgz#0dde2b66b7b34bb1bcd2a23805eac806d87fd17f" + integrity sha1-Dd4rZrezS7G80qI4BerIBth/0X8= + dependencies: + big-rat "^1.0.3" + react-fast-compare@^2.0.1: version "2.0.4" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" @@ -6537,6 +8657,22 @@ react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-motion@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/react-motion/-/react-motion-0.5.2.tgz#0dd3a69e411316567927917c6626551ba0607316" + integrity sha512-9q3YAvHoUiWlP3cK0v+w1N5Z23HXMj4IF4YuvjvWegWqNPfLXsOBE/V7UvQGpXxHFKRQQcNcVQE31g9SB/6qgQ== + dependencies: + performance-now "^0.2.0" + prop-types "^15.5.8" + raf "^3.1.0" + +react-plotly.js@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/react-plotly.js/-/react-plotly.js-2.4.0.tgz#7a8fd89ffa126daa36a5855890282960e2e4eaf0" + integrity sha512-BCkxMe8yWqu3nP/hw9A1KCIuoL67WV5/k68SL9yhEkF6UG+pAuIev9Q3cMKtNkQJZhsYFpOmlqrpPjIdUFACOQ== + dependencies: + prop-types "^15.7.2" + react-redux@^7.1.0: version "7.2.1" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.1.tgz#8dedf784901014db2feca1ab633864dee68ad985" @@ -6577,6 +8713,30 @@ react-router@5.2.0: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" +react-vis@^1.11.7: + version "1.11.7" + resolved "https://registry.yarnpkg.com/react-vis/-/react-vis-1.11.7.tgz#909902af00158895d14da1adfe1d0dc0045228ff" + integrity sha512-vJqS12l/6RHeSq8DVl4PzX0j8iPgbT8H8PtgTRsimKsBNcPjPseO4RICw1FUPrwj8MPrrna34LBtzyC4ATd5Ow== + dependencies: + d3-array "^1.2.0" + d3-collection "^1.0.3" + d3-color "^1.0.3" + d3-contour "^1.1.0" + d3-format "^1.2.0" + d3-geo "^1.6.4" + d3-hexbin "^0.2.2" + d3-hierarchy "^1.1.4" + d3-interpolate "^1.1.4" + d3-sankey "^0.7.1" + d3-scale "^1.0.5" + d3-shape "^1.1.0" + d3-voronoi "^1.1.2" + deep-equal "^1.0.1" + global "^4.3.1" + hoek "4.2.1" + prop-types "^15.5.8" + react-motion "^0.5.2" + read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -6641,7 +8801,7 @@ read-pkg@^3.0.0: string_decoder "~1.1.1" util-deprecate "~1.0.1" -"readable-stream@2 || 3", readable-stream@^3.6.0: +"readable-stream@2 || 3", readable-stream@^3.0.2, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -6650,6 +8810,16 @@ read-pkg@^3.0.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" +"readable-stream@>=1.0.33-1 <1.1.0-0": + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -6689,6 +8859,15 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" +reduce-simplicial-complex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/reduce-simplicial-complex/-/reduce-simplicial-complex-1.0.0.tgz#74d696a2f835f7a6dcd92065fd8c5181f2edf8bc" + integrity sha1-dNaWovg196bc2SBl/YxRgfLt+Lw= + dependencies: + cell-orientation "^1.0.1" + compare-cell "^1.0.0" + compare-oriented-cell "^1.0.1" + redux-mock-store@^1.5.3: version "1.5.4" resolved "https://registry.yarnpkg.com/redux-mock-store/-/redux-mock-store-1.5.4.tgz#90d02495fd918ddbaa96b83aef626287c9ab5872" @@ -6746,7 +8925,12 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp.prototype.flags@^1.3.0: +regex-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/regex-regex/-/regex-regex-1.0.0.tgz#9048a1eaeb870f4d480dabc76fc42cdcc0bc3a72" + integrity sha1-kEih6uuHD01IDavHb8Qs3MC8OnI= + +regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== @@ -6783,6 +8967,77 @@ regjsparser@^0.6.4: dependencies: jsesc "~0.5.0" +regl-error2d@^2.0.11: + version "2.0.11" + resolved "https://registry.yarnpkg.com/regl-error2d/-/regl-error2d-2.0.11.tgz#1de91b6fb02866ecf66e70bbba7419caae1c207b" + integrity sha512-Bv4DbLtDU69GXPSm+NvlVWzT82oQ8M2FK+SxzkyaYMlA9izZRdLmDADqBSyJTnPWiRT4a/2KA+MP+WI0N0yt7Q== + dependencies: + array-bounds "^1.0.1" + color-normalize "^1.5.0" + flatten-vertex-data "^1.0.2" + object-assign "^4.1.1" + pick-by-alias "^1.2.0" + to-float32 "^1.0.1" + update-diff "^1.1.0" + +regl-line2d@^3.0.18: + version "3.0.18" + resolved "https://registry.yarnpkg.com/regl-line2d/-/regl-line2d-3.0.18.tgz#84b68dcf4d7f878f97554183de02175627f0c246" + integrity sha512-yX1TlV0SHBdn8EkU+9K+K19qx7WSDOchrKx+h43rE2NCWuPlVj/MPDgrIXnzhnd42XhQtvvnkSc7aCSLjGAhZQ== + dependencies: + array-bounds "^1.0.1" + array-normalize "^1.1.4" + color-normalize "^1.5.0" + earcut "^2.1.5" + es6-weak-map "^2.0.3" + flatten-vertex-data "^1.0.2" + glslify "^7.0.0" + object-assign "^4.1.1" + parse-rect "^1.2.0" + pick-by-alias "^1.2.0" + to-float32 "^1.0.1" + +regl-scatter2d@3.2.0, regl-scatter2d@^3.1.9: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regl-scatter2d/-/regl-scatter2d-3.2.0.tgz#c4733d94bc6352e74c5e5e660a498343d1b7e4cc" + integrity sha512-c0MxiakVW50UBslsHRmnq41w53bhat5oGvugZEpIZGTdKHVeopRAR2FQHeJf8YrEhOsVn7TpOk9tjySoyHXWGA== + dependencies: + "@plotly/point-cluster" "^3.1.9" + array-range "^1.0.1" + array-rearrange "^2.2.2" + clamp "^1.0.1" + color-id "^1.1.0" + color-normalize "1.5.0" + color-rgba "^2.1.1" + flatten-vertex-data "^1.0.2" + glslify "^7.0.0" + image-palette "^2.1.0" + is-iexplorer "^1.0.0" + object-assign "^4.1.1" + parse-rect "^1.2.0" + pick-by-alias "^1.2.0" + to-float32 "^1.0.1" + update-diff "^1.1.0" + +regl-splom@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/regl-splom/-/regl-splom-1.0.12.tgz#635e1a238e4d5eb7ba07854e30af79b49313be4e" + integrity sha512-LliMmAQ6wJFuPiLxZgYOFOzjhWcrIWPbS3Vf763Twl6R8eKpuUyRHZ54q+hxWGYwICHoPCBKMs7pVAJi8Iv7/w== + dependencies: + array-bounds "^1.0.1" + array-range "^1.0.1" + color-alpha "^1.0.4" + flatten-vertex-data "^1.0.2" + parse-rect "^1.2.0" + pick-by-alias "^1.2.0" + raf "^3.4.1" + regl-scatter2d "^3.1.9" + +regl@^1.3.11, regl@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/regl/-/regl-1.6.1.tgz#6930172cda9b8fb65724abc0d4930d79333f5460" + integrity sha512-7Z9rmpEqmLNwC9kCYCyfyu47eWZaQWeNpwZfwz99QueXN8B/Ow40DB0N+OeUeM/yu9pZAB01+JgJ+XghGveVoA== + remove-bom-buffer@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" @@ -6810,7 +9065,7 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.6.1: +repeat-string@^1.3.0, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= @@ -6897,12 +9152,24 @@ resolve-pathname@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== +resolve-protobuf-schema@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz#9ca9a9e69cf192bbdaf1006ec1973948aa4a3758" + integrity sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ== + dependencies: + protocol-buffers-schema "^3.3.1" + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.10.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.7.1: +resolve@^0.6.1: + version "0.6.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46" + integrity sha1-3ZV5gufnNt699TtYpN2RdUV13UY= + +resolve@^1.0.0, resolve@^1.1.5, resolve@^1.10.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.7.1, resolve@~1.17.0: version "1.17.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== @@ -6925,6 +9192,13 @@ restore-cursor@^2.0.0: onetime "^2.0.0" signal-exit "^3.0.2" +resumer@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" + integrity sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k= + dependencies: + through "~2.3.4" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -6935,6 +9209,11 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +right-now@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/right-now/-/right-now-1.0.0.tgz#6e89609deebd7dcdaf8daecc9aea39cf585a0918" + integrity sha1-bolgne69fc2vja7Mmuo5z1haCRg= + rimraf@2, rimraf@^2.5.4, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" @@ -6964,6 +9243,89 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" +robust-compress@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/robust-compress/-/robust-compress-1.0.0.tgz#4cf62c4b318d8308516012bb8c11752f39329b1b" + integrity sha1-TPYsSzGNgwhRYBK7jBF1Lzkymxs= + +robust-determinant@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/robust-determinant/-/robust-determinant-1.1.0.tgz#8ecae79b79caab3e74f6debe2237e5391a27e9c7" + integrity sha1-jsrnm3nKqz509t6+IjflORon6cc= + dependencies: + robust-compress "^1.0.0" + robust-scale "^1.0.0" + robust-sum "^1.0.0" + two-product "^1.0.0" + +robust-dot-product@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/robust-dot-product/-/robust-dot-product-1.0.0.tgz#c9ba0178bd2c304bfd725f58e889f1d946004553" + integrity sha1-yboBeL0sMEv9cl9Y6Inx2UYARVM= + dependencies: + robust-sum "^1.0.0" + two-product "^1.0.0" + +robust-in-sphere@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/robust-in-sphere/-/robust-in-sphere-1.1.3.tgz#1c5883d16a4e923929476ef34819857bf2a9cf75" + integrity sha1-HFiD0WpOkjkpR27zSBmFe/Kpz3U= + dependencies: + robust-scale "^1.0.0" + robust-subtract "^1.0.0" + robust-sum "^1.0.0" + two-product "^1.0.0" + +robust-linear-solve@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/robust-linear-solve/-/robust-linear-solve-1.0.0.tgz#0cd6ac5040691a6f2aa3cd6311d728905ca3a1f1" + integrity sha1-DNasUEBpGm8qo81jEdcokFyjofE= + dependencies: + robust-determinant "^1.1.0" + +robust-orientation@^1.0.1, robust-orientation@^1.0.2, robust-orientation@^1.1.2, robust-orientation@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/robust-orientation/-/robust-orientation-1.1.3.tgz#daff5b00d3be4e60722f0e9c0156ef967f1c2049" + integrity sha1-2v9bANO+TmByLw6cAVbvln8cIEk= + dependencies: + robust-scale "^1.0.2" + robust-subtract "^1.0.0" + robust-sum "^1.0.0" + two-product "^1.0.2" + +robust-product@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/robust-product/-/robust-product-1.0.0.tgz#685250007cdbba7cf1de75bff6d2927011098abe" + integrity sha1-aFJQAHzbunzx3nW/9tKScBEJir4= + dependencies: + robust-scale "^1.0.0" + robust-sum "^1.0.0" + +robust-scale@^1.0.0, robust-scale@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/robust-scale/-/robust-scale-1.0.2.tgz#775132ed09542d028e58b2cc79c06290bcf78c32" + integrity sha1-d1Ey7QlULQKOWLLMecBikLz3jDI= + dependencies: + two-product "^1.0.2" + two-sum "^1.0.0" + +robust-segment-intersect@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/robust-segment-intersect/-/robust-segment-intersect-1.0.1.tgz#3252b6a0fc1ba14ade6915ccbe09cbce9aab1c1c" + integrity sha1-MlK2oPwboUreaRXMvgnLzpqrHBw= + dependencies: + robust-orientation "^1.1.3" + +robust-subtract@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/robust-subtract/-/robust-subtract-1.0.0.tgz#e0b164e1ed8ba4e3a5dda45a12038348dbed3e9a" + integrity sha1-4LFk4e2LpOOl3aRaEgODSNvtPpo= + +robust-sum@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/robust-sum/-/robust-sum-1.0.0.tgz#16646e525292b4d25d82757a286955e0bbfa53d9" + integrity sha1-FmRuUlKStNJdgnV6KGlV4Lv6U9k= + rsvp@^4.8.4: version "4.8.5" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" @@ -6986,6 +9348,11 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" +rw@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" + integrity sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q= + rx@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" @@ -7020,6 +9387,11 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sane-topojson@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/sane-topojson/-/sane-topojson-4.0.0.tgz#624cdb26fc6d9392c806897bfd1a393f29bb5308" + integrity sha512-bJILrpBboQfabG3BNnHI2hZl52pbt80BE09u4WhnrmzuF2JbMKZdl62G5glXskJ46p+gxE2IzOwGj/awR4g8AA== + sane@^4.0.3: version "4.1.0" resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" @@ -7127,6 +9499,11 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" +shallow-copy@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170" + integrity sha1-QV9CcC1z2BAzApLMXuhurhoRoXA= + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -7164,6 +9541,67 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== +signum@^0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/signum/-/signum-0.0.0.tgz#ab551b1003351070a704783f1a09c5e7691f9cf6" + integrity sha1-q1UbEAM1EHCnBHg/GgnF52kfnPY= + +signum@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/signum/-/signum-1.0.0.tgz#74a7d2bf2a20b40eba16a92b152124f1d559fa77" + integrity sha1-dKfSvyogtA66FqkrFSEk8dVZ+nc= + +simplicial-complex-boundary@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simplicial-complex-boundary/-/simplicial-complex-boundary-1.0.1.tgz#72c9ff1e24deaa374c9bb2fa0cbf0c081ebef815" + integrity sha1-csn/HiTeqjdMm7L6DL8MCB6++BU= + dependencies: + boundary-cells "^2.0.0" + reduce-simplicial-complex "^1.0.0" + +simplicial-complex-contour@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/simplicial-complex-contour/-/simplicial-complex-contour-1.0.2.tgz#890aacac284365340110545cf2629a26e04bf9d1" + integrity sha1-iQqsrChDZTQBEFRc8mKaJuBL+dE= + dependencies: + marching-simplex-table "^1.0.0" + ndarray "^1.0.15" + ndarray-sort "^1.0.0" + typedarray-pool "^1.1.0" + +simplicial-complex@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/simplicial-complex/-/simplicial-complex-0.3.3.tgz#4c30cad57f9e45729dd8f306c8753579f46be99e" + integrity sha1-TDDK1X+eRXKd2PMGyHU1efRr6Z4= + dependencies: + bit-twiddle "~0.0.1" + union-find "~0.0.3" + +simplicial-complex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/simplicial-complex/-/simplicial-complex-1.0.0.tgz#6c33a4ed69fcd4d91b7bcadd3b30b63683eae241" + integrity sha1-bDOk7Wn81Nkbe8rdOzC2NoPq4kE= + dependencies: + bit-twiddle "^1.0.0" + union-find "^1.0.0" + +simplify-planar-graph@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/simplify-planar-graph/-/simplify-planar-graph-2.0.1.tgz#bc85893725f32e8fa8ae25681398446d2cbcf766" + integrity sha1-vIWJNyXzLo+oriVoE5hEbSy892Y= + dependencies: + robust-orientation "^1.0.1" + simplicial-complex "^0.3.3" + +slab-decomposition@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/slab-decomposition/-/slab-decomposition-1.0.2.tgz#1ded56754d408b10739f145103dfc61807f65134" + integrity sha1-He1WdU1AixBznxRRA9/GGAf2UTQ= + dependencies: + binary-search-bounds "^1.0.0" + functional-red-black-tree "^1.0.0" + robust-orientation "^1.1.3" + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -7308,6 +9746,14 @@ split-on-first@^1.0.0: resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== +split-polygon@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/split-polygon/-/split-polygon-1.0.0.tgz#0eacc8a136a76b12a3d95256ea7da45db0c2d247" + integrity sha1-DqzIoTanaxKj2VJW6n2kXbDC0kc= + dependencies: + robust-dot-product "^1.0.0" + robust-sum "^1.0.0" + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -7322,6 +9768,11 @@ split@0.3: dependencies: through "2" +sprintf-js@^1.0.3: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" + integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -7349,6 +9800,11 @@ ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" +stack-trace@0.0.9: + version "0.0.9" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695" + integrity sha1-qPbq7KkGdMMz58Q5U/J1tFFRBpU= + stack-utils@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" @@ -7367,6 +9823,13 @@ start-server-and-test@^1.11.0: ps-tree "1.2.0" wait-on "5.2.0" +static-eval@^2.0.5: + version "2.1.0" + resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-2.1.0.tgz#a16dbe54522d7fa5ef1389129d813fd47b148014" + integrity sha512-agtxZ/kWSsCkI5E4QifRwsaPs0P0JmZV6dkLz6ILYfFYQGn+5plctanRN+IC8dJRiFkyXHrwEE3W9Wmx67uDbw== + dependencies: + escodegen "^1.11.1" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -7431,6 +9894,21 @@ string-argv@^0.3.0: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== +string-split-by@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/string-split-by/-/string-split-by-1.0.0.tgz#53895fb3397ebc60adab1f1e3a131f5372586812" + integrity sha512-KaJKY+hfpzNyet/emP81PJA9hTVSfxNLS9SFTWxdCnnW1/zOOwiV248+EfoX7IQFcBaOp4G5YE6xTJMF+pLg6A== + dependencies: + parenthesis "^3.1.5" + +string-to-arraybuffer@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-to-arraybuffer/-/string-to-arraybuffer-1.0.2.tgz#161147fbadea02e28b0935002cec4c40f1ca7f0a" + integrity sha512-DaGZidzi93dwjQen5I2osxR9ERS/R7B1PFyufNMnzhj+fmlDQAc1DSDIJVJhgI8Oq221efIMbABUBdPHDRt43Q== + dependencies: + atob-lite "^2.0.0" + is-base64 "^0.1.0" + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -7478,6 +9956,15 @@ string.prototype.matchall@^4.0.2: regexp.prototype.flags "^1.3.0" side-channel "^1.0.2" +string.prototype.trim@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz#141233dff32c82bfad80684d7e5f0869ee0fb782" + integrity sha512-MjGFEeqixw47dAMFMtgUro/I0+wNqZB5GKXGt1fFr24u3TzDXCPu7J9Buppzoe3r/LqkSDLDDJzE15RGWDGAVw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" + function-bind "^1.1.1" + string.prototype.trimend@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" @@ -7501,6 +9988,11 @@ string_decoder@^1.0.0, string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -7586,6 +10078,23 @@ strip-json-comments@^2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +strongly-connected-components@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strongly-connected-components/-/strongly-connected-components-1.0.1.tgz#0920e2b4df67c8eaee96c6b6234fe29e873dba99" + integrity sha1-CSDitN9nyOrulsa2I0/inoc9upk= + +supercluster@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supercluster/-/supercluster-7.1.0.tgz#f0a457426ec0ab95d69c5f03b51e049774b94479" + integrity sha512-LDasImUAFMhTqhK+cUXfy9C2KTUqJ3gucLjmNLNFmKWOnDUBxLFLH9oKuXOTCLveecmxh8fbk8kgh6Q0gsfe2w== + dependencies: + kdbush "^3.0.0" + +superscript-text@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/superscript-text/-/superscript-text-1.0.0.tgz#e7cb2752567360df50beb0610ce8df3d71d8dfd8" + integrity sha1-58snUlZzYN9QvrBhDOjfPXHY39g= + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -7612,6 +10121,41 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +surface-nets@^1.0.0, surface-nets@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/surface-nets/-/surface-nets-1.0.2.tgz#e433c8cbba94a7274c6f4c99552b461bf1fc7a4b" + integrity sha1-5DPIy7qUpydMb0yZVStGG/H8eks= + dependencies: + ndarray-extract-contour "^1.0.0" + triangulate-hypercube "^1.0.0" + zero-crossings "^1.0.0" + +svg-arc-to-cubic-bezier@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/svg-arc-to-cubic-bezier/-/svg-arc-to-cubic-bezier-3.2.0.tgz#390c450035ae1c4a0104d90650304c3bc814abe6" + integrity sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g== + +svg-path-bounds@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/svg-path-bounds/-/svg-path-bounds-1.0.1.tgz#bf458b783726bf53431b4633f2792f60748d9f74" + integrity sha1-v0WLeDcmv1NDG0Yz8nkvYHSNn3Q= + dependencies: + abs-svg-path "^0.1.1" + is-svg-path "^1.0.1" + normalize-svg-path "^1.0.0" + parse-svg-path "^0.1.2" + +svg-path-sdf@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/svg-path-sdf/-/svg-path-sdf-1.1.3.tgz#92957a31784c0eaf68945472c8dc6bf9e6d126fc" + integrity sha512-vJJjVq/R5lSr2KLfVXVAStktfcfa1pNFjFOgyJnzZFXlO/fDZ5DmM8FpnSKKzLPfEYTVeXuVBTHF296TpxuJVg== + dependencies: + bitmap-sdf "^1.0.0" + draw-svg-path "^1.0.0" + is-svg-path "^1.0.1" + parse-svg-path "^0.1.2" + svg-path-bounds "^1.0.1" + symbol-observable@^1.1.0, symbol-observable@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" @@ -7637,6 +10181,27 @@ tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== +tape@^4.0.0: + version "4.13.3" + resolved "https://registry.yarnpkg.com/tape/-/tape-4.13.3.tgz#51b3d91c83668c7a45b1a594b607dee0a0b46278" + integrity sha512-0/Y20PwRIUkQcTCSi4AASs+OANZZwqPKaipGCEwp10dQMipVvSZwUUCi01Y/OklIGyHKFhIcjock+DKnBfLAFw== + dependencies: + deep-equal "~1.1.1" + defined "~1.0.0" + dotignore "~0.1.2" + for-each "~0.3.3" + function-bind "~1.1.1" + glob "~7.1.6" + has "~1.0.3" + inherits "~2.0.4" + is-regex "~1.0.5" + minimist "~1.2.5" + object-inspect "~1.7.0" + resolve "~1.17.0" + resumer "~0.0.0" + string.prototype.trim "~1.2.1" + through "~2.3.8" + tar@^2.0.0: version "2.2.2" resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" @@ -7680,6 +10245,13 @@ test-exclude@^5.2.3: read-pkg-up "^4.0.0" require-main-filename "^2.0.0" +text-cache@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/text-cache/-/text-cache-4.2.2.tgz#d0d30ba89b7312ea1c1a31cd9a4db56c1cef7fe7" + integrity sha512-zky+UDYiX0a/aPw/YTBD+EzKMlCTu1chFuCMZeAkgoRiceySdROu1V2kJXhCbtEdBhiOviYnAdGiSYl58HW0ZQ== + dependencies: + vectorize-text "^3.2.1" + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -7706,7 +10278,15 @@ through2-map@^3.0.0: through2 "~2.0.0" xtend "^4.0.0" -through2@^2.0.0, through2@^2.0.3, through2@~2.0.0: +through2@^0.6.3: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + integrity sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg= + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + +through2@^2.0.0, through2@^2.0.1, through2@^2.0.3, through2@~2.0.0: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== @@ -7722,7 +10302,7 @@ through2@^3.0.1: inherits "^2.0.4" readable-stream "2 || 3" -through@2, through@^2.3.6, through@~2.3, through@~2.3.1: +through@2, through@^2.3.6, through@~2.3, through@~2.3.1, through@~2.3.4, through@~2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -7744,6 +10324,16 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.2, tiny-warning@^1.0.3: resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== +tinycolor2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" + integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g= + +tinyqueue@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-2.0.3.tgz#64d8492ebf39e7801d7bd34062e29b45b2035f08" + integrity sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA== + tmp@^0.0.29: version "0.0.29" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.29.tgz#f25125ff0dd9da3ccb0c2dd371ee1288bb9128c0" @@ -7778,6 +10368,15 @@ to-absolute-glob@^2.0.0: is-absolute "^1.0.0" is-negated-glob "^1.0.0" +to-array-buffer@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/to-array-buffer/-/to-array-buffer-3.2.0.tgz#cb684dd691a7368c3b249c2348d75227f7d4dbb4" + integrity sha512-zN33mwi0gpL+7xW1ITLfJ48CEj6ZQW0ZAP0MU+2W3kEY0PAIncyuxmD4OqkUVhPAbTP7amq9j/iwvZKYS+lzSQ== + dependencies: + flatten-vertex-data "^1.0.2" + is-blob "^2.0.1" + string-to-arraybuffer "^1.0.0" + to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" @@ -7788,6 +10387,11 @@ to-fast-properties@^2.0.0: resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= +to-float32@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-float32/-/to-float32-1.0.1.tgz#22d5921f38183164b9e7e9876158c0c16cb9753a" + integrity sha512-nOy2WSwae3xhZbc+05xiCuU3ZPPmH0L4Rg4Q1qiOGFSuNSCTB9nVJaGgGl3ZScxAclX/L8hJuDHJGDAzbfuKCQ== + to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" @@ -7795,6 +10399,20 @@ to-object-path@^0.3.0: dependencies: kind-of "^3.0.2" +to-px@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-px/-/to-px-1.0.1.tgz#5bbaed5e5d4f76445bcc903c293a2307dd324646" + integrity sha1-W7rtXl1PdkRbzJA8KTojB90yRkY= + dependencies: + parse-unit "^1.0.1" + +to-px@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/to-px/-/to-px-1.1.0.tgz#b6b269ed5db0cc9aefc15272a4c8bcb2ca1e99ca" + integrity sha512-bfg3GLYrGoEzrGoE05TAL/Uw+H/qrf2ptr9V3W7U0lkjjyYnIfgxmVLUfhQ1hZpIQwin81uxhDjvUkDYsC0xWw== + dependencies: + parse-unit "^1.0.1" + to-regex-range@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" @@ -7827,6 +10445,24 @@ to-through@^2.0.0: dependencies: through2 "^2.0.3" +to-uint8@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/to-uint8/-/to-uint8-1.4.1.tgz#9f45694905b827f247d37bc8ec83b2818d81fac9" + integrity sha512-o+ochsMlTZyucbww8It401FC2Rx+OP2RpDeYbA6h+y9HgedDl1UjdsJ9CmzKEG7AFP9es5PmJ4eDWeeeXihESg== + dependencies: + arr-flatten "^1.1.0" + clamp "^1.0.1" + is-base64 "^0.1.0" + is-float-array "^1.0.0" + to-array-buffer "^3.0.0" + +topojson-client@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/topojson-client/-/topojson-client-3.1.0.tgz#22e8b1ed08a2b922feeb4af6f53b6ef09a467b99" + integrity sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw== + dependencies: + commander "2" + tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" @@ -7835,6 +10471,22 @@ tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" +triangulate-hypercube@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/triangulate-hypercube/-/triangulate-hypercube-1.0.1.tgz#d8071db2ebfcfd51f308d0bcf2a5c48a5b36d137" + integrity sha1-2Acdsuv8/VHzCNC88qXEils20Tc= + dependencies: + gamma "^0.1.0" + permutation-parity "^1.0.0" + permutation-rank "^1.0.0" + +triangulate-polyline@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/triangulate-polyline/-/triangulate-polyline-1.0.3.tgz#bf8ba877a85054103feb9fa5a61b4e8d7017814d" + integrity sha1-v4uod6hQVBA/65+lphtOjXAXgU0= + dependencies: + cdt2d "^1.0.0" + trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" @@ -7874,11 +10526,30 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" +turntable-camera-controller@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/turntable-camera-controller/-/turntable-camera-controller-3.0.1.tgz#8dbd3fe00550191c65164cb888971049578afd99" + integrity sha1-jb0/4AVQGRxlFky4iJcQSVeK/Zk= + dependencies: + filtered-vector "^1.2.1" + gl-mat4 "^1.0.2" + gl-vec3 "^1.0.2" + tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +two-product@^1.0.0, two-product@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/two-product/-/two-product-1.0.2.tgz#67d95d4b257a921e2cb4bd7af9511f9088522eaa" + integrity sha1-Z9ldSyV6kh4stL16+VEfkIhSLqo= + +two-sum@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/two-sum/-/two-sum-1.0.0.tgz#31d3f32239e4f731eca9df9155e2b297f008ab64" + integrity sha1-MdPzIjnk9zHsqd+RVeKyl/AIq2Q= + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -7886,6 +10557,29 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-name@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/type-name/-/type-name-2.0.2.tgz#efe7d4123d8ac52afff7f40c7e4dec5266008fb4" + integrity sha1-7+fUEj2KxSr/9/QMfk3sUmYAj7Q= + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.1.0.tgz#9bdc22c648cf8cf86dd23d32336a41cfb6475e3f" + integrity sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA== + +typedarray-pool@^1.0.0, typedarray-pool@^1.0.2, typedarray-pool@^1.1.0, typedarray-pool@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/typedarray-pool/-/typedarray-pool-1.2.0.tgz#e7e90720144ba02b9ed660438af6f3aacfe33ac3" + integrity sha512-YTSQbzX43yvtpfRtIDAYygoYtgT+Rpjuxy9iOpczrjpXLgGoyG7aS5USJXV2d3nn8uHTeb9rXDvzS27zUg5KYQ== + dependencies: + bit-twiddle "^1.0.0" + dup "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -7929,6 +10623,16 @@ unicode-property-aliases-ecmascript@^1.0.4: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== +union-find@^1.0.0, union-find@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/union-find/-/union-find-1.0.2.tgz#292bac415e6ad3a89535d237010db4a536284e58" + integrity sha1-KSusQV5q06iVNdI3AQ20pTYoTlg= + +union-find@~0.0.3: + version "0.0.4" + resolved "https://registry.yarnpkg.com/union-find/-/union-find-0.0.4.tgz#b854b3301619bdad144b0014c78f96eac0d2f0f6" + integrity sha1-uFSzMBYZva0USwAUx4+W6sDS8PY= + union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -7939,6 +10643,11 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^2.0.1" +uniq@^1.0.0, uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" @@ -7966,6 +10675,11 @@ universalify@^0.1.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +unquote@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" + integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= + unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" @@ -7984,6 +10698,11 @@ upath@^1.1.1: resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== +update-diff@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/update-diff/-/update-diff-1.1.0.tgz#f510182d81ee819fb82c3a6b22b62bbdeda7808f" + integrity sha1-9RAYLYHugZ+4LDprIrYrve2ngI8= + uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" @@ -8038,6 +10757,45 @@ util@^0.11.0: dependencies: inherits "2.0.3" +utils-copy-error@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-copy-error/-/utils-copy-error-1.0.1.tgz#791de393c0f09890afd59f3cbea635f079a94fa5" + integrity sha1-eR3jk8DwmJCv1Z88vqY18HmpT6U= + dependencies: + object-keys "^1.0.9" + utils-copy "^1.1.0" + +utils-copy@^1.0.0, utils-copy@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/utils-copy/-/utils-copy-1.1.1.tgz#6e2b97982aa8cd73e1182a3e6f8bec3c0f4058a7" + integrity sha1-biuXmCqozXPhGCo+b4vsPA9AWKc= + dependencies: + const-pinf-float64 "^1.0.0" + object-keys "^1.0.9" + type-name "^2.0.0" + utils-copy-error "^1.0.0" + utils-indexof "^1.0.0" + utils-regex-from-string "^1.0.0" + validate.io-array "^1.0.3" + validate.io-buffer "^1.0.1" + validate.io-nonnegative-integer "^1.0.0" + +utils-indexof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/utils-indexof/-/utils-indexof-1.0.0.tgz#20feabf09ef1018b523643e8380e7bc83ec61b5c" + integrity sha1-IP6r8J7xAYtSNkPoOA57yD7GG1w= + dependencies: + validate.io-array-like "^1.0.1" + validate.io-integer-primitive "^1.0.0" + +utils-regex-from-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/utils-regex-from-string/-/utils-regex-from-string-1.0.0.tgz#fe1a2909f8de0ff0d5182c80fbc654d6a687d189" + integrity sha1-/hopCfjeD/DVGCyA+8ZU1qaH0Yk= + dependencies: + regex-regex "^1.0.0" + validate.io-string-primitive "^1.0.0" + uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" @@ -8051,6 +10809,77 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +validate.io-array-like@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/validate.io-array-like/-/validate.io-array-like-1.0.2.tgz#7af9f7eb7b51715beb2215668ec5cce54faddb5a" + integrity sha1-evn363tRcVvrIhVmjsXM5U+t21o= + dependencies: + const-max-uint32 "^1.0.2" + validate.io-integer-primitive "^1.0.0" + +validate.io-array@^1.0.3, validate.io-array@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/validate.io-array/-/validate.io-array-1.0.6.tgz#5b5a2cafd8f8b85abb2f886ba153f2d93a27774d" + integrity sha1-W1osr9j4uFq7L4hroVPy2Tond00= + +validate.io-buffer@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/validate.io-buffer/-/validate.io-buffer-1.0.2.tgz#852d6734021914d5d13afc32531761e3720ed44e" + integrity sha1-hS1nNAIZFNXROvwyUxdh43IO1E4= + +validate.io-integer-primitive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/validate.io-integer-primitive/-/validate.io-integer-primitive-1.0.0.tgz#a9aa010355fe8681c0fea6c1a74ad2419cadddc6" + integrity sha1-qaoBA1X+hoHA/qbBp0rSQZyt3cY= + dependencies: + validate.io-number-primitive "^1.0.0" + +validate.io-integer@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/validate.io-integer/-/validate.io-integer-1.0.5.tgz#168496480b95be2247ec443f2233de4f89878068" + integrity sha1-FoSWSAuVviJH7EQ/IjPeT4mHgGg= + dependencies: + validate.io-number "^1.0.3" + +validate.io-matrix-like@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/validate.io-matrix-like/-/validate.io-matrix-like-1.0.2.tgz#5ec32a75d0889dac736dea68bdd6145b155edfc3" + integrity sha1-XsMqddCInaxzbepovdYUWxVe38M= + +validate.io-ndarray-like@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/validate.io-ndarray-like/-/validate.io-ndarray-like-1.0.0.tgz#d8a3b0ed165bbf1d2fc0d0073270cfa552295919" + integrity sha1-2KOw7RZbvx0vwNAHMnDPpVIpWRk= + +validate.io-nonnegative-integer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/validate.io-nonnegative-integer/-/validate.io-nonnegative-integer-1.0.0.tgz#8069243a08c5f98e95413c929dfd7b18f3f6f29f" + integrity sha1-gGkkOgjF+Y6VQTySnf17GPP28p8= + dependencies: + validate.io-integer "^1.0.5" + +validate.io-number-primitive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/validate.io-number-primitive/-/validate.io-number-primitive-1.0.0.tgz#d2e01f202989369dcf1155449564203afe584e55" + integrity sha1-0uAfICmJNp3PEVVElWQgOv5YTlU= + +validate.io-number@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/validate.io-number/-/validate.io-number-1.0.3.tgz#f63ffeda248bf28a67a8d48e0e3b461a1665baf8" + integrity sha1-9j/+2iSL8opnqNSODjtGGhZluvg= + +validate.io-positive-integer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/validate.io-positive-integer/-/validate.io-positive-integer-1.0.0.tgz#7ed2d03b4c27558cc66a00aab0f0e921814a6582" + integrity sha1-ftLQO0wnVYzGagCqsPDpIYFKZYI= + dependencies: + validate.io-integer "^1.0.5" + +validate.io-string-primitive@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/validate.io-string-primitive/-/validate.io-string-primitive-1.0.1.tgz#b8135b9fb1372bde02fdd53ad1d0ccd6de798fee" + integrity sha1-uBNbn7E3K94C/dU60dDM1t55j+4= + value-equal@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" @@ -8061,6 +10890,19 @@ value-or-function@^3.0.0: resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" integrity sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM= +vectorize-text@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/vectorize-text/-/vectorize-text-3.2.1.tgz#85921abd9685af775fd20a01041a2837fe51bdb5" + integrity sha512-rGojF+D9BB96iPZPUitfq5kaiS6eCJmfEel0NXOK/MzZSuXGiwhoop80PtaDas9/Hg/oaox1tI9g3h93qpuspg== + dependencies: + cdt2d "^1.0.0" + clean-pslg "^1.1.0" + ndarray "^1.0.11" + planar-graph-to-polyline "^1.0.0" + simplify-planar-graph "^2.0.1" + surface-nets "^1.0.0" + triangulate-polyline "^1.0.0" + verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -8130,6 +10972,15 @@ vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== +vt-pbf@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/vt-pbf/-/vt-pbf-3.1.1.tgz#b0f627e39a10ce91d943b898ed2363d21899fb82" + integrity sha512-pHjWdrIoxurpmTcbfBWXaPwSmtPAHS105253P1qyEfSTV2HJddqjM+kIHquaT/L6lVJIk9ltTGc0IxR/G47hYA== + dependencies: + "@mapbox/point-geometry" "0.1.0" + "@mapbox/vector-tile" "^1.3.1" + pbf "^3.0.5" + wait-for-expect@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-1.3.0.tgz#65241ce355425f907f5d127bdb5e72c412ff830c" @@ -8171,6 +11022,23 @@ watchpack@^1.7.4: chokidar "^3.4.1" watchpack-chokidar2 "^2.0.0" +weak-map@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/weak-map/-/weak-map-1.0.5.tgz#79691584d98607f5070bd3b70a40e6bb22e401eb" + integrity sha1-eWkVhNmGB/UHC9O3CkDmuyLkAes= + +weakmap-shim@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/weakmap-shim/-/weakmap-shim-1.1.1.tgz#d65afd784109b2166e00ff571c33150ec2a40b49" + integrity sha1-1lr9eEEJshZuAP9XHDMVDsKkC0k= + +webgl-context@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/webgl-context/-/webgl-context-2.2.0.tgz#8f37d7257cf6df1cd0a49e6a7b1b721b94cc86a0" + integrity sha1-jzfXJXz23xzQpJ5qextyG5TMhqA= + dependencies: + get-canvas-context "^1.0.1" + webpack-sources@^1.4.0, webpack-sources@^1.4.1: version "1.4.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" @@ -8251,6 +11119,13 @@ worker-farm@^1.7.0: dependencies: errno "~0.1.7" +world-calendars@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/world-calendars/-/world-calendars-1.0.3.tgz#b25c5032ba24128ffc41d09faf4a5ec1b9c14335" + integrity sha1-slxQMrokEo/8QdCfr0pewbnBQzU= + dependencies: + object-assign "^4.1.0" + wrap-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" @@ -8298,11 +11173,16 @@ write@1.0.3: dependencies: mkdirp "^0.5.1" -xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== +xtend@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.2.0.tgz#eef6b1f198c1c8deafad8b1765a04dad4a01c5a9" + integrity sha1-7vax8ZjByN6vrYsXZaBNrUoBxak= + y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" @@ -8381,3 +11261,10 @@ yazl@^2.5.1: integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw== dependencies: buffer-crc32 "~0.2.3" + +zero-crossings@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/zero-crossings/-/zero-crossings-1.0.1.tgz#c562bd3113643f3443a245d12406b88b69b9a9ff" + integrity sha1-xWK9MRNkPzRDokXRJAa4i2m5qf8= + dependencies: + cwise-compiler "^1.0.0" From 5385d76a81d3e809f7b8c2990b39b2c554d801fb Mon Sep 17 00:00:00 2001 From: Yizhe Liu Date: Fri, 16 Oct 2020 01:09:03 -0700 Subject: [PATCH 2/8] Fix current broken UT --- .../__tests__/AnomaliesChart.test.tsx | 3 +- public/pages/EditFeatures/utils/helpers.ts | 2 +- public/utils/utils.tsx | 12 +- .../routes/utils/__tests__/adHelpers.test.ts | 144 +++++++++--------- test/setup.jest.ts | 4 + 5 files changed, 83 insertions(+), 82 deletions(-) diff --git a/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx b/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx index 6cb7da8b..3421f86b 100644 --- a/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx +++ b/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx @@ -19,6 +19,7 @@ import { AnomaliesChart } from '../AnomaliesChart'; import moment from 'moment'; import { initialState, mockedStore } from '../../../../redux/utils/testUtils'; import { Provider } from 'react-redux'; +import { INITIAL_ANOMALY_SUMMARY } from '../../utils/constants'; const initialStartTime = moment('2019-10-10T09:00:00'); const initialEndTime = initialStartTime.clone().add(2, 'd'); @@ -69,7 +70,7 @@ const renderDataFilter = () => ({ onZoomRangeChange={jest.fn()} title="test" bucketizedAnomalies={true} - anomalySummary={undefined} + anomalySummary={INITIAL_ANOMALY_SUMMARY} dateRange={dateRange} isLoading={false} anomalyGradeSeriesName="anomaly grade" diff --git a/public/pages/EditFeatures/utils/helpers.ts b/public/pages/EditFeatures/utils/helpers.ts index 14cfc10c..f5faa8be 100644 --- a/public/pages/EditFeatures/utils/helpers.ts +++ b/public/pages/EditFeatures/utils/helpers.ts @@ -112,7 +112,7 @@ export const validateFeatures = (values: any) => { hasError = true; // @ts-ignore return { - featureName: 'You must enter a feature name.', + featureName: 'You must enter a feature name', }; } }); diff --git a/public/utils/utils.tsx b/public/utils/utils.tsx index 93295884..d95dbe55 100644 --- a/public/utils/utils.tsx +++ b/public/utils/utils.tsx @@ -41,7 +41,7 @@ export const validateName = ( fieldName: string ): string | undefined => { if (isEmpty(name)) { - return `You must enter a ${fieldName} name.`; + return `You must enter a ${fieldName} name`; } if (name.length > MAX_FEATURE_NAME_SIZE) { return `Name is too big maximum limit is ${MAX_FEATURE_NAME_SIZE}`; @@ -57,7 +57,7 @@ export const isInvalid = (name: string, form: any) => export const getError = (name: string, form: any) => get(form.errors, name); export const requiredSelectField = (val: any): string | undefined => { - return required(val, 'You must select a field.'); + return required(val, 'You must select a field'); }; export const required = ( @@ -67,7 +67,7 @@ export const required = ( // if val is number, skip check as number value already exists const message = !isEmpty(customErrorMessage) ? customErrorMessage - : 'Required.'; + : 'Required'; return typeof val !== 'number' && !val ? message : undefined; }; @@ -77,16 +77,16 @@ export const requiredNonEmptyArray = ( ): string | undefined => { const message = !isEmpty(customErrorMessage) ? customErrorMessage - : 'Required.'; + : 'Required'; return !val || val.length === 0 ? message : undefined; }; export const requiredNonEmptyFieldSelected = (val: any): string | undefined => { - return requiredNonEmptyArray(val, 'You must select a field.'); + return requiredNonEmptyArray(val, 'You must select a field'); }; export const validateCategoryField = (val: any): string | undefined => { - return requiredNonEmptyArray(val, 'You must select a category field.'); + return requiredNonEmptyArray(val, 'You must select a category field'); }; export const validatePositiveInteger = (value: any) => { diff --git a/server/routes/utils/__tests__/adHelpers.test.ts b/server/routes/utils/__tests__/adHelpers.test.ts index ee64c5ab..92e7a21a 100644 --- a/server/routes/utils/__tests__/adHelpers.test.ts +++ b/server/routes/utils/__tests__/adHelpers.test.ts @@ -28,73 +28,71 @@ describe('adHelpers', () => { periodStart: 1596309273336, periodEnd: 1596914073336, detector: { - name: "test2", - description: "test", - timeField: "@timestamp", - indices: [ - "metricbeat-7.8.1" - ], + name: 'test2', + description: 'test', + timeField: '@timestamp', + indices: ['metricbeat-7.8.1'], detectionInterval: { period: { interval: 1, - unit: "Minutes" - } + unit: 'Minutes', + }, }, windowDelay: { period: { interval: 1, - unit: "Minutes" - } + unit: 'Minutes', + }, }, filterQuery: { bool: { filter: [ { term: { - "host.name": { - value: "myserver" - } - } - } - ] - } + 'host.name': { + value: 'myserver', + }, + }, + }, + ], + }, }, featureAttributes: [ { - featureId: "9lAlx3MBdAn13oNrKKPk", - featureName: "F1", + featureId: '9lAlx3MBdAn13oNrKKPk', + featureName: 'F1', featureEnabled: true, importance: 1, aggregationQuery: { f_1: { avg: { - field: "system.cpu.total.pct" - } - } - } - } + field: 'system.cpu.total.pct', + }, + }, + }, + }, ], uiMetadata: { features: { F1: { - featureType: "simple_aggs", - aggregationBy: "avg", - aggregationOf: "system.cpu.total.pct" - } + featureType: 'simple_aggs', + aggregationBy: 'avg', + aggregationOf: 'system.cpu.total.pct', + }, }, filters: [ { fieldInfo: [ { - label: "host.name", - type: "keyword" - } + label: 'host.name', + type: 'keyword', + }, ], - fieldValue: "myserver", - operator: "is" - } + fieldValue: 'myserver', + operator: 'is', + }, ], - filterType: "simple_filter" + filterType: 'simple_filter', }, }, }); @@ -102,75 +100,73 @@ describe('adHelpers', () => { period_start: 1596309273336, period_end: 1596914073336, detector: { - name: "test2", - description: "test", - time_field: "@timestamp", - indices: [ - "metricbeat-7.8.1" - ], + name: 'test2', + description: 'test', + time_field: '@timestamp', + indices: ['metricbeat-7.8.1'], detection_interval: { period: { interval: 1, - unit: "Minutes" - } + unit: 'Minutes', + }, }, window_delay: { period: { interval: 1, - unit: "Minutes" - } + unit: 'Minutes', + }, }, filter_query: { bool: { filter: [ { term: { - "host.name": { - value: "myserver" - } - } - } - ] - } + 'host.name': { + value: 'myserver', + }, + }, + }, + ], + }, }, feature_attributes: [ { - feature_id: "9lAlx3MBdAn13oNrKKPk", - feature_name: "F1", + feature_id: '9lAlx3MBdAn13oNrKKPk', + feature_name: 'F1', feature_enabled: true, importance: 1, aggregation_query: { f_1: { avg: { - field: "system.cpu.total.pct" - } - } - } - } + field: 'system.cpu.total.pct', + }, + }, + }, + }, ], ui_metadata: { features: { F1: { - featureType: "simple_aggs", - aggregationBy: "avg", - aggregationOf: "system.cpu.total.pct" - } + featureType: 'simple_aggs', + aggregationBy: 'avg', + aggregationOf: 'system.cpu.total.pct', + }, }, filters: [ { fieldInfo: [ { - label: "host.name", - type: "keyword" - } + label: 'host.name', + type: 'keyword', + }, ], - fieldValue: "myserver", - operator: "is" - } + fieldValue: 'myserver', + operator: 'is', + }, ], - filterType: "simple_filter" + filterType: 'simple_filter', }, - } + }, }); }); }); @@ -330,6 +326,7 @@ describe('adHelpers', () => { enabled: false, disabledTime: undefined, enabledTime: undefined, + categoryField: [], }); }); test('should not convert keys to camelCase for filterQuery', () => { @@ -381,9 +378,7 @@ describe('adHelpers', () => { }, }, uiMetadata: {}, - enabled: false, - disabledTime: undefined, - enabledTime: undefined, + categoryField: [], }); }); @@ -409,6 +404,7 @@ describe('adHelpers', () => { enabled: false, disabledTime: undefined, enabledTime: undefined, + categoryField: [], }); }); }); diff --git a/test/setup.jest.ts b/test/setup.jest.ts index 55e64453..acfe0ae3 100644 --- a/test/setup.jest.ts +++ b/test/setup.jest.ts @@ -57,3 +57,7 @@ jest.mock('ui/chrome', () => { }, }; }); + +// for Plotly +//@ts-ignore +window.URL.createObjectURL = function () {}; From f897be25b7f2322f9652b1223e82498076121b6e Mon Sep 17 00:00:00 2001 From: Yizhe Liu Date: Fri, 16 Oct 2020 12:31:57 -0700 Subject: [PATCH 3/8] Fix color scale and use undefined as default categoryField value --- public/pages/AnomalyCharts/utils/anomalyChartUtils.ts | 10 ++++++---- server/routes/utils/__tests__/adHelpers.test.ts | 6 +++--- server/routes/utils/adHelpers.ts | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts b/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts index 1bb0d29b..2d2ce1bd 100644 --- a/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts +++ b/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts @@ -153,14 +153,16 @@ export const disabledHistoryAnnotations = ( export const ANOMALY_HEATMAP_COLORSCALE = [ [0, '#F2F2F2'], - [0.2, '#F2F2F2'], + [0.0000001, '#F2F2F2'], + [0.0000001, '#F7E0B8'], [0.2, '#F7E0B8'], - [0.4, '#F7E0B8'], + [0.2, '#F2C596'], [0.4, '#F2C596'], - [0.6, '#F2C596'], + [0.4, '#ECA976'], [0.6, '#ECA976'], - [0.8, '#ECA976'], + [0.6, '#E78D5B'], [0.8, '#E78D5B'], + [0.8, '#E8664C'], [1, '#E8664C'], ]; diff --git a/server/routes/utils/__tests__/adHelpers.test.ts b/server/routes/utils/__tests__/adHelpers.test.ts index 92e7a21a..ed12e69b 100644 --- a/server/routes/utils/__tests__/adHelpers.test.ts +++ b/server/routes/utils/__tests__/adHelpers.test.ts @@ -326,7 +326,7 @@ describe('adHelpers', () => { enabled: false, disabledTime: undefined, enabledTime: undefined, - categoryField: [], + categoryField: undefined, }); }); test('should not convert keys to camelCase for filterQuery', () => { @@ -378,7 +378,7 @@ describe('adHelpers', () => { }, }, uiMetadata: {}, - categoryField: [], + categoryField: undefined, }); }); @@ -404,7 +404,7 @@ describe('adHelpers', () => { enabled: false, disabledTime: undefined, enabledTime: undefined, - categoryField: [], + categoryField: undefined, }); }); }); diff --git a/server/routes/utils/adHelpers.ts b/server/routes/utils/adHelpers.ts index 0ec0d377..8824fc98 100644 --- a/server/routes/utils/adHelpers.ts +++ b/server/routes/utils/adHelpers.ts @@ -74,7 +74,7 @@ export const convertDetectorKeysToCamelCase = (response: object) => { enabled: get(response, 'adJob.enabled', false), enabledTime: get(response, 'adJob.enabled_time'), disabledTime: get(response, 'adJob.disabled_time'), - categoryField: get(response, 'category_field', []), + categoryField: get(response, 'category_field'), }; }; From 4bcff0d34b2d589f1b844c0117255dd31e5c4d83 Mon Sep 17 00:00:00 2001 From: Yizhe Liu Date: Mon, 19 Oct 2020 13:22:02 -0700 Subject: [PATCH 4/8] Address PR comments --- .../containers/AnomaliesChart.tsx | 32 +++++--- .../containers/AnomalyDetailsChart.tsx | 70 ++++++++--------- .../containers/AnomalyHeatmapChart.tsx | 40 ++-------- .../containers/AnomalyOccurrenceChart.tsx | 21 ++--- .../containers/FeatureBreakDown.tsx | 14 ++-- .../__tests__/AnomaliesChart.test.tsx | 2 - .../AnomalyCharts/utils/anomalyChartUtils.ts | 76 ++++++++++++++++++- public/pages/AnomalyCharts/utils/constants.ts | 5 -- .../containers/AnomalyHistory.tsx | 5 +- .../containers/AnomalyResults.tsx | 4 +- .../containers/AnomalyResultsTable.tsx | 4 +- .../containers/SampleAnomalies.tsx | 14 ++-- .../containers/CreateDetector.tsx | 2 +- 13 files changed, 167 insertions(+), 122 deletions(-) diff --git a/public/pages/AnomalyCharts/containers/AnomaliesChart.tsx b/public/pages/AnomalyCharts/containers/AnomaliesChart.tsx index fb2b716d..9d423637 100644 --- a/public/pages/AnomalyCharts/containers/AnomaliesChart.tsx +++ b/public/pages/AnomalyCharts/containers/AnomaliesChart.tsx @@ -39,6 +39,12 @@ import { AnomalyHeatmapChart, HeatmapCell, } from '../containers/AnomalyHeatmapChart'; +import { + getAnomalyGradeWording, + getConfidenceWording, + getFeatureBreakdownWording, + getFeatureDataWording, +} from '../utils/anomalyChartUtils'; import { DATE_PICKER_QUICK_OPTIONS, INITIAL_ANOMALY_SUMMARY, @@ -59,8 +65,6 @@ interface AnomaliesChartProps { dateRange: DateRange; isLoading: boolean; showAlerts?: boolean; - anomalyGradeSeriesName: string; - confidenceSeriesName: string; detectorId: string; detectorName: string; detector?: Detector; @@ -213,7 +217,7 @@ export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => { unit={props.unit} onHeatmapCellSelected={props.onHeatmapCellSelected} />, - props.showAlerts === undefined || !props.showAlerts + props.showAlerts !== true ? [ , { bucketizedAnomalies={false} anomalySummary={INITIAL_ANOMALY_SUMMARY} isLoading={props.isLoading} - anomalyGradeSeriesName="Anomaly grade" - confidenceSeriesName="Confidence" - showAlerts={false} + anomalyGradeSeriesName={getAnomalyGradeWording( + props.showAlerts + )} + confidenceSeriesName={getConfidenceWording( + props.showAlerts + )} + showAlerts={props.showAlerts} detectorId={props.detectorId} detectorName={props.detectorName} detector={props.detector} @@ -248,7 +256,9 @@ export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => { />, , { isLoading={props.isLoading} //@ts-ignore dateRange={props.zoomRange} - featureDataSeriesName="Sample feature output" + featureDataSeriesName={getFeatureDataWording( + props.showAlerts + )} isHCDetector={props.isHCDetector} selectedHeatmapCell={props.selectedHeatmapCell} />, @@ -279,8 +291,8 @@ export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => { bucketizedAnomalies={props.bucketizedAnomalies} anomalySummary={props.anomalySummary} isLoading={props.isLoading} - anomalyGradeSeriesName="Anomaly grade" - confidenceSeriesName="Confidence" + anomalyGradeSeriesName={getAnomalyGradeWording(props.showAlerts)} + confidenceSeriesName={getConfidenceWording(props.showAlerts)} showAlerts={props.showAlerts} detectorId={props.detectorId} detectorName={props.detectorName} diff --git a/public/pages/AnomalyCharts/containers/AnomalyDetailsChart.tsx b/public/pages/AnomalyCharts/containers/AnomalyDetailsChart.tsx index 6544156e..4149141f 100644 --- a/public/pages/AnomalyCharts/containers/AnomalyDetailsChart.tsx +++ b/public/pages/AnomalyCharts/containers/AnomalyDetailsChart.tsx @@ -60,7 +60,11 @@ import { convertAlerts, disabledHistoryAnnotations, generateAlertAnnotations, + getAnomalyGradeWording, + getAnomalyOccurrenceWording, getAnomalySummary, + getConfidenceWording, + getLastAnomalyOccurrenceWording, } from '../utils/anomalyChartUtils'; import { ANOMALY_CHART_THEME, @@ -169,10 +173,9 @@ export const AnomalyDetailsChart = React.memo( } if ( props.monitor && - props.dateRange.startDate && + props.dateRange && // only load alert stats for non HC detector - props.isHCDetector != undefined && - !props.isHCDetector + props.isHCDetector !== true ) { getMonitorAlerts( props.monitor.id, @@ -180,7 +183,7 @@ export const AnomalyDetailsChart = React.memo( props.dateRange.endDate ); } - }, [props.monitor, props.dateRange.startDate]); + }, [props.monitor, props.dateRange.startDate, props.dateRange.endDate]); const anomalyChartTimeFormatter = niceTimeFormatter([ zoomRange.startDate, @@ -192,60 +195,41 @@ export const AnomalyDetailsChart = React.memo( handleZoomRangeChange(startDate, endDate); }; - const showLoader = useDelayedLoader(props.isLoading || isLoadingAlerts); + const isLoading = props.isLoading || isLoadingAlerts; + const showLoader = useDelayedLoader(isLoading); return ( @@ -255,7 +239,7 @@ export const AnomalyDetailsChart = React.memo( monitor={props.monitor} showAlertsFlyout={() => setShowAlertsFlyout(true)} totalAlerts={totalAlerts} - isLoading={props.isLoading} + isLoading={isLoading} /> ) : null} @@ -269,7 +253,7 @@ export const AnomalyDetailsChart = React.memo( opacity: showLoader ? 0.2 : 1, }} > - {props.isLoading || isLoadingAlerts ? ( + {isLoading ? ( setShowAlertsFlyout(false)} /> diff --git a/public/pages/AnomalyCharts/containers/AnomalyHeatmapChart.tsx b/public/pages/AnomalyCharts/containers/AnomalyHeatmapChart.tsx index 5c65106f..105346ca 100644 --- a/public/pages/AnomalyCharts/containers/AnomalyHeatmapChart.tsx +++ b/public/pages/AnomalyCharts/containers/AnomalyHeatmapChart.tsx @@ -42,6 +42,7 @@ import { sortHeatmapPlotData, filterHeatmapPlotDataByY, } from '../utils/anomalyChartUtils'; +import { MIN_IN_MILLI_SECS } from '../../../../server/utils/constants'; interface AnomalyHeatmapChartProps { title: string; @@ -126,7 +127,7 @@ export const AnomalyHeatmapChart = React.memo( originalHeatmapData ); - const [sortByFeildValue, setSortByFeildValue] = useState( + const [sortByFieldValue, setSortByFieldValue] = useState( SORT_BY_FIELD_OPTIONS[0].value ); @@ -198,11 +199,7 @@ export const AnomalyHeatmapChart = React.memo( const selectedStartDate = selectedEndDate - - getHeatmapCellDateRangeInterval( - //@ts-ignore - heatmapData[0].x, - selectedCellIndices[1] - ); + get(selectedHeatmapData, '[0].cellTimeInterval', MIN_IN_MILLI_SECS); props.onHeatmapCellSelected({ dateRange: { startDate: selectedStartDate, @@ -214,27 +211,6 @@ export const AnomalyHeatmapChart = React.memo( } }; - const getHeatmapCellDateRangeInterval = ( - dates: string[], - index: number - ) => { - if (dates.length < 2) { - // if only less than 2 dates in X axis, it means the props.dateRange is too small. - // we can just use props.dateRange interval for heatmap cell - return props.dateRange.endDate - props.dateRange.startDate; - } - let prevIndex = index; - let nextIndex = index + 1; - if (nextIndex >= dates.length) { - nextIndex = index; - prevIndex = index - 1; - } - return ( - moment(dates[nextIndex], HEATMAP_X_AXIS_DATE_FORMAT).valueOf() - - moment(dates[prevIndex], HEATMAP_X_AXIS_DATE_FORMAT).valueOf() - ); - }; - const getColorPaletteFlexItem = (hexCode: string) => { return ( @@ -255,7 +231,7 @@ export const AnomalyHeatmapChart = React.memo( const updateHeatmapPlotData = getAnomaliesHeatmapData( props.anomalies, props.dateRange, - sortByFeildValue, + sortByFieldValue, displayTopEntityNum ); setOriginalHeatmapData(updateHeatmapPlotData); @@ -279,7 +255,7 @@ export const AnomalyHeatmapChart = React.memo( const updateHeatmapPlotData = getAnomaliesHeatmapData( props.anomalies, props.dateRange, - sortByFeildValue, + sortByFieldValue, displayTopEntityNum ); setOriginalHeatmapData(updateHeatmapPlotData); @@ -302,7 +278,7 @@ export const AnomalyHeatmapChart = React.memo( let selectedHeatmapData = filterHeatmapPlotDataByY( originalHeatmapData[0], selectedYs, - sortByFeildValue + sortByFieldValue ); selectedHeatmapData.opacity = 1; @@ -317,7 +293,7 @@ export const AnomalyHeatmapChart = React.memo( }; const handleSortByFieldChange = (value: any) => { - setSortByFeildValue(value); + setSortByFieldValue(value); const sortedHeatmapData = sortHeatmapPlotData( heatmapData[0], value, @@ -373,7 +349,7 @@ export const AnomalyHeatmapChart = React.memo( handleSortByFieldChange(value)} hasDividers /> diff --git a/public/pages/AnomalyCharts/containers/AnomalyOccurrenceChart.tsx b/public/pages/AnomalyCharts/containers/AnomalyOccurrenceChart.tsx index 947066cd..8fa757f9 100644 --- a/public/pages/AnomalyCharts/containers/AnomalyOccurrenceChart.tsx +++ b/public/pages/AnomalyCharts/containers/AnomalyOccurrenceChart.tsx @@ -21,7 +21,10 @@ import { Monitor, Detector, DateRange } from '../../../models/interfaces'; import { AnomalyDetailsChart } from './AnomalyDetailsChart'; import { HeatmapCell } from './AnomalyHeatmapChart'; import { filterWithHeatmapFilter } from '../../utils/anomalyResultUtils'; -import { getAnomalySummary } from '../utils/anomalyChartUtils'; +import { + getAnomalySummary, + getDateRangeWithSelectedHeatmapCell, +} from '../utils/anomalyChartUtils'; interface AnomalyOccurrenceChartProps { onDateRangeChange( @@ -79,24 +82,22 @@ export const AnomalyOccurrenceChart = React.memo( } }; - const getDateRange = () => { - if (props.isHCDetector && props.selectedHeatmapCell) { - return props.selectedHeatmapCell.dateRange; - } - return props.dateRange; - }; return ( { return props.annotations; } }; - const getDateRange = () => { - if (props.isHCDetector && props.selectedHeatmapCell) { - return props.selectedHeatmapCell.dateRange; - } - return props.dateRange; - }; + return ( {props.title ? ( @@ -150,7 +146,11 @@ export const FeatureBreakDown = React.memo((props: FeatureBreakDownProps) => { )} annotations={getAnnotationData()} isLoading={props.isLoading} - dateRange={getDateRange()} + dateRange={getDateRangeWithSelectedHeatmapCell( + props.dateRange, + props.isHCDetector, + props.selectedHeatmapCell + )} featureType={ get( props, diff --git a/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx b/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx index 3421f86b..b5726375 100644 --- a/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx +++ b/public/pages/AnomalyCharts/containers/__tests__/AnomaliesChart.test.tsx @@ -73,8 +73,6 @@ const renderDataFilter = () => ({ anomalySummary={INITIAL_ANOMALY_SUMMARY} dateRange={dateRange} isLoading={false} - anomalyGradeSeriesName="anomaly grade" - confidenceSeriesName="confidence" detectorId="testDetectorId" detectorName="testDetectorName" anomaliesResult={anomaliesResult} diff --git a/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts b/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts index 2d2ce1bd..adb0d58f 100644 --- a/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts +++ b/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts @@ -27,6 +27,7 @@ import { DEFAULT_ANOMALY_SUMMARY } from './constants'; import { Datum, PlotData } from 'plotly.js'; import moment from 'moment'; import { calculateTimeWindowsWithMaxDataPoints } from '../../utils/anomalyResultUtils'; +import { HeatmapCell } from '../containers/AnomalyHeatmapChart'; export const convertAlerts = (response: any): MonitorAlert[] => { const alerts = get(response, 'data.response.alerts', []); @@ -171,14 +172,15 @@ export enum AnomalyHeatmapSortType { OCCURRENCES = 'by_occurrences', } -const getColorForValue = (value: number) => { +const getHeatmapColorByValue = (value: number) => { + // check if value is larger than largest value in color scale if ( value >= ANOMALY_HEATMAP_COLORSCALE[ANOMALY_HEATMAP_COLORSCALE.length - 1][0] ) { return ANOMALY_HEATMAP_COLORSCALE[ANOMALY_HEATMAP_COLORSCALE.length - 1][1]; } - + // check if value is smaller than smallest value in color scale if (value <= ANOMALY_HEATMAP_COLORSCALE[0][0]) { return ANOMALY_HEATMAP_COLORSCALE[0][1]; } @@ -215,6 +217,8 @@ export const getAnomaliesHeatmapData = ( if (isEmpty(entityAnomaliesMap)) { // put placeholder data so that heatmap won't look empty for (let i = 0; i < displayTopNum; i++) { + // using blank string with different length as entity values instead of + // only 1 whitesapce for all entities, to avoid heatmap with single row const blankStrValue = buildBlankStringWithLength(i); entityAnomaliesMap.set(blankStrValue, []); } @@ -232,6 +236,24 @@ export const getAnomaliesHeatmapData = ( entityAnomaliesMap.forEach((entityAnomalies, entity) => { const maxAnomalyGradesForEntity = [] as number[]; const numAnomalyGradesForEntity = [] as number[]; + if ( + (isEmpty(entityAnomalies) || + isEmpty( + entityAnomalies.filter( + (anomaly) => get(anomaly, 'anomalyGrade', 0) > 0 + ) + )) && + !isEmpty(entity.trim()) + ) { + console.log( + `find entity ${entity} with empty anomalies`, + entityAnomalies + ); + // skip non-blank entity with empty anomalies, + // keep blank entity as it is placeholder data + // for totally emtpy anomaly data state + return; + } entityValues.push(entity); timeWindows.forEach((timeWindow) => { const anomaliesInWindow = entityAnomalies.filter( @@ -281,6 +303,7 @@ export const getAnomaliesHeatmapData = ( 'Max anomaly grade: %{z}
' + 'Anomaly occurrences: %{text}' + '', + cellTimeInterval: timeWindows[0].endDate - timeWindows[0].startDate, } as PlotData; const resultPlotData = sortHeatmapPlotData(plotData, sortType, displayTopNum); return [resultPlotData]; @@ -414,7 +437,7 @@ export const getSelectedHeatmapCellPlotData = ( } selectedZData.push(row); } - const colorForCell = getColorForValue(selectedValue); + const colorForCell = getHeatmapColorByValue(selectedValue); //@ts-ignore return [ { @@ -430,3 +453,50 @@ export const getSelectedHeatmapCellPlotData = ( }, ] as PlotData[]; }; + +export const getAnomalyGradeWording = (isNotSample: boolean | undefined) => { + return isNotSample ? 'Anomaly grade' : 'Sample anomaly grade'; +}; + +export const getConfidenceWording = (isNotSample: boolean | undefined) => { + return isNotSample ? 'Confidence' : 'Sample confidence'; +}; + +export const getFeatureBreakdownWording = ( + isNotSample: boolean | undefined +) => { + return isNotSample ? 'Feature breakdown' : 'Sample feature breakdown'; +}; + +export const getFeatureDataWording = (isNotSample: boolean | undefined) => { + return isNotSample ? 'Feature output' : 'Sample feature output'; +}; + +export const getLastAnomalyOccurrenceWording = ( + isNotSample: boolean | undefined +) => { + return isNotSample + ? 'Last anomaly occurrence' + : 'Last sample anomaly occurrence'; +}; + +export const getAnomalyOccurrenceWording = ( + isNotSample: boolean | undefined +) => { + return isNotSample ? 'Anomaly occurrences' : 'Sample anomaly occurrences'; +}; + +export const getAnomalyHistoryWording = (isNotSample: boolean | undefined) => { + return isNotSample ? 'Anomaly history' : 'Sample anomaly history'; +}; + +export const getDateRangeWithSelectedHeatmapCell = ( + originalDateRange: DateRange, + isHCDetector: boolean | undefined, + heatmapCell: HeatmapCell | undefined +) => { + if (isHCDetector && heatmapCell) { + return heatmapCell.dateRange; + } + return originalDateRange; +}; diff --git a/public/pages/AnomalyCharts/utils/constants.ts b/public/pages/AnomalyCharts/utils/constants.ts index c359e24a..0d3abebd 100644 --- a/public/pages/AnomalyCharts/utils/constants.ts +++ b/public/pages/AnomalyCharts/utils/constants.ts @@ -22,11 +22,6 @@ export const INITIAL_ANOMALY_SUMMARY = { lastAnomalyOccurrence: '', }; -export enum ANOMALY_CHART_TITLE { - SAMPLE_ANOMALY_HISTORY = 'Sample anomaly history', - ANOMALY_HISTORY = 'Sample anomaly history', -} - export enum CHART_FIELDS { PLOT_TIME = 'plotTime', ANOMALY_GRADE = 'anomalyGrade', diff --git a/public/pages/DetectorResults/containers/AnomalyHistory.tsx b/public/pages/DetectorResults/containers/AnomalyHistory.tsx index f9274ea3..9de8668d 100644 --- a/public/pages/DetectorResults/containers/AnomalyHistory.tsx +++ b/public/pages/DetectorResults/containers/AnomalyHistory.tsx @@ -58,6 +58,7 @@ import { getDetectorResults } from '../../../redux/reducers/anomalyResults'; import { searchResults } from '../../../redux/reducers/anomalyResults'; import { AnomalyOccurrenceChart } from '../../AnomalyCharts/containers/AnomalyOccurrenceChart'; import { HeatmapCell } from '../../AnomalyCharts/containers/AnomalyHeatmapChart'; +import { getAnomalyHistoryWording } from '../../AnomalyCharts/utils/anomalyChartUtils'; interface AnomalyHistoryProps { detector: Detector; @@ -312,15 +313,13 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { return ( anomaly.anomalyGrade > 0) : []; - const sortFiledCompare = (field: string, sortDirection: SORT_DIRECTION) => { + const sortFieldCompare = (field: string, sortDirection: SORT_DIRECTION) => { return (a: any, b: any) => { if (get(a, `${field}`) > get(b, `${field}`)) return sortDirection === SORT_DIRECTION.ASC ? 1 : -1; @@ -85,7 +85,7 @@ export function AnomalyResultsTable(props: AnomalyResultsTableProps) { : []; anomalies.sort( - sortFiledCompare( + sortFieldCompare( state.queryParams.sortField, state.queryParams.sortDirection ) diff --git a/public/pages/EditFeatures/containers/SampleAnomalies.tsx b/public/pages/EditFeatures/containers/SampleAnomalies.tsx index 58dba756..960751d6 100644 --- a/public/pages/EditFeatures/containers/SampleAnomalies.tsx +++ b/public/pages/EditFeatures/containers/SampleAnomalies.tsx @@ -28,6 +28,11 @@ import { } from '@elastic/eui'; import { get, isEmpty } from 'lodash'; import moment from 'moment'; +import { + getAnomalyHistoryWording, + getFeatureBreakdownWording, + getFeatureDataWording, +} from '../../AnomalyCharts/utils/anomalyChartUtils'; import React, { Fragment, useCallback, useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; // @ts-ignore @@ -154,7 +159,6 @@ export function SampleAnomalies(props: SampleAnomaliesProps) { newDetector, true ); - console.log('updatedDetector in SampleAnomalies', updatedDetector); setPreviewDone(false); setZoomRange({ ...dateRange }); setNewDetector(updatedDetector); @@ -226,13 +230,11 @@ export function SampleAnomalies(props: SampleAnomaliesProps) { {!firstPreview ? ( ) : isHCDetector ? null : ( )} diff --git a/public/pages/createDetector/containers/CreateDetector.tsx b/public/pages/createDetector/containers/CreateDetector.tsx index c30c0b32..d4482db5 100644 --- a/public/pages/createDetector/containers/CreateDetector.tsx +++ b/public/pages/createDetector/containers/CreateDetector.tsx @@ -137,7 +137,7 @@ export function CreateDetector(props: CreateADProps) { try { const detectorResp = await dispatch(createDetector(detectorToBeCreated)); toastNotifications.addSuccess( - `Detector created: ${detectorResp.data.response.name}` + `Detector created: ${detectorToBeCreated.name}` ); props.history.push( `/detectors/${detectorResp.data.response.id}/configurations/` From 197014852e6aa662b16ae0189d471045f4108f03 Mon Sep 17 00:00:00 2001 From: Yizhe Liu Date: Mon, 19 Oct 2020 15:07:22 -0700 Subject: [PATCH 5/8] More refactoring --- .../containers/AnomaliesChart.tsx | 49 +++++++------------ .../containers/AnomalyDetailsChart.tsx | 8 +-- .../containers/AnomalyOccurrenceChart.tsx | 13 +---- .../__tests__/AnomaliesChart.test.tsx | 4 +- .../AnomalyCharts/utils/anomalyChartUtils.ts | 41 +++++++++------- .../containers/AnomalyHistory.tsx | 17 ------- .../containers/AnomalyResultsTable.tsx | 21 ++++---- .../containers/SampleAnomalies.tsx | 5 +- 8 files changed, 59 insertions(+), 99 deletions(-) diff --git a/public/pages/AnomalyCharts/containers/AnomaliesChart.tsx b/public/pages/AnomalyCharts/containers/AnomaliesChart.tsx index 9d423637..48567065 100644 --- a/public/pages/AnomalyCharts/containers/AnomaliesChart.tsx +++ b/public/pages/AnomalyCharts/containers/AnomaliesChart.tsx @@ -65,11 +65,7 @@ interface AnomaliesChartProps { dateRange: DateRange; isLoading: boolean; showAlerts?: boolean; - detectorId: string; - detectorName: string; - detector?: Detector; - detectorInterval?: number; - unit?: string; + detector: Detector; monitor?: Monitor; children: React.ReactNode | React.ReactNode[]; isHCDetector?: boolean; @@ -153,10 +149,14 @@ export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => { const setUpAlertsButton = () => ( ); @@ -204,8 +204,8 @@ export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => { ) : ( [ { isLoading={props.isLoading} showAlerts={props.showAlerts} monitor={props.monitor} - detectorInterval={props.detectorInterval} - unit={props.unit} + detectorInterval={get( + props.detector, + 'detectionInterval.period.interval' + )} + unit={get( + props.detector, + 'detectionInterval.period.unit' + )} onHeatmapCellSelected={props.onHeatmapCellSelected} />, props.showAlerts !== true @@ -240,17 +246,7 @@ export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => { props.showAlerts )} showAlerts={props.showAlerts} - detectorId={props.detectorId} - detectorName={props.detectorName} detector={props.detector} - detectorInterval={get( - props.detector, - 'detectionInterval.period.interval' - )} - unit={get( - props.detector, - 'detectionInterval.period.unit' - )} isHCDetector={props.isHCDetector} selectedHeatmapCell={props.selectedHeatmapCell} />, @@ -294,14 +290,7 @@ export const AnomaliesChart = React.memo((props: AnomaliesChartProps) => { anomalyGradeSeriesName={getAnomalyGradeWording(props.showAlerts)} confidenceSeriesName={getConfidenceWording(props.showAlerts)} showAlerts={props.showAlerts} - detectorId={props.detectorId} - detectorName={props.detectorName} detector={props.detector} - detectorInterval={get( - props.detector, - 'detectionInterval.period.interval' - )} - unit={get(props.detector, 'detectionInterval.period.unit')} monitor={props.monitor} isHCDetector={props.isHCDetector} onDatePickerRangeChange={handleDatePickerRangeChange} diff --git a/public/pages/AnomalyCharts/containers/AnomalyDetailsChart.tsx b/public/pages/AnomalyCharts/containers/AnomalyDetailsChart.tsx index 4149141f..821fc7cb 100644 --- a/public/pages/AnomalyCharts/containers/AnomalyDetailsChart.tsx +++ b/public/pages/AnomalyCharts/containers/AnomalyDetailsChart.tsx @@ -88,11 +88,7 @@ interface AnomalyDetailsChartProps { showAlerts?: boolean; anomalyGradeSeriesName: string; confidenceSeriesName: string; - detectorId: string; - detectorName: string; - detector?: Detector; - detectorInterval?: number; - unit?: string; + detector: Detector; monitor?: Monitor; isHCDetector?: boolean; selectedHeatmapCell?: HeatmapCell; @@ -356,9 +352,7 @@ export const AnomalyDetailsChart = React.memo( {showAlertsFlyout ? ( ({ anomalySummary={INITIAL_ANOMALY_SUMMARY} dateRange={dateRange} isLoading={false} - detectorId="testDetectorId" - detectorName="testDetectorName" anomaliesResult={anomaliesResult} + detector={getRandomDetector(true)} /> ), diff --git a/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts b/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts index adb0d58f..8fad176d 100644 --- a/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts +++ b/public/pages/AnomalyCharts/utils/anomalyChartUtils.ts @@ -213,7 +213,10 @@ export const getAnomaliesHeatmapData = ( sortType: AnomalyHeatmapSortType = AnomalyHeatmapSortType.SEVERITY, displayTopNum: number ): PlotData[] => { - const entityAnomaliesMap = getEntityAnomaliesMap(anomalies); + const entityAnomalyResultMap = getEntityAnomaliesMap(anomalies); + const entityAnomaliesMap = filterEntityAnomalyResultMap( + entityAnomalyResultMap + ); if (isEmpty(entityAnomaliesMap)) { // put placeholder data so that heatmap won't look empty for (let i = 0; i < displayTopNum; i++) { @@ -236,24 +239,7 @@ export const getAnomaliesHeatmapData = ( entityAnomaliesMap.forEach((entityAnomalies, entity) => { const maxAnomalyGradesForEntity = [] as number[]; const numAnomalyGradesForEntity = [] as number[]; - if ( - (isEmpty(entityAnomalies) || - isEmpty( - entityAnomalies.filter( - (anomaly) => get(anomaly, 'anomalyGrade', 0) > 0 - ) - )) && - !isEmpty(entity.trim()) - ) { - console.log( - `find entity ${entity} with empty anomalies`, - entityAnomalies - ); - // skip non-blank entity with empty anomalies, - // keep blank entity as it is placeholder data - // for totally emtpy anomaly data state - return; - } + entityValues.push(entity); timeWindows.forEach((timeWindow) => { const anomaliesInWindow = entityAnomalies.filter( @@ -328,6 +314,23 @@ const getEntityAnomaliesMap = (anomalies: any[]): Map => { return entityAnomaliesMap; }; +const filterEntityAnomalyResultMap = ( + entityAnomalyResultMap: Map +) => { + const entityAnomaliesMap = new Map(); + entityAnomalyResultMap.forEach((entityAnomalies, entity) => { + if ( + !isEmpty(entityAnomalies) && + !isEmpty( + entityAnomalies.filter((anomaly) => get(anomaly, 'anomalyGrade', 0) > 0) + ) + ) { + entityAnomaliesMap.set(entity, entityAnomalies); + } + }); + return entityAnomaliesMap; +}; + export const filterHeatmapPlotDataByY = ( heatmapData: PlotData, selectedYs: Datum[], diff --git a/public/pages/DetectorResults/containers/AnomalyHistory.tsx b/public/pages/DetectorResults/containers/AnomalyHistory.tsx index 9de8668d..0bb6005e 100644 --- a/public/pages/DetectorResults/containers/AnomalyHistory.tsx +++ b/public/pages/DetectorResults/containers/AnomalyHistory.tsx @@ -321,14 +321,7 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { anomalySummary={bucketizedAnomalySummary} isLoading={isLoading || isLoadingAnomalyResults} showAlerts={true} - detectorId={props.detector.id} - detectorName={props.detector.name} detector={props.detector} - detectorInterval={get( - props.detector, - 'detectionInterval.period.interval' - )} - unit={get(props.detector, 'detectionInterval.period.unit')} monitor={props.monitor} isHCDetector={isHCDetector} detectorCategoryField={detectorCategoryField} @@ -392,17 +385,7 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { anomalyGradeSeriesName="Anomaly grade" confidenceSeriesName="Confidence" showAlerts={true} - detectorId={props.detector.id} - detectorName={props.detector.name} detector={props.detector} - detectorInterval={get( - props.detector, - 'detectionInterval.period.interval' - )} - unit={get( - props.detector, - 'detectionInterval.period.unit' - )} monitor={props.monitor} isHCDetector={isHCDetector} selectedHeatmapCell={selectedHeatmapCell} diff --git a/public/pages/DetectorResults/containers/AnomalyResultsTable.tsx b/public/pages/DetectorResults/containers/AnomalyResultsTable.tsx index 2d7e060d..630aa3c1 100644 --- a/public/pages/DetectorResults/containers/AnomalyResultsTable.tsx +++ b/public/pages/DetectorResults/containers/AnomalyResultsTable.tsx @@ -34,7 +34,6 @@ import { ListControls } from '../components/ListControls/ListControls'; import { DetectorResultsQueryParams } from 'server/models/types'; import { AnomalyData } from '../../../models/interfaces'; import { getTitleWithCount } from '../../../utils/utils'; -import { HeatmapCell } from '../../AnomalyCharts/containers/AnomalyHeatmapChart'; interface AnomalyResultsTableProps { anomalies: AnomalyData[]; @@ -73,17 +72,19 @@ export function AnomalyResultsTable(props: AnomalyResultsTableProps) { }; useEffect(() => { - const anomalies = props.anomalies - ? props.anomalies - .filter((anomaly) => anomaly.anomalyGrade > 0) - .map((anomaly) => { - return { - ...anomaly, - [ENTITY_VALUE_FIELD]: get(anomaly, 'entity[0].value'), - }; - }) + let anomalies = props.anomalies + ? props.anomalies.filter((anomaly) => anomaly.anomalyGrade > 0) : []; + if (props.isHCDetector) { + anomalies = anomalies.map((anomaly) => { + return { + ...anomaly, + [ENTITY_VALUE_FIELD]: get(anomaly, 'entity[0].value'), + }; + }); + } + anomalies.sort( sortFieldCompare( state.queryParams.sortField, diff --git a/public/pages/EditFeatures/containers/SampleAnomalies.tsx b/public/pages/EditFeatures/containers/SampleAnomalies.tsx index 960751d6..822b99ac 100644 --- a/public/pages/EditFeatures/containers/SampleAnomalies.tsx +++ b/public/pages/EditFeatures/containers/SampleAnomalies.tsx @@ -235,8 +235,9 @@ export function SampleAnomalies(props: SampleAnomaliesProps) { onZoomRangeChange={handleZoomChange} isLoading={isLoading} dateRange={dateRange} - detectorId={props.detector.id} - detectorName={props.detector.name} + // detectorId={props.detector.id} + // detectorName={props.detector.name} + detector={props.detector} isHCDetector={isHCDetector} detectorCategoryField={newDetector.categoryField} onHeatmapCellSelected={handleHeatmapCellSelected} From 94247fc232dce6aa1ba8da88842d7910653fde2f Mon Sep 17 00:00:00 2001 From: Yizhe Liu Date: Mon, 19 Oct 2020 15:18:45 -0700 Subject: [PATCH 6/8] Rename anomalies.ts to previewAnomalies.ts --- public/pages/EditFeatures/containers/SampleAnomalies.tsx | 2 +- public/redux/reducers/index.ts | 4 ++-- public/redux/reducers/{anomalies.ts => previewAnomalies.ts} | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename public/redux/reducers/{anomalies.ts => previewAnomalies.ts} (97%) diff --git a/public/pages/EditFeatures/containers/SampleAnomalies.tsx b/public/pages/EditFeatures/containers/SampleAnomalies.tsx index 822b99ac..61eaca6e 100644 --- a/public/pages/EditFeatures/containers/SampleAnomalies.tsx +++ b/public/pages/EditFeatures/containers/SampleAnomalies.tsx @@ -40,7 +40,7 @@ import { toastNotifications } from 'ui/notify'; import ContentPanel from '../../../components/ContentPanel/ContentPanel'; import { DateRange, Detector } from '../../../models/interfaces'; import { AppState } from '../../../redux/reducers'; -import { previewDetector } from '../../../redux/reducers/anomalies'; +import { previewDetector } from '../../../redux/reducers/previewAnomalies'; import { AnomaliesChart } from '../../AnomalyCharts/containers/AnomaliesChart'; import { HeatmapCell } from '../../AnomalyCharts/containers/AnomalyHeatmapChart'; import { FeatureBreakDown } from '../../AnomalyCharts/containers/FeatureBreakDown'; diff --git a/public/redux/reducers/index.ts b/public/redux/reducers/index.ts index 1cc4b37f..ca1b8d4d 100644 --- a/public/redux/reducers/index.ts +++ b/public/redux/reducers/index.ts @@ -16,7 +16,7 @@ import { combineReducers } from 'redux'; import indicesReducer from './elasticsearch'; import adReducer from './ad'; -import anomalies from './anomalies'; +import previewAnomalies from './previewAnomalies'; import anomalyResults from './anomalyResults'; import liveAnomalyResults from './liveAnomalyResults'; import adAppReducer from './adAppReducer'; @@ -24,7 +24,7 @@ import alertingReducer from './alerting'; const rootReducer = combineReducers({ elasticsearch: indicesReducer, - anomalies: anomalies, + anomalies: previewAnomalies, anomalyResults: anomalyResults, liveAnomalyResults: liveAnomalyResults, ad: adReducer, diff --git a/public/redux/reducers/anomalies.ts b/public/redux/reducers/previewAnomalies.ts similarity index 97% rename from public/redux/reducers/anomalies.ts rename to public/redux/reducers/previewAnomalies.ts index 3663fd63..a820e107 100644 --- a/public/redux/reducers/anomalies.ts +++ b/public/redux/reducers/previewAnomalies.ts @@ -1,5 +1,5 @@ /* - * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. From e78a7725d8595cb116defc5ae6d21ff1fd8027bb Mon Sep 17 00:00:00 2001 From: Yizhe Liu Date: Mon, 19 Oct 2020 15:52:29 -0700 Subject: [PATCH 7/8] Load bucketized data only for single entity detector + address a few comments --- public/pages/DetectorResults/containers/AnomalyHistory.tsx | 3 ++- public/pages/EditFeatures/containers/SampleAnomalies.tsx | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/public/pages/DetectorResults/containers/AnomalyHistory.tsx b/public/pages/DetectorResults/containers/AnomalyHistory.tsx index 0bb6005e..151f19f4 100644 --- a/public/pages/DetectorResults/containers/AnomalyHistory.tsx +++ b/public/pages/DetectorResults/containers/AnomalyHistory.tsx @@ -146,8 +146,9 @@ export const AnomalyHistory = (props: AnomalyHistoryProps) => { fetchRawAnomalyResults(isHCDetector); if ( + !isHCDetector && dateRange.endDate - dateRange.startDate > - detectorInterval * MIN_IN_MILLI_SECS * MAX_ANOMALIES + detectorInterval * MIN_IN_MILLI_SECS * MAX_ANOMALIES ) { getBucketizedAnomalyResults(); } else { diff --git a/public/pages/EditFeatures/containers/SampleAnomalies.tsx b/public/pages/EditFeatures/containers/SampleAnomalies.tsx index 61eaca6e..4e1730a6 100644 --- a/public/pages/EditFeatures/containers/SampleAnomalies.tsx +++ b/public/pages/EditFeatures/containers/SampleAnomalies.tsx @@ -235,8 +235,6 @@ export function SampleAnomalies(props: SampleAnomaliesProps) { onZoomRangeChange={handleZoomChange} isLoading={isLoading} dateRange={dateRange} - // detectorId={props.detector.id} - // detectorName={props.detector.name} detector={props.detector} isHCDetector={isHCDetector} detectorCategoryField={newDetector.categoryField} From 8a6c8cc4f60bde06bf9d168e9fbd3d0f58eb797c Mon Sep 17 00:00:00 2001 From: Yizhe Liu Date: Mon, 19 Oct 2020 16:35:06 -0700 Subject: [PATCH 8/8] Hide init over time callout for HC detector --- public/pages/DetectorResults/containers/AnomalyResults.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/pages/DetectorResults/containers/AnomalyResults.tsx b/public/pages/DetectorResults/containers/AnomalyResults.tsx index ad28780b..23da717d 100644 --- a/public/pages/DetectorResults/containers/AnomalyResults.tsx +++ b/public/pages/DetectorResults/containers/AnomalyResults.tsx @@ -409,7 +409,7 @@ export function AnomalyResults(props: AnomalyResultsProps) { // don't show miss feature callout for HC detector (isDetectorMissingData && !isHCDetector) || isInitializingNormally || - isInitOvertime || + (isInitOvertime && !isHCDetector) || isDetectorFailed ? (