Merge branch 'master' of bitbucket.org:SanderVocke/digikam-fatclient

master
Sander Vocke 6 years ago
commit a38a2b1528
  1. 3
      package.json
  2. 1
      src/database.js
  3. 1
      src/main.js
  4. 60
      src/map.js
  5. 29
      src/queries.js
  6. 70
      src/resultsview.js
  7. 429
      src/userquerywidget.js
  8. 222
      yarn.lock

@ -12,12 +12,11 @@
"@testing-library/user-event": "^7.1.2",
"alasql": "^0.5.4",
"eslint-plugin-react-hooks": "^2.3.0",
"leaflet": "^1.6.0",
"lodash": "^4.17.15",
"lodash.clonedeep": "^4.5.0",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-grid-gallery": "^0.5.5",
"react-photo-gallery": "^8.0.0",
"react-scripts": "3.3.0",
"search-string": "^3.1.0",
"sql.js": "^1.1.0",

@ -16,7 +16,6 @@ export function alasql_async_queries(alasql_object, queries) {
var p = Promise.resolve(null);
for (let i = 0; i < queries.length; i++) {
p = p.then(() => {
console.log(queries[i]);
return alasql_object.promise(queries[i]);
});
}

@ -142,6 +142,7 @@ const theme = createMuiTheme({
},
});
export function MainPage() {
return (
<ThemeProvider theme={theme}>

@ -0,0 +1,60 @@
// TODO https://leafletjs.com/examples/quick-start/
import React, { useEffect, useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Box from '@material-ui/core/Box';
import "leaflet/dist/leaflet.css"
import L from 'leaflet';
export function MapView(props) {
const [map, setMap] = useState(null);
const [camera, setCameraNoPush] = useState([51.505, -0.09, 13]); //lat, long, zoom
var _ = require('lodash');
const id = _.uniqueId("leaflet_map_");
function updateCamera() {
var c = map.getCenter();
var z = map.getZoom();
setCameraNoPush([c[0], c[1], z]);
}
// Initialize the map on mount.
useEffect(() => {
setMap(L.map(id, {
center: [camera[0], camera[1]],
zoom: camera[2],
layers: [
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}),
]
}
));
}, [])
// Update camera state of this component when map changes.
useEffect(() => {
if (map != null) {
map.on('move', function (e) {
updateCamera();
});
map.on('zoom', function (e) {
updateCamera();
});
}
}, [ map ])
const style = {
width: "100%",
height: "600px",
};
return (
<Box>
<div id={id} style={style}></div>
</Box>
);
}

@ -8,18 +8,14 @@ export function escape_regex(s) {
export function do_image_query(query, database, collection_path, collection_thumbs_path) {
return new Promise(function (resolve, reject) {
var queries = [];
var ids = []; // TODO: this is for always uniquifying because of GROUP BY apparent bug in AlaSQL
queries.push(query);
database.queries_async(queries).then(res => {
var photos = [];
if (res && Array.isArray(res)) {
res.forEach(row => {
if (!ids.includes(row["id"])) { //uniquify
ids.push(row["id"]); //uniquify
var imagepath = process.env.PUBLIC_URL + collection_path + "/" + row["relativePath"] + "/" + row["name"];
var thumbpath = process.env.PUBLIC_URL + collection_thumbs_path + "/" + row["uniqueHash"] + ".jpg";
photos.push(create_photo(row["id"], row["name"], imagepath, thumbpath, [row["width"], row["height"]]));
}
var imagepath = process.env.PUBLIC_URL + collection_path + "/" + row["relativePath"] + "/" + row["name"];
var thumbpath = process.env.PUBLIC_URL + collection_thumbs_path + "/" + row["uniqueHash"] + ".jpg";
photos.push(create_photo(row["id"], row["name"], imagepath, thumbpath, [row["width"], row["height"]]));
});
}
resolve(photos);
@ -84,6 +80,7 @@ export class ResultFilter {
to_sql_where() { return "(1=1)"; }
is_true() { return false; }
is_false() { return false; }
is_negation() { return false; }
simplify() { return this; }
}
@ -109,17 +106,23 @@ export class NegationFilter extends ResultFilter {
body = new ConstFilter(this.return_type, false);
to_sql_where() {
return "NOT (" + this.body.to_sql_where + ")";
return "NOT (" + this.body.to_sql_where() + ")";
}
is_negation() { return true; }
simplify() {
var f = this.body.simplify();
console.log("NOT body:", f);
if (f.is_true()) {
return new ConstFilter(this.result_type, false);
}
if (f.is_false()) {
return new ConstFilter(this.result_type, true);
}
if (f.is_negation()) {
return f.body;
}
return this;
}
}
@ -224,11 +227,11 @@ export class UserQuery {
// This query will return database entries with the fields "id", "uniqueHash", "relativePath" (of the album) and "name" for each matching image.
export function image_query_with_where(maybe_where) {
return "SELECT Images.id, Images.name, Images.uniqueHash, Albums.relativePath, "
+ "ImageInformation.width, ImageInformation.height "
+ "FROM Images INNER JOIN Albums ON Images.album=Albums.id "
+ "LEFT JOIN ImageTags ON Images.id=ImageTags.imageid "
+ "LEFT JOIN ImageInformation ON Images.id=ImageInformation.imageid "
+ "LEFT JOIN Tags ON ImageTags.tagid=Tags.id " + (maybe_where ? maybe_where : "");
+ "ImageInformation.width, ImageInformation.height "
+ "FROM Images INNER JOIN Albums ON Images.album=Albums.id "
+ "LEFT JOIN ImageTags ON Images.id=ImageTags.imageid "
+ "LEFT JOIN ImageInformation ON Images.id=ImageInformation.imageid "
+ "LEFT JOIN Tags ON ImageTags.tagid=Tags.id " + (maybe_where ? maybe_where : "");
// TODO: the following for some reason breaks the query:
//+ " GROUP BY Images.id;";
}

@ -5,8 +5,12 @@ import Box from '@material-ui/core/Box';
import ImportContactsIcon from '@material-ui/icons/ImportContacts';
import Button from '@material-ui/core/Button';
import LabelIcon from '@material-ui/icons/Label';
import AppBar from '@material-ui/core/AppBar';
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';
import { GridGallery } from './gridgallery.js';
import { MapView } from './map.js';
const useStyles = makeStyles(theme => ({
root: {
@ -90,21 +94,63 @@ export function ImagesView(props) {
return <GridGallery {...props} />;
}
function TabPanel(props) {
const { children, activeIndex, myIndex } = props;
return (
<>
{activeIndex === myIndex && <Box>{children}</Box>}
</>
);
}
export function ResultsView(props) {
const classes = useStyles();
const { photos, albums, tags } = props;
const [ activeIndex, setActiveIndex ] = React.useState(0);
var _ = require('lodash');
function tabProps(index) {
return {
id: _.uniqueId("tab_"),
};
}
const handleChange = (e, newindex) => {
setActiveIndex(newindex);
}
return (
<Box className={classes.root}>
<Box className={classes.root}>
<ImagesView className={classes.root} photos={photos} />
</Box>
<Box className={classes.root}>
<AlbumsView className={classes.root} albums={albums} />
</Box>
<Box className={classes.root}>
<TagsView className={classes.root} tags={tags} />
</Box>
</Box>
)
<div className={classes.root}>
<AppBar position="static">
<Tabs value={activeIndex} onChange={handleChange}>
<Tab label="Images" {...tabProps(0)} />
<Tab label="Albums" {...tabProps(1)} />
<Tab label="Tags" {...tabProps(2)} />
<Tab label="Map" {...tabProps(3)} />
</Tabs>
</AppBar>
<TabPanel activeIndex={activeIndex} myIndex={0}>
<Box className={classes.root}>
<ImagesView className={classes.root} photos={photos} />
</Box>
</TabPanel>
<TabPanel activeIndex={activeIndex} myIndex={1}>
<Box className={classes.root}>
<AlbumsView className={classes.root} albums={albums} />
</Box>
</TabPanel>
<TabPanel activeIndex={activeIndex} myIndex={2}>
<Box className={classes.root}>
<TagsView className={classes.root} tags={tags} />
</Box>
</TabPanel>
<TabPanel activeIndex={activeIndex} myIndex={3}>
<Box className={classes.root}>
<MapView></MapView>
</Box>
</TabPanel>
</div>
);
}

@ -1,20 +1,28 @@
import React from 'react';
import React, { useEffect } from 'react';
import Switch from '@material-ui/core/Switch';
import Box from '@material-ui/core/Box';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import FormControl from '@material-ui/core/FormControl';
import Button from '@material-ui/core/Button';
import LabelIcon from '@material-ui/icons/Label';
import ImportContactsIcon from '@material-ui/icons/ImportContacts';
import PhotoIcon from '@material-ui/icons/Photo';
import SearchIcon from '@material-ui/icons/Search';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import DialogTitle from '@material-ui/core/DialogTitle';
import Dialog from '@material-ui/core/Dialog';
import Select from '@material-ui/core/Select';
import TextField from '@material-ui/core/TextField';
import { makeStyles } from '@material-ui/core/styles';
import {
filter_is_const_false, ConstFilter, LogicalOperatorFilter, MatchingFilter,
ResultTypeEnum, LogicalOperatorEnum, MatchTypeEnum
ResultTypeEnum, LogicalOperatorEnum, MatchTypeEnum, NegationFilter
} from './queries.js'
import { Typography } from '@material-ui/core';
const useStyles = makeStyles(theme => ({
root: {},
@ -40,14 +48,202 @@ const useStyles = makeStyles(theme => ({
},
}));
export function EditConstFilterExpression(props) {
const { onChange, filter } = props;
var _ = require('lodash');
function handleResultToggled() {
var newfilter = _.cloneDeep(filter);
newfilter.constval = !filter.constval;
onChange(newfilter);
}
return (
<FormControlLabel
control={
<Switch
checked={filter.constval}
onChange={handleResultToggled}
color="primary"
/>
}
label={filter.constval ? "TRUE" : "FALSE"}
/>
);
}
export function EditLogicalOperatorFilterExpression(props) {
const { onChange, filter } = props;
var _ = require('lodash');
const id = _.uniqueId("logic_op_");
const labelid = _.uniqueId("logic_op_label_");
function handleChange(e) {
var newfilter = _.cloneDeep(filter);
newfilter.operator = e.target.value;
onChange(newfilter);
}
return (
<FormControl>
<Select
labelId={labelid}
id={id}
value={filter.operator}
onChange={handleChange}
>
<MenuItem value={LogicalOperatorEnum.AND}>AND</MenuItem>
<MenuItem value={LogicalOperatorEnum.OR}>OR</MenuItem>
</Select>
</FormControl>
);
}
export function EditMatchingFilterExpression(props) {
const { onChange, filter } = props;
const classes = useStyles();
function handleTypeChange(e) {
var new_filter = _.cloneDeep(filter);
new_filter.match_type = e.target.value;
onChange(new_filter);
}
function handleMatchChange(e) {
var new_filter = _.cloneDeep(filter);
new_filter.match_from = e.target.value;
onChange(new_filter);
}
var _ = require('lodash');
const typeSelectId = _.uniqueId("select_");
const typeSelectLabelId = _.uniqueId("select_label_");
return (
<FormControl>
<Typography className={classes.margined}>TODO: make nice icons and autocomplete here</Typography>
<Select
className={classes.margined}
labelId={typeSelectLabelId}
id={typeSelectId}
value={filter.match_type}
onChange={handleTypeChange}
>
<MenuItem value={MatchTypeEnum.MATCH_IMAGE_NAME_EQUALS}>Image Name Equals</MenuItem>
<MenuItem value={MatchTypeEnum.MATCH_IMAGE_NAME_NATURAL}>Image Name Natural</MenuItem>
<MenuItem value={MatchTypeEnum.MATCH_ALBUM_EQUALS}>Album Equals</MenuItem>
<MenuItem value={MatchTypeEnum.MATCH_ALBUM_EQUALS_OR_CHILD}>Album Equals Or Child</MenuItem>
<MenuItem value={MatchTypeEnum.MATCH_ALBUM_NATURAL}>Album Natural</MenuItem>
<MenuItem value={MatchTypeEnum.MATCH_ALBUM_NAME_EQUALS}>Album Name Equals</MenuItem>
<MenuItem value={MatchTypeEnum.MATCH_TAG_EQUALS}>Tag Equals</MenuItem>
</Select>
<TextField className={classes.margined} label="Value" type="text" onChange={handleMatchChange} />
</FormControl>
);
}
export function EditFilterExpressionDialog(props) {
const classes = useStyles();
const { onClose, startingFilter, open } = props;
const [filter, setFilter] = React.useState(startingFilter);
const FilterTypeEnum = {
CONST: 0,
NEGATION: 1,
MATCHING: 2,
LOGICAL: 3,
};
useEffect(() => {
setFilter(startingFilter);
}, [startingFilter]);
const handleClose = () => {
onClose(filter);
};
const handleTypeChange = e => {
var val = e.target.value;
if (val == FilterTypeEnum.CONST) {
setFilter(new ConstFilter(filter.result_type, true));
} else if (val == FilterTypeEnum.MATCHING) {
setFilter(new MatchingFilter(filter.result_type, "", MatchTypeEnum.MATCH_IMAGE_NAME_NATURAL));
} else {
throw new Error('Unsupported filter type: ' + val);
}
}
const getFilterType = filter => {
if (filter instanceof ConstFilter) { return FilterTypeEnum.CONST; }
else if (filter instanceof NegationFilter) { return FilterTypeEnum.NEGATION; }
else if (filter instanceof MatchingFilter) { return FilterTypeEnum.MATCHING; }
else if (filter instanceof LogicalOperatorFilter) { return FilterTypeEnum.LOGICAL; }
else {
throw new Error('Unsupported filter type: ' + filter);
}
}
var _ = require('lodash');
const id = _.uniqueId("simple_dialog_title_");
const selectId = _.uniqueId("select_");
const selectLabelId = _.uniqueId("select_label_");
var control = <></>;
var subprops = {
onChange: setFilter,
filter: filter,
};
if (filter instanceof ConstFilter) {
control = <EditConstFilterExpression {...subprops} />
} else if (filter instanceof LogicalOperatorFilter) {
control = <EditLogicalOperatorFilterExpression {...subprops} />
} else if (filter instanceof MatchingFilter) {
control = <EditMatchingFilterExpression {...subprops} />
}
// If this is a "leaf" filter, we will allow changing the filter type in the dialog.
// But if it is a combination filter (i.e. AND / OR / NOT), we won't allow it because
// That throws away all its children.
const allowTypeChange =
(filter instanceof ConstFilter) ||
(filter instanceof MatchingFilter);
return (
<Dialog aria-labelledby={id} open={open}>
<DialogTitle id={id}>Edit expression</DialogTitle>
{allowTypeChange &&
<FormControl className={classes.margined}>
<Select
labelId={selectLabelId}
id={selectId}
value={getFilterType(filter)}
onChange={handleTypeChange}
>
<MenuItem value={FilterTypeEnum.CONST}>Constant</MenuItem>
<MenuItem value={FilterTypeEnum.MATCHING}>Matching</MenuItem>
</Select>
</FormControl>
}
{control}
<Button onClick={handleClose} className={classes.margined}>
Done
</Button>
</Dialog>
);
}
export function TagEqualsExpressionControl(props) {
const classes = useStyles();
const { name } = props;
const { name, onClick } = props;
return (
<>
<Button
variant="outlined"
className={classes.filterexpcontrol}
aria-controls="simple-menu" aria-haspopup="true"
onClick={onClick}
startIcon={<LabelIcon />}>
{name}
</Button>
@ -57,12 +253,14 @@ export function TagEqualsExpressionControl(props) {
export function AlbumEqualsExpressionControl(props) {
const classes = useStyles();
const { name } = props;
const { name, onClick } = props;
return (
<>
<Button
variant="outlined"
className={classes.filterexpcontrol}
aria-controls="simple-menu" aria-haspopup="true"
onClick={onClick}
startIcon={<ImportContactsIcon />}>
{name}
</Button>
@ -72,12 +270,14 @@ export function AlbumEqualsExpressionControl(props) {
export function ImageNameEqualsExpressionControl(props) {
const classes = useStyles();
const { name } = props;
const { name, onClick } = props;
return (
<>
<Button
variant="outlined"
className={classes.filterexpcontrol}
aria-controls="simple-menu" aria-haspopup="true"
onClick={onClick}
startIcon={<PhotoIcon />}>
{name}
</Button>
@ -87,12 +287,14 @@ export function ImageNameEqualsExpressionControl(props) {
export function ImageNameNaturalMatchExpressionControl(props) {
const classes = useStyles();
const { name } = props;
const { name, onClick } = props;
return (
<>
<Button
variant="outlined"
className={classes.filterexpcontrol}
aria-controls="simple-menu" aria-haspopup="true"
onClick={onClick}
startIcon={<><PhotoIcon /><SearchIcon /></>}>
{name}
</Button>
@ -102,23 +304,23 @@ export function ImageNameNaturalMatchExpressionControl(props) {
export function MatchingFilterExpressionControl(props) {
const classes = useStyles();
const { expr } = props;
const { expr, onClick } = props;
var pretty_name = expr.match_from
.replace(/^"/g, '')
.replace(/"$/g, '');
if (expr.match_type === MatchTypeEnum.MATCH_TAG_EQUALS) {
return <TagEqualsExpressionControl name={pretty_name} />
return <TagEqualsExpressionControl name={pretty_name} onClick={onClick} />
} else if (expr.match_type === MatchTypeEnum.MATCH_ALBUM_EQUALS) {
return <AlbumEqualsExpressionControl name={pretty_name} />
return <AlbumEqualsExpressionControl name={pretty_name} onClick={onClick} />
} else if (expr.match_type === MatchTypeEnum.MATCH_ALBUM_EQUALS_OR_CHILD) {
return <AlbumEqualsExpressionControl name={pretty_name + '(/...)'} />
return <AlbumEqualsExpressionControl name={pretty_name + '(/...)'} onClick={onClick} />
} else if (expr.match_type === MatchTypeEnum.MATCH_IMAGE_NAME_EQUALS) {
return <ImageNameEqualsExpressionControl name={pretty_name} />
return <ImageNameEqualsExpressionControl name={pretty_name} onClick={onClick} />
} else if (expr.match_type === MatchTypeEnum.MATCH_IMAGE_NAME_NATURAL) {
return <ImageNameNaturalMatchExpressionControl name={pretty_name} />
return <ImageNameNaturalMatchExpressionControl name={pretty_name} onClick={onClick} />
} else if (expr.match_type === MatchTypeEnum.MATCH_ALBUM_NAME_EQUALS) {
return <AlbumEqualsExpressionControl name={'(.../)' + pretty_name + '(/...)'} />
return <AlbumEqualsExpressionControl name={'(.../)' + pretty_name + '(/...)'} onClick={onClick} />
}
throw new Error('Cannot render matching filter control: unsupported type.');
@ -126,7 +328,7 @@ export function MatchingFilterExpressionControl(props) {
export function LogicalOperatorFilterExpressionControl(props) {
const classes = useStyles();
const { expr } = props;
const { expr, onClick, onChange } = props;
var opstring = "";
if (expr.operator === LogicalOperatorEnum.AND) {
@ -135,24 +337,49 @@ export function LogicalOperatorFilterExpressionControl(props) {
opstring = " OR ";
}
var _ = require('lodash');
const handleAChanged = (new_a) => {
if (new_a == null) {
onChange(expr.sub_filter_b);
return;
}
var new_me = _.cloneDeep(expr);
new_me.sub_filter_a = new_a;
onChange(new_me);
}
const handleBChanged = (new_b) => {
if (new_b == null) {
onChange(expr.sub_filter_a);
return;
}
var new_me = _.cloneDeep(expr);
new_me.sub_filter_b = new_b;
onChange(new_me);
}
return (
<>
<Box className={classes.logic_op_outer}>
<Box className={classes.logic_op_sbs}>
<Box>
<Box className={classes.logic_op_subexpr}>
<FilterExpressionControl expr={expr.sub_filter_a} />
<FilterExpressionControl expr={expr.sub_filter_a} onChange={handleAChanged} isRoot={false} />
</Box>
</Box>
<Box>
<Box className={classes.logic_op_subexpr}>
<FilterExpressionControl expr={expr.sub_filter_b} />
<FilterExpressionControl expr={expr.sub_filter_b} onChange={handleBChanged} isRoot={false} />
</Box>
</Box>
</Box>
<Button
variant="outlined"
className={classes.filterexpcontrol + " " + classes.logic_op_sbs}>
className={classes.filterexpcontrol + " " + classes.logic_op_sbs}
aria-controls="simple-menu" aria-haspopup="true"
onClick={onClick}
>
{opstring}
</Button>
</Box>
@ -162,33 +389,184 @@ export function LogicalOperatorFilterExpressionControl(props) {
export function ConstFilterExpressionControl(props) {
const classes = useStyles();
const { expr } = props;
const { expr, onClick } = props;
return (
<Button variant="outlined" className={classes.filterexpcontrol}>
<Button
variant="outlined"
className={classes.filterexpcontrol}
aria-controls="simple-menu" aria-haspopup="true"
onClick={onClick}
>
{JSON.stringify(expr.constval)}
</Button>
);
}
export function NegationExpressionControl(props) {
const classes = useStyles();
const { expr, onClick, onChange } = props;
var _ = require('lodash');
function handleBodyChanged(body) {
var new_filter = _.cloneDeep(expr);
new_filter.body = body;
onChange(new_filter);
}
return (
<>
<Box className={classes.logic_op_outer}>
<Box className={classes.logic_op_sbs}>
<Box>
<Box className={classes.logic_op_subexpr}>
<FilterExpressionControl expr={expr.body} onChange={handleBodyChanged} isRoot={false} />
</Box>
</Box>
</Box>
<Button
variant="outlined"
className={classes.filterexpcontrol + " " + classes.logic_op_sbs}
aria-controls="simple-menu" aria-haspopup="true"
onClick={onClick}
>
NOT
</Button>
</Box>
</>
)
}
export function FilterExpressionControl(props) {
const { expr } = props;
const { expr, onChange, isRoot } = props;
const [anchorEl, setAnchorEl] = React.useState(null);
const [editDialogOpen, setEditDialogOpen] = React.useState(false);
const [combineDialogOpen, setCombineDialogOpen] = React.useState(false);
const [combineExpr, setCombineExpr] = React.useState(new LogicalOperatorFilter(
expr.result_type,
expr,
new ConstFilter(expr.result_type, true),
LogicalOperatorEnum.AND)
);
var _ = require('lodash');
const menu_id = _.uniqueId("filter_menu_");
const handleClick = event => {
setAnchorEl(event.currentTarget);
};
const handleCloseMenu = () => {
setAnchorEl(null);
};
const handleOpenEditDialog = (filter) => {
handleCloseMenu();
setEditDialogOpen(true);
}
const handleCloseEditFilterDialog = (filter) => {
setEditDialogOpen(false);
onChange(filter.simplify());
};
const handleRemove = () => {
// For negation filters, removal means replacing the negation node by its child.
// In all other cases, removal means complete deletion of the subtree.
if (expr instanceof NegationFilter) {
onChange(expr.body);
return;
}
onChange(null);
}
const handleCloseCombineDialog = (filter) => {
setCombineDialogOpen(false);
var new_filter = _.cloneDeep(combineExpr);
new_filter.sub_filter_b = filter;
onChange(new_filter.simplify());
}
const handleAnd = () => {
handleCloseMenu();
setCombineExpr(new LogicalOperatorFilter(
expr.result_type,
expr,
new ConstFilter(expr.result_type, true), LogicalOperatorEnum.AND
));
setCombineDialogOpen(true);
}
const handleOr = () => {
handleCloseMenu();
setCombineExpr(new LogicalOperatorFilter(
expr.result_type,
expr,
new ConstFilter(expr.result_type, true), LogicalOperatorEnum.OR
));
setCombineDialogOpen(true);
}
const handleNegation = () => {
handleCloseMenu();
var new_filter = new NegationFilter(expr.result_type, expr);
onChange(new_filter.simplify());
}
var filter_elem = false;
if (expr instanceof ConstFilter) {
return <ConstFilterExpressionControl {...props} />
filter_elem = <ConstFilterExpressionControl {...props} onClick={handleClick} />
} else if (expr instanceof LogicalOperatorFilter) {
return <LogicalOperatorFilterExpressionControl {...props} />
filter_elem = <LogicalOperatorFilterExpressionControl {...props} onClick={handleClick} onChange={onChange} />
} else if (expr instanceof MatchingFilter) {
return <MatchingFilterExpressionControl {...props} />
filter_elem = <MatchingFilterExpressionControl {...props} onClick={handleClick} />
} else if (expr instanceof NegationFilter) {
filter_elem = <NegationExpressionControl {...props} onClick={handleClick} onChange={onChange} />
} else {
throw new Error('Unsupported filter expression');
}
throw new Error('Unsupported filter expression');
// If this is the root node, removing it is not allowed.
// Other nodes may be removed.
// The only exception is a negation node: removing that will replace it by its child.
var allowRemove = !isRoot || (expr instanceof NegationFilter);
return (
<>
{filter_elem}
<Menu
id={menu_id}
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleCloseMenu}
>
<MenuItem onClick={handleOpenEditDialog}>Edit...</MenuItem>
<MenuItem onClick={handleAnd}>And...</MenuItem>
<MenuItem onClick={handleOr}>Or...</MenuItem>
<MenuItem onClick={handleNegation}>Negate</MenuItem>
{allowRemove && <MenuItem onClick={handleRemove}>Remove</MenuItem>}
</Menu>
<EditFilterExpressionDialog
onClose={handleCloseEditFilterDialog}
startingFilter={expr}
open={editDialogOpen}
/>
<EditFilterExpressionDialog
onClose={handleCloseCombineDialog}
startingFilter={combineExpr.sub_filter_b}
open={combineDialogOpen}
/>
</>
);
}
export function FilterControl(props) {
const classes = useStyles();
const { filter, onChange, resultType, resultTypeString } = props;
const enabled = !filter_is_const_false(filter);
function handleResultToggled() {
if (enabled) {
onChange(new ConstFilter(resultType, false));
@ -198,7 +576,6 @@ export function FilterControl(props) {
}
}
const enabled = !filter_is_const_false(filter);
return (
<>
<Box className={classes.filtercontrol}>
@ -212,7 +589,7 @@ export function FilterControl(props) {
}
label={resultTypeString + ':'}
/>
<FilterExpressionControl expr={filter} />
<FilterExpressionControl expr={filter} onChange={onChange} isRoot={true} />
</Box>
</>
);

@ -1844,11 +1844,6 @@ abab@^2.0.0:
resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a"
integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==
abbrev@1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
version "1.3.7"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
@ -2029,19 +2024,11 @@ aphrodite@^0.5.0:
asap "^2.0.3"
inline-style-prefixer "^2.0.0"
aproba@^1.0.3, aproba@^1.1.1:
aproba@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
are-we-there-yet@~1.1.2:
version "1.1.5"
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21"
integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==
dependencies:
delegates "^1.0.0"
readable-stream "^2.0.6"
argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
@ -3123,11 +3110,6 @@ console-browserify@^1.1.0:
resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==
console-control-strings@^1.0.0, console-control-strings@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
constants-browserify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
@ -3582,7 +3564,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
dependencies:
ms "2.0.0"
debug@^3.0.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6:
debug@^3.0.0, debug@^3.1.1, debug@^3.2.5:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
@ -3618,11 +3600,6 @@ deep-equal@^1.0.1:
object-keys "^1.1.1"
regexp.prototype.flags "^1.2.0"
deep-extend@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
deep-is@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
@ -3683,11 +3660,6 @@ delayed-stream@~1.0.0:
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
depd@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
@ -3706,11 +3678,6 @@ destroy@~1.0.4:
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
detect-libc@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
detect-newline@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
@ -4774,13 +4741,6 @@ fs-extra@^8.1.0:
jsonfile "^4.0.0"
universalify "^0.1.0"
fs-minipass@^1.2.5:
version "1.2.7"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==
dependencies:
minipass "^2.6.0"
fs-minipass@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
@ -4826,20 +4786,6 @@ functional-red-black-tree@^1.0.1:
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
gauge@~2.7.3:
version "2.7.4"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=
dependencies:
aproba "^1.0.3"
console-control-strings "^1.0.0"
has-unicode "^2.0.0"
object-assign "^4.1.0"
signal-exit "^3.0.0"
string-width "^1.0.1"
strip-ansi "^3.0.1"
wide-align "^1.1.0"
gensync@^1.0.0-beta.1:
version "1.0.0-beta.1"
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269"
@ -5021,11 +4967,6 @@ has-symbols@^1.0.0, has-symbols@^1.0.1:
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=
has-value@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f"
@ -5270,7 +5211,7 @@ hyphenate-style-name@^1.0.1, hyphenate-style-name@^1.0.3:
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz#097bb7fa0b8f1a9cf0bd5c734cf95899981a9b48"
integrity sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ==
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
iconv-lite@0.4.24, iconv-lite@^0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
@ -5301,13 +5242,6 @@ iferr@^0.1.5:
resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501"
integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE=
ignore-walk@^3.0.1:
version "3.0.3"
resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37"
integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==
dependencies:
minimatch "^3.0.4"
ignore@^3.3.5:
version "3.3.10"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043"
@ -5404,7 +5338,7 @@ inherits@2.0.3:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
ini@^1.3.5, ini@~1.3.0:
ini@^1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
@ -6550,6 +6484,11 @@ lcid@^2.0.0:
dependencies:
invert-kv "^2.0.0"
leaflet@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.6.0.tgz#aecbb044b949ec29469eeb31c77a88e2f448f308"
integrity sha512-CPkhyqWUKZKFJ6K8umN5/D2wrJ2+/8UIpXppY7QDnUZW5bZL5+SEI2J7GBpwh4LIupOKqbNSQXgqmrEJopHVNQ==
left-pad@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e"
@ -6960,14 +6899,6 @@ minipass-pipeline@^1.2.2:
dependencies:
minipass "^3.0.0"
minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6"
integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==
dependencies:
safe-buffer "^5.1.2"
yallist "^3.0.0"
minipass@^3.0.0, minipass@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5"
@ -6975,13 +6906,6 @@ minipass@^3.0.0, minipass@^3.1.1:
dependencies:
yallist "^4.0.0"
minizlib@^1.2.1:
version "1.3.3"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d"
integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==
dependencies:
minipass "^2.9.0"
mississippi@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022"
@ -7014,7 +6938,7 @@ mixin-object@^2.0.1:
for-in "^0.1.3"
is-extendable "^0.1.1"
mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1:
mkdirp@0.5.1, mkdirp@^0.5.1, mkdirp@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
@ -7098,15 +7022,6 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
needle@^2.2.1:
version "2.4.0"
resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c"
integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==
dependencies:
debug "^3.2.6"
iconv-lite "^0.4.4"
sax "^1.2.4"
negotiator@0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
@ -7189,22 +7104,6 @@ node-notifier@^5.4.2:
shellwords "^0.1.1"
which "^1.3.0"
node-pre-gyp@*:
version "0.14.0"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz#9a0596533b877289bcad4e143982ca3d904ddc83"
integrity sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==
dependencies:
detect-libc "^1.0.2"
mkdirp "^0.5.1"
needle "^2.2.1"
nopt "^4.0.1"
npm-packlist "^1.1.6"
npmlog "^4.0.2"
rc "^1.2.7"
rimraf "^2.6.1"
semver "^5.3.0"
tar "^4.4.2"
node-releases@^1.1.40, node-releases@^1.1.46:
version "1.1.47"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.47.tgz#c59ef739a1fd7ecbd9f0b7cf5b7871e8a8b591e4"
@ -7212,14 +7111,6 @@ node-releases@^1.1.40, node-releases@^1.1.46:
dependencies:
semver "^6.3.0"
nopt@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"
integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=
dependencies:
abbrev "1"
osenv "^0.1.4"
normalize-package-data@^2.3.2:
version "2.5.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
@ -7267,27 +7158,6 @@ normalize-url@^3.0.0:
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559"
integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==
npm-bundled@^1.0.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b"
integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==
dependencies:
npm-normalize-package-bin "^1.0.1"
npm-normalize-package-bin@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2"
integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==
npm-packlist@^1.1.6:
version "1.4.8"
resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e"
integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==
dependencies:
ignore-walk "^3.0.1"
npm-bundled "^1.0.1"
npm-normalize-package-bin "^1.0.1"
npm-run-path@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
@ -7295,16 +7165,6 @@ npm-run-path@^2.0.0:
dependencies:
path-key "^2.0.0"
npmlog@^4.0.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
dependencies:
are-we-there-yet "~1.1.2"
console-control-strings "~1.1.0"
gauge "~2.7.3"
set-blocking "~2.0.0"
nth-check@^1.0.2, nth-check@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c"
@ -7517,11 +7377,6 @@ os-browserify@^0.3.0:
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
os-homedir@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
os-locale@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a"
@ -7531,19 +7386,11 @@ os-locale@^3.0.0:
lcid "^2.0.0"
mem "^4.0.0"
os-tmpdir@^1.0.0, os-tmpdir@~1.0.2:
os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
osenv@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==
dependencies:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"
p-defer@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c"
@ -8801,16 +8648,6 @@ raw-body@2.4.0:
iconv-lite "0.4.24"
unpipe "1.0.0"
rc@^1.2.7:
version "1.2.8"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
dependencies:
deep-extend "^0.6.0"
ini "~1.3.0"
minimist "^1.2.0"
strip-json-comments "~2.0.1"
react-app-polyfill@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-1.0.5.tgz#59c7377a0b9ed25692eeaca7ad9b12ef2d064709"
@ -9040,7 +8877,7 @@ read-pkg@^3.0.0:
normalize-package-data "^2.3.2"
path-type "^3.0.0"
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
version "2.3.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
@ -9388,7 +9225,7 @@ rimraf@2.6.3:
dependencies:
glob "^7.1.3"
rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@^2.7.1:
rimraf@^2.5.4, rimraf@^2.6.3, rimraf@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
@ -9536,7 +9373,7 @@ selfsigned@^1.10.7:
dependencies:
node-forge "0.9.0"
"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0:
"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@ -9598,7 +9435,7 @@ serve-static@1.14.1:
parseurl "~1.3.3"
send "0.17.1"
set-blocking@^2.0.0, set-blocking@~2.0.0:
set-blocking@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
@ -10005,7 +9842,7 @@ string-width@^1.0.1:
is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0"
"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1:
string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
@ -10128,11 +9965,6 @@ strip-json-comments@^3.0.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7"
integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==
strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
style-loader@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.0.0.tgz#1d5296f9165e8e2c85d24eee0b7caf9ec8ca1f82"
@ -10213,19 +10045,6 @@ tapable@^1.0.0, tapable@^1.1.0, tapable@^1.1.3:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
tar@^4.4.2:
version "4.4.13"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
dependencies:
chownr "^1.1.1"
fs-minipass "^1.2.5"
minipass "^2.8.6"
minizlib "^1.2.1"
mkdirp "^0.5.0"
safe-buffer "^5.1.2"
yallist "^3.0.3"
terser-webpack-plugin@2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-2.2.1.tgz#5569e6c7d8be79e5e43d6da23acc3b6ba77d22bd"
@ -10912,13 +10731,6 @@ which@^1.2.9, which@^1.3.0, which@^1.3.1:
dependencies:
isexe "^2.0.0"
wide-align@^1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==
dependencies:
string-width "^1.0.2 || 2"
word-wrap@~1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
@ -11158,7 +10970,7 @@ xtend@^4.0.0, xtend@~4.0.1:
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3:
yallist@^3.0.2:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==

Loading…
Cancel
Save