diff options
Diffstat (limited to 'web')
31 files changed, 1465 insertions, 506 deletions
| diff --git a/web/source/.eslintrc.js b/web/source/.eslintrc.js index cb94b8e88..7615c76d4 100644 --- a/web/source/.eslintrc.js +++ b/web/source/.eslintrc.js @@ -1,8 +1,5 @@  "use strict";  module.exports = { -	"extends": ["@f0x52/eslint-config-react"], -	"rules": { -		"react/prop-types": "off" -	} +	"extends": ["@joepie91/eslint-config/react"]  };
\ No newline at end of file diff --git a/web/source/css/base.css b/web/source/css/base.css index 576c0829f..ed8d55d05 100644 --- a/web/source/css/base.css +++ b/web/source/css/base.css @@ -261,12 +261,16 @@ section.login {  }  section.error { +	word-break: break-word;  	display: flex;  	flex-direction: row;  	align-items: center; +	margin-bottom: 0.5rem; +  	span {  		font-size: 2em;  	} +  	pre {  		border: 1px solid #ff000080;  		margin-left: 1em; diff --git a/web/source/index.js b/web/source/index.js index a96e663cd..90ee5a4ea 100644 --- a/web/source/index.js +++ b/web/source/index.js @@ -66,6 +66,7 @@ skulk({  			],  		},  		settings: { +			debug: false,  			entryFile: "settings",  			outputFile: "settings.js",  			prodCfg: prodCfg, diff --git a/web/source/package.json b/web/source/package.json index 6eb13c9ac..6625c4fd7 100644 --- a/web/source/package.json +++ b/web/source/package.json @@ -30,9 +30,13 @@      "@babel/preset-env": "^7.19.4",      "@babel/preset-react": "^7.18.6",      "@browserify/envify": "^6.0.0", +    "@joepie91/eslint-config": "^1.1.1",      "autoprefixer": "^10.4.13",      "babelify": "^10.0.0",      "css-extract": "^2.0.0", +    "eslint": "^8.26.0", +    "eslint-plugin-react": "^7.31.10", +    "eslint-plugin-react-hooks": "^4.6.0",      "factor-bundle": "^2.5.0",      "icssify": "^2.0.0",      "postcss": "^8.4.18", diff --git a/web/source/settings/admin/actions.js b/web/source/settings/admin/actions.js index d4980d021..915b8aee1 100644 --- a/web/source/settings/admin/actions.js +++ b/web/source/settings/admin/actions.js @@ -18,7 +18,6 @@  "use strict"; -const Promise = require("bluebird");  const React = require("react");  const Redux = require("react-redux"); diff --git a/web/source/settings/admin/emoji.js b/web/source/settings/admin/emoji.js deleted file mode 100644 index ad7fcab06..000000000 --- a/web/source/settings/admin/emoji.js +++ /dev/null @@ -1,229 +0,0 @@ -/* -	GoToSocial -	Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org - -	This program is free software: you can redistribute it and/or modify -	it under the terms of the GNU Affero General Public License as published by -	the Free Software Foundation, either version 3 of the License, or -	(at your option) any later version. - -	This program is distributed in the hope that it will be useful, -	but WITHOUT ANY WARRANTY; without even the implied warranty of -	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -	GNU Affero General Public License for more details. - -	You should have received a copy of the GNU Affero General Public License -	along with this program.  If not, see <http://www.gnu.org/licenses/>. -*/ - -"use strict"; - -const Promise = require("bluebird"); -const React = require("react"); -const Redux = require("react-redux"); -const {Switch, Route, Link, Redirect, useRoute, useLocation} = require("wouter"); - -const Submit = require("../components/submit"); -const FakeToot = require("../components/fake-toot"); -const { formFields } = require("../components/form-fields"); - -const api = require("../lib/api"); -const adminActions = require("../redux/reducers/admin").actions; -const submit = require("../lib/submit"); -const BackButton = require("../components/back-button"); - -const base = "/settings/admin/custom-emoji"; - -module.exports = function CustomEmoji() { -	const dispatch = Redux.useDispatch(); -	const [loaded, setLoaded] = React.useState(false); - -	const [errorMsg, setError] = React.useState(""); - -	React.useEffect(() => { -		if (!loaded) { -			Promise.try(() => { -				return dispatch(api.admin.fetchCustomEmoji()); -			}).then(() => { -				setLoaded(true); -			}).catch((e) => { -				setLoaded(true); -				setError(e.message); -			}); -		} -	}, []); - -	if (!loaded) { -		return ( -			<> -				<h1>Custom Emoji</h1> -				Loading... -			</> -		); -	} - -	return ( -		<> -			{errorMsg.length > 0 &&  -				<div className="error accent">{errorMsg}</div> -			} -			<Switch> -				<Route path={`${base}/:emojiId`}> -					<EmojiDetailWrapped /> -				</Route> -				<EmojiOverview /> -			</Switch> -		</> -	); -}; - -function EmojiOverview() { -	return ( -		<> -			<h1>Custom Emoji</h1> -			<EmojiList/> -			<NewEmoji/> -		</> -	); -} - -const NewEmojiForm = formFields(adminActions.updateNewEmojiVal, (state) => state.admin.newEmoji); -function NewEmoji() { -	const dispatch = Redux.useDispatch(); -	const newEmojiForm = Redux.useSelector((state) => state.admin.newEmoji); - -	const [errorMsg, setError] = React.useState(""); -	const [statusMsg, setStatus] = React.useState(""); - -	const uploadEmoji = submit( -		() => dispatch(api.admin.newEmoji()), -		{ -			setStatus, setError, -			onSuccess: function() { -				URL.revokeObjectURL(newEmojiForm.image); -				return Promise.all([ -					dispatch(adminActions.updateNewEmojiVal(["image", undefined])), -					dispatch(adminActions.updateNewEmojiVal(["imageFile", undefined])), -					dispatch(adminActions.updateNewEmojiVal(["shortcode", ""])), -				]); -			} -		} -	); - -	React.useEffect(() => { -		if (newEmojiForm.shortcode.length == 0) { -			if (newEmojiForm.imageFile != undefined) { -				let [name, ext] = newEmojiForm.imageFile.name.split("."); -				dispatch(adminActions.updateNewEmojiVal(["shortcode", name])); -			} -		} -	}); - -	let emojiOrShortcode = `:${newEmojiForm.shortcode}:`; - -	if (newEmojiForm.image != undefined) { -		emojiOrShortcode = <img -			className="emoji" -			src={newEmojiForm.image} -			title={`:${newEmojiForm.shortcode}:`} -			alt={newEmojiForm.shortcode} -		/>; -	} - -	return ( -		<div> -			<h2>Add new custom emoji</h2> - -			<FakeToot> -				Look at this new custom emoji {emojiOrShortcode} isn't it cool? -			</FakeToot> - -			<NewEmojiForm.File -				id="image" -				name="Image" -				fileType="image/png,image/gif" -				showSize={true} -				maxSize={50 * 1000} -			/> - -			<NewEmojiForm.TextInput -				id="shortcode" -				name="Shortcode (without : :), must be unique on the instance" -				placeHolder="blobcat" -			/> - -			<Submit onClick={uploadEmoji} label="Upload" errorMsg={errorMsg} statusMsg={statusMsg} /> -		</div> -	); -} - -function EmojiList() { -	const emoji = Redux.useSelector((state) => state.admin.emoji); - -	return ( -		<div> -			<h2>Overview</h2> -			<div className="list emoji-list"> -				{Object.entries(emoji).map(([category, entries]) => { -					return <EmojiCategory key={category} category={category} entries={entries}/>; -				})} -			</div> -		</div> -	); -} - -function EmojiCategory({category, entries}) { -	return ( -		<div className="entry"> -			<b>{category}</b> -			<div className="emoji-group"> -				{entries.map((e) => { -					return ( -						<Link key={e.id} to={`${base}/${e.id}`}> -							{/* <Link key={e.static_url} to={`${base}`}> */} -							<a> -								<img src={e.url} alt={e.shortcode} title={`:${e.shortcode}:`}/> -							</a> -						</Link> -					); -				})} -			</div> -		</div> -	); -} - -function EmojiDetailWrapped() { -	/* We wrap the component to generate formFields with a setter depending on the domain -		 if formFields() is used inside the same component that is re-rendered with their state, -		 inputs get re-created on every change, causing them to lose focus, and bad performance -	*/ -	let [_match, {emojiId}] = useRoute(`${base}/:emojiId`); -	const emojiById = Redux.useSelector((state) => state.admin.emojiById); -	const emoji = emojiById[emojiId]; -	if (emoji == undefined) { -		return ( -			<h1><BackButton to={base}/> Custom Emoji: </h1> -		); -	} - -	function alterEmoji([key, val]) { -		return adminActions.updateDomainBlockVal([emojiId, key, val]); -	} - -	const fields = formFields(alterEmoji, (state) => state.admin.blockedInstances[emojiId]); - -	return <EmojiDetail emoji={emoji} Form={fields} />; -} - -function EmojiDetail({emoji, Form}) { -	return ( -		<div> -			<h1><BackButton to={base}/> Custom Emoji: {emoji.shortcode}</h1> -			<p> -				Editing custom emoji isn't implemented yet.<br/> -				<a target="_blank" rel="noreferrer" href="https://github.com/superseriousbusiness/gotosocial/issues/797">View implementation progress.</a> -			</p> -			<img src={emoji.url} alt={emoji.shortcode} title={`:${emoji.shortcode}:`}/> -		</div> -	); -}
\ No newline at end of file diff --git a/web/source/settings/admin/emoji/detail.js b/web/source/settings/admin/emoji/detail.js new file mode 100644 index 000000000..cc0f8e73c --- /dev/null +++ b/web/source/settings/admin/emoji/detail.js @@ -0,0 +1,86 @@ +/* +	GoToSocial +	Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org + +	This program is free software: you can redistribute it and/or modify +	it under the terms of the GNU Affero General Public License as published by +	the Free Software Foundation, either version 3 of the License, or +	(at your option) any later version. + +	This program is distributed in the hope that it will be useful, +	but WITHOUT ANY WARRANTY; without even the implied warranty of +	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +	GNU Affero General Public License for more details. + +	You should have received a copy of the GNU Affero General Public License +	along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +"use strict"; + +const React = require("react"); + +const { useRoute, Link, Redirect } = require("wouter"); + +const BackButton = require("../../components/back-button"); + +const query = require("../../lib/query"); + +const base = "/settings/admin/custom-emoji"; + +/* We wrap the component to generate formFields with a setter depending on the domain +	 if formFields() is used inside the same component that is re-rendered with their state, +	 inputs get re-created on every change, causing them to lose focus, and bad performance +*/ +module.exports = function EmojiDetailWrapped() { +	let [_match, {emojiId}] = useRoute(`${base}/:emojiId`); +	const {currentData: emoji, isLoading, error} = query.useGetEmojiQuery(emojiId); + +	return (<> +		{error && <div className="error accent">{error.status}: {error.data.error}</div>} +		{isLoading +			? "Loading..." +			: <EmojiDetail emoji={emoji}/> +		} +	</>); +}; + +function EmojiDetail({emoji}) { +	if (emoji == undefined) { +		return (<> +			<Link to={base}> +				<a className="button">go back</a> +			</Link> +		</>); +	} + +	return ( +		<div> +			<h1><BackButton to={base}/> Custom Emoji: {emoji.shortcode}</h1> +			<DeleteButton id={emoji.id}/> +			<p> +				Editing custom emoji isn't implemented yet.<br/> +				<a target="_blank" rel="noreferrer" href="https://github.com/superseriousbusiness/gotosocial/issues/797">View implementation progress.</a> +			</p> +			<img src={emoji.url} alt={emoji.shortcode} title={`:${emoji.shortcode}:`}/> +		</div> +	); +} + +function DeleteButton({id}) { +	// TODO: confirmation dialog? +	const [deleteEmoji, deleteResult] = query.useDeleteEmojiMutation(); + +	let text = "Delete this emoji"; +	if (deleteResult.isLoading) { +		text = "processing..."; +	} + +	if (deleteResult.isSuccess) { +		return <Redirect to={base}/>; +	} + +	return ( +		<button onClick={() => deleteEmoji(id)} disabled={deleteResult.isLoading}>{text}</button> +	); +}
\ No newline at end of file diff --git a/web/source/settings/admin/emoji/index.js b/web/source/settings/admin/emoji/index.js new file mode 100644 index 000000000..0fcda8264 --- /dev/null +++ b/web/source/settings/admin/emoji/index.js @@ -0,0 +1,40 @@ +/* +	GoToSocial +	Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org + +	This program is free software: you can redistribute it and/or modify +	it under the terms of the GNU Affero General Public License as published by +	the Free Software Foundation, either version 3 of the License, or +	(at your option) any later version. + +	This program is distributed in the hope that it will be useful, +	but WITHOUT ANY WARRANTY; without even the implied warranty of +	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +	GNU Affero General Public License for more details. + +	You should have received a copy of the GNU Affero General Public License +	along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +"use strict"; + +const React = require("react"); +const {Switch, Route} = require("wouter"); + +const EmojiOverview = require("./overview"); +const EmojiDetail = require("./detail"); + +const base = "/settings/admin/custom-emoji"; + +module.exports = function CustomEmoji() { +	return ( +		<> +			<Switch> +				<Route path={`${base}/:emojiId`}> +					<EmojiDetail /> +				</Route> +				<EmojiOverview /> +			</Switch> +		</> +	); +}; diff --git a/web/source/settings/admin/emoji/new-emoji.js b/web/source/settings/admin/emoji/new-emoji.js new file mode 100644 index 000000000..e5bc8893d --- /dev/null +++ b/web/source/settings/admin/emoji/new-emoji.js @@ -0,0 +1,133 @@ +/* +	GoToSocial +	Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org + +	This program is free software: you can redistribute it and/or modify +	it under the terms of the GNU Affero General Public License as published by +	the Free Software Foundation, either version 3 of the License, or +	(at your option) any later version. + +	This program is distributed in the hope that it will be useful, +	but WITHOUT ANY WARRANTY; without even the implied warranty of +	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +	GNU Affero General Public License for more details. + +	You should have received a copy of the GNU Affero General Public License +	along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +"use strict"; + +const Promise = require('bluebird'); +const React = require("react"); + +const FakeToot = require("../../components/fake-toot"); +const MutateButton = require("../../components/mutation-button"); + +const {  +	useTextInput, +	useFileInput +} = require("../../components/form"); + +const query = require("../../lib/query"); + +module.exports = function NewEmojiForm({emoji}) { +	const emojiCodes = React.useMemo(() => { +		return new Set(emoji.map((e) => e.shortcode)); +	}, [emoji]); + +	const [addEmoji, result] = query.useAddEmojiMutation(); + +	const [onFileChange, resetFile, {image, imageURL, imageInfo}] = useFileInput("image", { +		withPreview: true, +		maxSize: 50 * 1024 +	}); + +	const [onShortcodeChange, resetShortcode, {shortcode, setShortcode, shortcodeRef}] = useTextInput("shortcode", { +		validator: function validateShortcode(code) { +			return emojiCodes.has(code) +				? "Shortcode already in use" +				: ""; +		} +	}); + +	React.useEffect(() => { +		if (shortcode.length == 0) { +			if (image != undefined) { +				let [name, _ext] = image.name.split("."); +				setShortcode(name); +			} +		} +		// eslint-disable-next-line react-hooks/exhaustive-deps +	}, [image]); + +	function uploadEmoji(e) { +		if (e) { +			e.preventDefault(); +		} + +		Promise.try(() => { +			return addEmoji({ +				image, +				shortcode +			}); +		}).then(() => { +			resetFile(); +			resetShortcode(); +		}); +	} + +	let emojiOrShortcode = `:${shortcode}:`; + +	if (imageURL != undefined) { +		emojiOrShortcode = <img +			className="emoji" +			src={imageURL} +			title={`:${shortcode}:`} +			alt={shortcode} +		/>; +	} + +	return ( +		<div> +			<h2>Add new custom emoji</h2> + +			<FakeToot> +				Look at this new custom emoji {emojiOrShortcode} isn't it cool? +			</FakeToot> + +			<form onSubmit={uploadEmoji} className="form-flex"> +				<div className="form-field file"> +					<label className="file-input button" htmlFor="image"> +						Browse +					</label> +					{imageInfo} +					<input +						className="hidden" +						type="file" +						id="image" +						name="Image" +						accept="image/png,image/gif" +						onChange={onFileChange} +					/> +				</div> + +				<div className="form-field text"> +					<label htmlFor="shortcode"> +						Shortcode, must be unique among the instance's local emoji +					</label> +					<input +						type="text" +						id="shortcode" +						name="Shortcode" +						ref={shortcodeRef} +						onChange={onShortcodeChange} +						value={shortcode} +					/> +				</div> +				 +				<MutateButton text="Upload emoji" result={result}/> +			</form> +		</div> +	); +};
\ No newline at end of file diff --git a/web/source/settings/admin/emoji/overview.js b/web/source/settings/admin/emoji/overview.js new file mode 100644 index 000000000..028276da2 --- /dev/null +++ b/web/source/settings/admin/emoji/overview.js @@ -0,0 +1,99 @@ +/* +	 GoToSocial +	 Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org + +	 This program is free software: you can redistribute it and/or modify +	 it under the terms of the GNU Affero General Public License as published by +	 the Free Software Foundation, either version 3 of the License, or +	 (at your option) any later version. + +	 This program is distributed in the hope that it will be useful, +	 but WITHOUT ANY WARRANTY; without even the implied warranty of +	 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +	 GNU Affero General Public License for more details. + +	 You should have received a copy of the GNU Affero General Public License +	 along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +"use strict"; + +const React = require("react"); +const {Link} = require("wouter"); +const defaultValue = require('default-value'); + +const NewEmojiForm = require("./new-emoji"); + +const query = require("../../lib/query"); + +const base = "/settings/admin/custom-emoji"; + +module.exports = function EmojiOverview() { +	const { +		data: emoji, +		isLoading, +		error +	} = query.useGetAllEmojiQuery({filter: "domain:local"}); + +	return ( +		<> +			<h1>Custom Emoji</h1> +			{error &&  +				<div className="error accent">{error}</div> +			} +			{isLoading +				? "Loading..." +				: <> +					<EmojiList emoji={emoji}/> +					<NewEmojiForm emoji={emoji}/> +				</> +			} +		</> +	); +}; + +function EmojiList({emoji}) { +	const byCategory = React.useMemo(() => { +		const categories = {}; + +		emoji.forEach((emoji) => { +			let cat = defaultValue(emoji.category, "Unsorted"); +			categories[cat] = defaultValue(categories[cat], []); +			categories[cat].push(emoji); +		}); + +		return categories; +	}, [emoji]); +	 +	return ( +		<div> +			<h2>Overview</h2> +			<div className="list emoji-list"> +				{emoji.length == 0 && "No local emoji yet"} +				{Object.entries(byCategory).map(([category, entries]) => { +					return <EmojiCategory key={category} category={category} entries={entries}/>; +				})} +			</div> +		</div> +	); +} + +function EmojiCategory({category, entries}) { +	return ( +		<div className="entry"> +			<b>{category}</b> +			<div className="emoji-group"> +				{entries.map((e) => { +					return ( +						<Link key={e.id} to={`${base}/${e.id}`}> +							{/* <Link key={e.static_url} to={`${base}`}> */} +							<a> +								<img src={e.url} alt={e.shortcode} title={`:${e.shortcode}:`}/> +							</a> +						</Link> +					); +				})} +			</div> +		</div> +	); +}
\ No newline at end of file diff --git a/web/source/settings/admin/federation.js b/web/source/settings/admin/federation.js index 99f10e69e..449d2156f 100644 --- a/web/source/settings/admin/federation.js +++ b/web/source/settings/admin/federation.js @@ -50,7 +50,7 @@ module.exports = function AdminSettings() {  				return dispatch(api.admin.fetchDomainBlocks());  			});  		} -	}, []); +	}, [dispatch, loadedBlockedInstances]);  	if (!loadedBlockedInstances) {  		return ( @@ -315,7 +315,7 @@ function InstancePage({domain, Form}) {  		if (entry == undefined) {  			dispatch(api.admin.getEditableDomainBlock(domain));  		} -	}, []); +	}, [dispatch, domain, entry]);  	const [errorMsg, setError] = React.useState("");  	const [statusMsg, setStatus] = React.useState(""); diff --git a/web/source/settings/admin/settings.js b/web/source/settings/admin/settings.js index 845a1f924..eb6e8b267 100644 --- a/web/source/settings/admin/settings.js +++ b/web/source/settings/admin/settings.js @@ -18,7 +18,6 @@  "use strict"; -const Promise = require("bluebird");  const React = require("react");  const Redux = require("react-redux"); @@ -32,7 +31,7 @@ const adminActions = require("../redux/reducers/instances").actions;  const {  	TextInput,  	TextArea, -	File +	_File  } = require("../components/form-fields").formFields(adminActions.setAdminSettingsVal, (state) => state.instances.adminSettings);  module.exports = function AdminSettings() { diff --git a/web/source/settings/components/error.jsx b/web/source/settings/components/error.jsx index 13dc686b7..dd1551c36 100644 --- a/web/source/settings/components/error.jsx +++ b/web/source/settings/components/error.jsx @@ -18,7 +18,6 @@  "use strict"; -const Promise = require("bluebird");  const React = require("react");  module.exports = function ErrorFallback({error, resetErrorBoundary}) { diff --git a/web/source/settings/components/form-fields.jsx b/web/source/settings/components/form-fields.jsx index cb402c3b2..6393b1d5c 100644 --- a/web/source/settings/components/form-fields.jsx +++ b/web/source/settings/components/form-fields.jsx @@ -119,7 +119,7 @@ module.exports = {  				field = (  					<>  						<label htmlFor={id} className="file-input button">Browse</label> -						<span> +						<span className="form-info">  							{file ? file.name : "no file selected"} {size}  						</span>  						{/* <a onClick={removeFile("header")}>remove</a> */} diff --git a/web/source/settings/components/form/file.jsx b/web/source/settings/components/form/file.jsx new file mode 100644 index 000000000..0d28cb699 --- /dev/null +++ b/web/source/settings/components/form/file.jsx @@ -0,0 +1,78 @@ +/* +	GoToSocial +	Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org + +	This program is free software: you can redistribute it and/or modify +	it under the terms of the GNU Affero General Public License as published by +	the Free Software Foundation, either version 3 of the License, or +	(at your option) any later version. + +	This program is distributed in the hope that it will be useful, +	but WITHOUT ANY WARRANTY; without even the implied warranty of +	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +	GNU Affero General Public License for more details. + +	You should have received a copy of the GNU Affero General Public License +	along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +"use strict"; + +const React = require("react"); +const prettierBytes = require("prettier-bytes"); + +module.exports = function useFileInput({name, _Name}, { +	withPreview, +	maxSize, +	initialInfo = "no file selected" +}) { +	const [file, setFile] = React.useState(); +	const [imageURL, setImageURL] = React.useState(); +	const [info, setInfo] = React.useState(); + +	function onChange(e) { +		let file = e.target.files[0]; +		setFile(file); + +		URL.revokeObjectURL(imageURL); + +		if (file != undefined) { +			if (withPreview) { +				setImageURL(URL.createObjectURL(file)); +			} +	 +			let size = prettierBytes(file.size); +			if (maxSize && file.size > maxSize) { +				size = <span className="error-text">{size}</span>; +			} + +			setInfo(<> +				{file.name} ({size}) +			</>); +		} else { +			setInfo(); +		} +	} + +	function reset() { +		URL.revokeObjectURL(imageURL); +		setImageURL(); +		setFile(); +		setInfo(); +	} + +	return [ +		onChange, +		reset, +		{ +			[name]: file, +			[`${name}URL`]: imageURL, +			[`${name}Info`]: <span className="form-info"> +				{info +					? info +					: initialInfo +				} +			</span> +		} +	]; +};
\ No newline at end of file diff --git a/web/source/settings/components/form/index.js b/web/source/settings/components/form/index.js new file mode 100644 index 000000000..5edc52364 --- /dev/null +++ b/web/source/settings/components/form/index.js @@ -0,0 +1,36 @@ +/* +	 GoToSocial +	 Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org + +	 This program is free software: you can redistribute it and/or modify +	 it under the terms of the GNU Affero General Public License as published by +	 the Free Software Foundation, either version 3 of the License, or +	 (at your option) any later version. + +	 This program is distributed in the hope that it will be useful, +	 but WITHOUT ANY WARRANTY; without even the implied warranty of +	 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +	 GNU Affero General Public License for more details. + +	 You should have received a copy of the GNU Affero General Public License +	 along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +"use strict"; + +function capitalizeFirst(str) { +	return str.slice(0,1).toUpperCase()+str.slice(1); +} + +function makeHook(func) { +	return (name, ...args) => func({ +		name, +		Name: capitalizeFirst(name) +	}, +	...args); +} + +module.exports = { +	useTextInput: makeHook(require("./text")), +	useFileInput: makeHook(require("./file")) +};
\ No newline at end of file diff --git a/web/source/settings/components/form/text.jsx b/web/source/settings/components/form/text.jsx new file mode 100644 index 000000000..a392239dc --- /dev/null +++ b/web/source/settings/components/form/text.jsx @@ -0,0 +1,56 @@ +/* +	GoToSocial +	Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org + +	This program is free software: you can redistribute it and/or modify +	it under the terms of the GNU Affero General Public License as published by +	the Free Software Foundation, either version 3 of the License, or +	(at your option) any later version. + +	This program is distributed in the hope that it will be useful, +	but WITHOUT ANY WARRANTY; without even the implied warranty of +	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +	GNU Affero General Public License for more details. + +	You should have received a copy of the GNU Affero General Public License +	along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +"use strict"; + +const React = require("react"); + +module.exports = function useTextInput({name, Name}, {validator} = {}) { +	const [text, setText] = React.useState(""); +	const textRef = React.useRef(null); + +	function onChange(e) { +		let input = e.target.value; +		setText(input); + +		if (validator) { +			validator(input); +		} +	} + +	function reset() { +		setText(""); +	} + +	React.useEffect(() => { +		if (validator) { +			textRef.current.setCustomValidity(validator(text)); +			textRef.current.reportValidity(); +		} +	}, [text, textRef, validator]); + +	return [ +		onChange, +		reset, +		{ +			[name]: text, +			[`${name}Ref`]: textRef, +			[`set${Name}`]: setText +		} +	]; +};
\ No newline at end of file diff --git a/web/source/settings/components/mutation-button.jsx b/web/source/settings/components/mutation-button.jsx new file mode 100644 index 000000000..9a8c9d089 --- /dev/null +++ b/web/source/settings/components/mutation-button.jsx @@ -0,0 +1,42 @@ +/* +	GoToSocial +	Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org + +	This program is free software: you can redistribute it and/or modify +	it under the terms of the GNU Affero General Public License as published by +	the Free Software Foundation, either version 3 of the License, or +	(at your option) any later version. + +	This program is distributed in the hope that it will be useful, +	but WITHOUT ANY WARRANTY; without even the implied warranty of +	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +	GNU Affero General Public License for more details. + +	You should have received a copy of the GNU Affero General Public License +	along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +"use strict"; + +const React = require("react"); + +module.exports = function MutateButton({text, result}) { +	let buttonText = text; + +	if (result.isLoading) { +		buttonText = "Processing..."; +	} + +	return (<div> +		{result.error &&  +			<section className="error">{result.error.status}: {result.error.data.error}</section> +		} +		<input +			className="button" +			type="submit" +			disabled={result.isLoading} +			value={buttonText} +		/> +	</div> +	); +};
\ No newline at end of file diff --git a/web/source/settings/index.js b/web/source/settings/index.js index 34720e818..58afe5d28 100644 --- a/web/source/settings/index.js +++ b/web/source/settings/index.js @@ -46,7 +46,7 @@ const nav = {  		"Instance Settings": require("./admin/settings.js"),  		"Actions": require("./admin/actions"),  		"Federation": require("./admin/federation.js"), -		"Custom Emoji": require("./admin/emoji.js"), +		"Custom Emoji": require("./admin/emoji"),  	}  }; @@ -94,7 +94,7 @@ function App() {  				console.error(e);  			});  		} -	}, []); +	}, [loginState, dispatch]);  	let ErrorElement = null;  	if (errorMsg != undefined) { diff --git a/web/source/settings/lib/api/admin.js b/web/source/settings/lib/api/admin.js index 56513b900..5f4fa1d1f 100644 --- a/web/source/settings/lib/api/admin.js +++ b/web/source/settings/lib/api/admin.js @@ -160,33 +160,6 @@ module.exports = function ({ apiCall, getChanges }) {  				});  			};  		}, - -		fetchCustomEmoji: function fetchCustomEmoji() { -			return function (dispatch, _getState) { -				return Promise.try(() => { -					return dispatch(apiCall("GET", "/api/v1/admin/custom_emojis?filter=domain:local&limit=0")); -				}).then((emoji) => { -					return dispatch(admin.setEmoji(emoji)); -				}); -			}; -		}, - -		newEmoji: function newEmoji() { -			return function (dispatch, getState) { -				return Promise.try(() => { -					const state = getState().admin.newEmoji; - -					const update = getChanges(state, { -						formKeys: ["shortcode"], -						fileKeys: ["image"] -					}); - -					return dispatch(apiCall("POST", "/api/v1/admin/custom_emojis", update, "form")); -				}).then((emoji) => { -					return dispatch(admin.addEmoji(emoji)); -				}); -			}; -		}  	};  	return adminAPI;  };
\ No newline at end of file diff --git a/web/source/settings/lib/api/index.js b/web/source/settings/lib/api/index.js index e699011bd..8af7d5b43 100644 --- a/web/source/settings/lib/api/index.js +++ b/web/source/settings/lib/api/index.js @@ -24,14 +24,12 @@ const d = require("dotty");  const { APIError, AuthenticationError } = require("../errors");  const { setInstanceInfo, setNamedInstanceInfo } = require("../../redux/reducers/instances").actions; -const oauth = require("../../redux/reducers/oauth").actions;  function apiCall(method, route, payload, type = "json") {  	return function (dispatch, getState) {  		const state = getState();  		let base = state.oauth.instance;  		let auth = state.oauth.token; -		console.log(method, base, route, "auth:", auth != undefined);  		return Promise.try(() => {  			let url = new URL(base); @@ -51,21 +49,7 @@ function apiCall(method, route, payload, type = "json") {  					headers["Content-Type"] = "application/json";  					body = JSON.stringify(payload);  				} else if (type == "form") { -					const formData = new FormData(); -					Object.entries(payload).forEach(([key, val]) => { -						if (isPlainObject(val)) { -							Object.entries(val).forEach(([key2, val2]) => { -								if (val2 != undefined) { -									formData.set(`${key}[${key2}]`, val2); -								} -							}); -						} else { -							if (val != undefined) { -								formData.set(key, val); -							} -						} -					}); -					body = formData; +					body = convertToForm(payload);  				}  			} @@ -100,6 +84,28 @@ function apiCall(method, route, payload, type = "json") {  	};  } +/* +	Takes an object with (nested) keys, and transforms it into +	a FormData object to be sent over the API +*/ +function convertToForm(payload) { +	const formData = new FormData(); +	Object.entries(payload).forEach(([key, val]) => { +		if (isPlainObject(val)) { +			Object.entries(val).forEach(([key2, val2]) => { +				if (val2 != undefined) { +					formData.set(`${key}[${key2}]`, val2); +				} +			}); +		} else { +			if (val != undefined) { +				formData.set(key, val); +			} +		} +	}); +	return formData; +} +  function getChanges(state, keys) {  	const { formKeys = [], fileKeys = [], renamedKeys = {} } = keys;  	const update = {}; @@ -129,7 +135,8 @@ function getChanges(state, keys) {  }  function getCurrentUrl() { -	return `${window.location.origin}${window.location.pathname}`; +	let [pre, _past] = window.location.pathname.split("/settings"); +	return `${window.location.origin}${pre}/settings`;  }  function fetchInstanceWithoutStore(domain) { @@ -181,5 +188,6 @@ module.exports = {  	user: require("./user")(submoduleArgs),  	admin: require("./admin")(submoduleArgs),  	apiCall, +	convertToForm,  	getChanges  };
\ No newline at end of file diff --git a/web/source/settings/lib/get-views.js b/web/source/settings/lib/get-views.js index 39f627435..96ab17404 100644 --- a/web/source/settings/lib/get-views.js +++ b/web/source/settings/lib/get-views.js @@ -19,8 +19,7 @@  "use strict";  const React = require("react"); -const Redux = require("react-redux"); -const { Link, Route, Switch, Redirect } = require("wouter"); +const { Link, Route, Redirect } = require("wouter");  const { ErrorBoundary } = require("react-error-boundary");  const ErrorFallback = require("../components/error"); diff --git a/web/source/settings/lib/panel.js b/web/source/settings/lib/panel.js deleted file mode 100644 index df723bc74..000000000 --- a/web/source/settings/lib/panel.js +++ /dev/null @@ -1,134 +0,0 @@ -/* -	GoToSocial -	Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org - -	This program is free software: you can redistribute it and/or modify -	it under the terms of the GNU Affero General Public License as published by -	the Free Software Foundation, either version 3 of the License, or -	(at your option) any later version. - -	This program is distributed in the hope that it will be useful, -	but WITHOUT ANY WARRANTY; without even the implied warranty of -	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -	GNU Affero General Public License for more details. - -	You should have received a copy of the GNU Affero General Public License -	along with this program.  If not, see <http://www.gnu.org/licenses/>. -*/ - -"use strict"; - -const Promise = require("bluebird"); -const React = require("react"); -const ReactDom = require("react-dom"); - -const oauthLib = require("./oauth"); - -module.exports = function createPanel(clientName, scope, Component) { -	ReactDom.render(<Panel/>, document.getElementById("root")); - -	function Panel() { -		const [oauth, setOauth] = React.useState(); -		const [hasAuth, setAuth] = React.useState(false); -		const [oauthState, setOauthState] = React.useState(localStorage.getItem("oauth")); - -		React.useEffect(() => { -			let state = localStorage.getItem("oauth"); -			if (state != undefined) { -				state = JSON.parse(state); -				let restoredOauth = oauthLib(state.config, state); -				Promise.try(() => { -					return restoredOauth.callback(); -				}).then(() => { -					setAuth(true); -				}); -				setOauth(restoredOauth); -			} -		}, [setAuth, setOauth]); - -		if (!hasAuth && oauth && oauth.isAuthorized()) { -			setAuth(true); -		} - -		if (oauth && oauth.isAuthorized()) { -			return <Component oauth={oauth} />; -		} else if (oauthState != undefined) { -			return "processing oauth..."; -		} else { -			return <Auth setOauth={setOauth} />; -		} -	} - -	function Auth({setOauth}) { -		const [ instance, setInstance ] = React.useState(""); - -		React.useEffect(() => { -			let isStillMounted = true; -			// check if current domain runs an instance -			let thisUrl = new URL(window.location.origin); -			thisUrl.pathname = "/api/v1/instance"; -			Promise.try(() => { -				return fetch(thisUrl.href); -			}).then((res) => { -				if (res.status == 200) { -					return res.json(); -				} -			}).then((json) => { -				if (json && json.uri && isStillMounted) { -					setInstance(json.uri); -				} -			}).catch((e) => { -				console.log("error checking instance response:", e); -			}); - -			return () => { -				// cleanup function -				isStillMounted = false; -			}; -		}, []); - -		function doAuth() { -			return Promise.try(() => { -				return new URL(instance); -			}).catch(TypeError, () => { -				return new URL(`https://${instance}`); -			}).then((parsedURL) => { -				let url = parsedURL.toString(); -				let oauth = oauthLib({ -					instance: url, -					client_name: clientName, -					scope: scope, -					website: window.location.href -				}); -				setOauth(oauth); -				setInstance(url); -				return oauth.register().then(() => { -					return oauth; -				}); -			}).then((oauth) => { -				return oauth.authorize(); -			}).catch((e) => { -				console.log("error authenticating:", e); -			}); -		} - -		function updateInstance(e) { -			if (e.key == "Enter") { -				doAuth(); -			} else { -				setInstance(e.target.value); -			} -		} - -		return ( -			<section className="login"> -				<h1>OAUTH Login:</h1> -				<form onSubmit={(e) => e.preventDefault()}> -					<label htmlFor="instance">Instance: </label> -					<input value={instance} onChange={updateInstance} id="instance"/> -					<button onClick={doAuth}>Authenticate</button> -				</form> -			</section> -		); -	} -};
\ No newline at end of file diff --git a/web/source/settings/lib/query/base.js b/web/source/settings/lib/query/base.js new file mode 100644 index 000000000..4023e9fbd --- /dev/null +++ b/web/source/settings/lib/query/base.js @@ -0,0 +1,55 @@ +/* +	 GoToSocial +	 Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org + +	 This program is free software: you can redistribute it and/or modify +	 it under the terms of the GNU Affero General Public License as published by +	 the Free Software Foundation, either version 3 of the License, or +	 (at your option) any later version. + +	 This program is distributed in the hope that it will be useful, +	 but WITHOUT ANY WARRANTY; without even the implied warranty of +	 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +	 GNU Affero General Public License for more details. + +	 You should have received a copy of the GNU Affero General Public License +	 along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +"use strict"; + +const { createApi, fetchBaseQuery } = require("@reduxjs/toolkit/query/react"); + +const { convertToForm } = require("../api"); + +function instanceBasedQuery(args, api, extraOptions) { +	const state = api.getState(); +	const {instance, token} = state.oauth; + +	if (args.baseUrl == undefined) { +		args.baseUrl = instance; +	} + +	if (args.asForm) { +		delete args.asForm; +		args.body = convertToForm(args.body); +	} + +	return fetchBaseQuery({ +		baseUrl: args.baseUrl, +		prepareHeaders: (headers) => { +			if (token != undefined) { +				headers.set('Authorization', token); +			} +			headers.set("Accept", "application/json"); +			return headers; +		}, +	})(args, api, extraOptions); +} + +module.exports = createApi({ +	reducerPath: "api", +	baseQuery: instanceBasedQuery, +	tagTypes: ["Emojis"], +	endpoints: () => ({}) +});
\ No newline at end of file diff --git a/web/source/settings/lib/query/custom-emoji.js b/web/source/settings/lib/query/custom-emoji.js new file mode 100644 index 000000000..a26da75ca --- /dev/null +++ b/web/source/settings/lib/query/custom-emoji.js @@ -0,0 +1,66 @@ +/* +	 GoToSocial +	 Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org + +	 This program is free software: you can redistribute it and/or modify +	 it under the terms of the GNU Affero General Public License as published by +	 the Free Software Foundation, either version 3 of the License, or +	 (at your option) any later version. + +	 This program is distributed in the hope that it will be useful, +	 but WITHOUT ANY WARRANTY; without even the implied warranty of +	 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +	 GNU Affero General Public License for more details. + +	 You should have received a copy of the GNU Affero General Public License +	 along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +"use strict"; + +const base = require("./base"); + +const endpoints = (build) => ({ +	getAllEmoji: build.query({ +		query: (params = {}) => ({ +			url: "/api/v1/admin/custom_emojis", +			params: { +				limit: 0, +				...params +			} +		}), +		providesTags: (res) =>  +			res +				? [...res.map((emoji) => ({type: "Emojis", id: emoji.id})), {type: "Emojis", id: "LIST"}] +				: [{type: "Emojis", id: "LIST"}] +	}), +	getEmoji: build.query({ +		query: (id) => ({ +			url: `/api/v1/admin/custom_emojis/${id}` +		}), +		providesTags: (res, error, id) => [{type: "Emojis", id}] +	}), +	addEmoji: build.mutation({ +		query: (form) => { +			return { +				method: "POST", +				url: `/api/v1/admin/custom_emojis`, +				asForm: true, +				body: form +			}; +		}, +		invalidatesTags: (res) =>  +			res +				? [{type: "Emojis", id: "LIST"}, {type: "Emojis", id: res.id}] +				: [{type: "Emojis", id: "LIST"}] +	}), +	deleteEmoji: build.mutation({ +		query: (id) => ({ +			method: "DELETE", +			url: `/api/v1/admin/custom_emojis/${id}` +		}), +		invalidatesTags: (res, error, id) => [{type: "Emojis", id}] +	}) +}); + +module.exports = base.injectEndpoints({endpoints});
\ No newline at end of file diff --git a/web/source/settings/lib/query/index.js b/web/source/settings/lib/query/index.js new file mode 100644 index 000000000..5b15fd252 --- /dev/null +++ b/web/source/settings/lib/query/index.js @@ -0,0 +1,24 @@ +/* +	 GoToSocial +	 Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org + +	 This program is free software: you can redistribute it and/or modify +	 it under the terms of the GNU Affero General Public License as published by +	 the Free Software Foundation, either version 3 of the License, or +	 (at your option) any later version. + +	 This program is distributed in the hope that it will be useful, +	 but WITHOUT ANY WARRANTY; without even the implied warranty of +	 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +	 GNU Affero General Public License for more details. + +	 You should have received a copy of the GNU Affero General Public License +	 along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +"use strict"; + +module.exports = { +	...require("./base"), +	...require("./custom-emoji.js") +};
\ No newline at end of file diff --git a/web/source/settings/redux/index.js b/web/source/settings/redux/index.js index f18b8e452..43f5c007d 100644 --- a/web/source/settings/redux/index.js +++ b/web/source/settings/redux/index.js @@ -18,18 +18,20 @@  "use strict"; -const { createStore, combineReducers, applyMiddleware } = require("redux"); -const { persistStore, persistReducer } = require("redux-persist"); -const thunk = require("redux-thunk").default; -const { composeWithDevTools } = require("redux-devtools-extension"); +const { combineReducers } = require("redux"); +const { configureStore } = require("@reduxjs/toolkit"); +const { +	persistStore, +	persistReducer, +	FLUSH, +	REHYDRATE, +	PAUSE, +	PERSIST, +	PURGE, +	REGISTER, +} = require("redux-persist"); -const persistConfig = { -	key: "gotosocial-settings", -	storage: require("redux-persist/lib/storage").default, -	stateReconciler: require("redux-persist/lib/stateReconciler/autoMergeLevel2").default, -	whitelist: ["oauth"], -	blacklist: ["temporary"] -}; +const query = require("../lib/query/base");  const combinedReducers = combineReducers({  	oauth: require("./reducers/oauth").reducer, @@ -37,13 +39,27 @@ const combinedReducers = combineReducers({  	temporary: require("./reducers/temporary").reducer,  	user: require("./reducers/user").reducer,  	admin: require("./reducers/admin").reducer, +	[query.reducerPath]: query.reducer  }); -const persistedReducer = persistReducer(persistConfig, combinedReducers); -const composedEnhancer = composeWithDevTools(applyMiddleware(thunk)); +const persistedReducer = persistReducer({ +	key: "gotosocial-settings", +	storage: require("redux-persist/lib/storage").default, +	stateReconciler: require("redux-persist/lib/stateReconciler/autoMergeLevel2").default, +	whitelist: ["oauth"], +}, combinedReducers); + +const store = configureStore({ +	reducer: persistedReducer, +	middleware: (getDefaultMiddleware) => { +		return getDefaultMiddleware({ +			serializableCheck: { +				ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER, "temporary/setScrollElement"] +			} +		}).concat(query.middleware); +	} +}); -// TODO: change to configureStore -const store = createStore(persistedReducer, composedEnhancer);  const persistor = persistStore(store);  module.exports = { store, persistor };
\ No newline at end of file diff --git a/web/source/settings/redux/reducers/admin.js b/web/source/settings/redux/reducers/admin.js index 666286178..57ca83d7e 100644 --- a/web/source/settings/redux/reducers/admin.js +++ b/web/source/settings/redux/reducers/admin.js @@ -19,7 +19,6 @@  "use strict";  const { createSlice } = require("@reduxjs/toolkit"); -const defaultValue = require("default-value");  function sortBlocks(blocks) {  	return blocks.sort((a, b) => { // alphabetical sort @@ -35,13 +34,6 @@ function emptyBlock() {  	};  } -function emptyEmojiForm() { -	return { -		id: Date.now(), -		shortcode: "" -	}; -} -  module.exports = createSlice({  	name: "admin",  	initialState: { @@ -52,10 +44,7 @@ module.exports = createSlice({  			exportType: "plain",  			...emptyBlock()  		}, -		newInstanceBlocks: {}, -		emoji: {}, -		emojiById: {}, -		newEmoji: emptyEmojiForm() +		newInstanceBlocks: {}  	},  	reducers: {  		setBlockedInstances: (state, { payload }) => { @@ -105,34 +94,6 @@ module.exports = createSlice({  			state.bulkBlock.list = Object.values(state.blockedInstances).map((entry) => {  				return entry.domain;  			}).join("\n"); -		}, - -		setEmoji: (state, {payload}) => { -			state.emoji = {}; -			payload.forEach((emoji) => { -				if (emoji.category == undefined) { -					emoji.category = "Unsorted"; -				} -				state.emoji[emoji.category] = defaultValue(state.emoji[emoji.category], []); -				state.emoji[emoji.category].push(emoji); -				state.emojiById[emoji.id] = emoji; -			}); -		}, - -		updateNewEmojiVal: (state, { payload: [key, val] }) => { -			state.newEmoji[key] = val; -		}, - -		addEmoji: (state, {payload: emoji}) => { -			if (emoji.category == undefined) { -				emoji.category = "Unsorted"; -			} -			if (emoji.id == undefined) { -				emoji.id = Date.now(); -			} -			state.emoji[emoji.category] = defaultValue(state.emoji[emoji.category], []); -			state.emoji[emoji.category].push(emoji); -			state.emojiById[emoji.id] = emoji; -		}, +		}  	}  });
\ No newline at end of file diff --git a/web/source/settings/style.css b/web/source/settings/style.css index 35d11fa08..93e52f680 100644 --- a/web/source/settings/style.css +++ b/web/source/settings/style.css @@ -283,6 +283,12 @@ section.with-sidebar > div {  	}  } +.form-flex { +	display: flex; +	flex-direction: column; +	gap: 1rem; +} +  .file-upload > div {  	display: flex;  	gap: 1rem; @@ -330,19 +336,6 @@ section.with-sidebar > div {  			flex-direction: column;  			justify-content: center; -			div.form-field { -				width: 100%; -				display: flex; - -				span { -					flex: 1 1 auto; -					overflow: hidden; -					text-overflow: ellipsis; -					white-space: nowrap; -					padding: 0.3rem 0; -				} -			} -  			h3 {  				margin-top: 0;  				margin-bottom: 0.5rem; @@ -363,6 +356,20 @@ section.with-sidebar > div {  	font-weight: bold;  } +.form-field.file { +	width: 100%; +	display: flex; +} + + +span.form-info { +	flex: 1 1 auto; +	overflow: hidden; +	text-overflow: ellipsis; +	white-space: nowrap; +	padding: 0.3rem 0; +} +  .list {  	display: flex;  	flex-direction: column; diff --git a/web/source/settings/user/profile.js b/web/source/settings/user/profile.js index 3162fa0dd..21e86ce66 100644 --- a/web/source/settings/user/profile.js +++ b/web/source/settings/user/profile.js @@ -18,7 +18,6 @@  "use strict"; -const Promise = require("bluebird");  const React = require("react");  const Redux = require("react-redux"); diff --git a/web/source/yarn.lock b/web/source/yarn.lock index 47ea5778f..7b7f1de91 100644 --- a/web/source/yarn.lock +++ b/web/source/yarn.lock @@ -969,6 +969,21 @@      multisplice "^1.0.0"      through2 "^4.0.2" +"@eslint/eslintrc@^1.3.3": +  version "1.3.3" +  resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95" +  integrity sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg== +  dependencies: +    ajv "^6.12.4" +    debug "^4.3.2" +    espree "^9.4.0" +    globals "^13.15.0" +    ignore "^5.2.0" +    import-fresh "^3.2.1" +    js-yaml "^4.1.0" +    minimatch "^3.1.2" +    strip-json-comments "^3.1.1" +  "@f0x52/spyfs@^1.1.0":    version "1.1.0"    resolved "https://registry.yarnpkg.com/@f0x52/spyfs/-/spyfs-1.1.0.tgz#67c628b7c6f207649457cf8a05ba1b1f5a850739" @@ -976,6 +991,30 @@    dependencies:      fs-monkey "0.4.0" +"@humanwhocodes/config-array@^0.11.6": +  version "0.11.7" +  resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.7.tgz#38aec044c6c828f6ed51d5d7ae3d9b9faf6dbb0f" +  integrity sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw== +  dependencies: +    "@humanwhocodes/object-schema" "^1.2.1" +    debug "^4.1.1" +    minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": +  version "1.0.1" +  resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" +  integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^1.2.1": +  version "1.2.1" +  resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" +  integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@joepie91/eslint-config@^1.1.1": +  version "1.1.1" +  resolved "https://registry.yarnpkg.com/@joepie91/eslint-config/-/eslint-config-1.1.1.tgz#cb276dec6dd25b5777daefbef561850c9717180d" +  integrity sha512-q8l83tdpL0YGC24ftlpeHgmQIIRmcpiVhwwEUFPcJ1YXWaee/JjoUs6e5tLKMTNNk+fvDKtq2YPSXkmLQU7h5Q== +  "@jridgewell/gen-mapping@^0.1.0":    version "0.1.1"    resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" @@ -1016,6 +1055,27 @@      "@jridgewell/resolve-uri" "3.1.0"      "@jridgewell/sourcemap-codec" "1.4.14" +"@nodelib/fs.scandir@2.1.5": +  version "2.1.5" +  resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" +  integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== +  dependencies: +    "@nodelib/fs.stat" "2.0.5" +    run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5": +  version "2.0.5" +  resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" +  integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.8": +  version "1.2.8" +  resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" +  integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== +  dependencies: +    "@nodelib/fs.scandir" "2.1.5" +    fastq "^1.6.0" +  "@reduxjs/toolkit@^1.8.6":    version "1.8.6"    resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.8.6.tgz#147fb7957befcdb75bc9c1230db63628e30e4332" @@ -1478,6 +1538,11 @@ accepts@~1.3.8:      mime-types "~2.1.34"      negotiator "0.6.3" +acorn-jsx@^5.3.2: +  version "5.3.2" +  resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" +  integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== +  acorn-node@^1.2.0, acorn-node@^1.3.0, acorn-node@^1.5.2, acorn-node@^1.8.2:    version "1.8.2"    resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8" @@ -1506,11 +1571,31 @@ acorn@^7.0.0:    resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"    integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^8.8.0: +  version "8.8.1" +  resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" +  integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== + +ajv@^6.10.0, ajv@^6.12.4: +  version "6.12.6" +  resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" +  integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== +  dependencies: +    fast-deep-equal "^3.1.1" +    fast-json-stable-stringify "^2.0.0" +    json-schema-traverse "^0.4.1" +    uri-js "^4.2.2" +  amdefine@>=0.0.4:    version "1.0.1"    resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"    integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg== +ansi-regex@^5.0.1: +  version "5.0.1" +  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" +  integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +  ansi-styles@^3.2.1:    version "3.2.1"    resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -1518,6 +1603,13 @@ ansi-styles@^3.2.1:    dependencies:      color-convert "^1.9.0" +ansi-styles@^4.1.0: +  version "4.3.0" +  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" +  integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== +  dependencies: +    color-convert "^2.0.1" +  anymatch@^3.1.0, anymatch@~3.1.2:    version "3.1.2"    resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" @@ -1526,6 +1618,11 @@ anymatch@^3.1.0, anymatch@~3.1.2:      normalize-path "^3.0.0"      picomatch "^2.0.4" +argparse@^2.0.1: +  version "2.0.1" +  resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" +  integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +  array-flatten@1.1.1:    version "1.1.1"    resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" @@ -1536,11 +1633,32 @@ array-from@^2.1.1:    resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195"    integrity sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg== +array-includes@^3.1.5: +  version "3.1.5" +  resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb" +  integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ== +  dependencies: +    call-bind "^1.0.2" +    define-properties "^1.1.4" +    es-abstract "^1.19.5" +    get-intrinsic "^1.1.1" +    is-string "^1.0.7" +  array-union@^2.1.0:    version "2.1.0"    resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"    integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +array.prototype.flatmap@^1.3.0: +  version "1.3.0" +  resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz#a7e8ed4225f4788a70cd910abcf0791e76a5534f" +  integrity sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg== +  dependencies: +    call-bind "^1.0.2" +    define-properties "^1.1.3" +    es-abstract "^1.19.2" +    es-shim-unscopables "^1.0.0" +  as-expression@^1.0.0:    version "1.0.0"    resolved "https://registry.yarnpkg.com/as-expression/-/as-expression-1.0.0.tgz#7bc620ca4cb2fe0ee90d86729bd6add33b8fd831" @@ -1916,6 +2034,11 @@ call-bind@^1.0.0, call-bind@^1.0.2:      function-bind "^1.1.1"      get-intrinsic "^1.0.2" +callsites@^3.0.0: +  version "3.1.0" +  resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" +  integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== +  caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001426:    version "1.0.30001427"    resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001427.tgz#d3a749f74be7ae0671fbec3a4eea18576e8ad646" @@ -1930,6 +2053,14 @@ chalk@^2.0.0:      escape-string-regexp "^1.0.5"      supports-color "^5.3.0" +chalk@^4.0.0: +  version "4.1.2" +  resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" +  integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== +  dependencies: +    ansi-styles "^4.1.0" +    supports-color "^7.1.0" +  chokidar@^3.4.0:    version "3.5.3"    resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" @@ -1967,11 +2098,23 @@ color-convert@^1.9.0:    dependencies:      color-name "1.1.3" +color-convert@^2.0.1: +  version "2.0.1" +  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" +  integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== +  dependencies: +    color-name "~1.1.4" +  color-name@1.1.3:    version "1.1.3"    resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"    integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +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== +  combine-source-map@^0.8.0, combine-source-map@~0.8.0:    version "0.8.0"    resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.8.0.tgz#a58d0df042c186fcf822a8e8015f5450d2d79a8b" @@ -2107,6 +2250,15 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7:      safe-buffer "^5.0.1"      sha.js "^2.4.8" +cross-spawn@^7.0.2: +  version "7.0.3" +  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" +  integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== +  dependencies: +    path-key "^3.1.0" +    shebang-command "^2.0.0" +    which "^2.0.1" +  crypto-browserify@^3.0.0:    version "3.12.0"    resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -2177,14 +2329,14 @@ debug@^3.1.0:    dependencies:      ms "^2.1.1" -debug@^4.1.0, debug@^4.1.1, debug@^4.3.4: +debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:    version "4.3.4"    resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"    integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==    dependencies:      ms "2.1.2" -deep-is@~0.1.3: +deep-is@^0.1.3, deep-is@~0.1.3:    version "0.1.4"    resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"    integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== @@ -2274,6 +2426,20 @@ diffie-hellman@^5.0.0:      miller-rabin "^4.0.0"      randombytes "^2.0.0" +doctrine@^2.1.0: +  version "2.1.0" +  resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" +  integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== +  dependencies: +    esutils "^2.0.2" + +doctrine@^3.0.0: +  version "3.0.0" +  resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" +  integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== +  dependencies: +    esutils "^2.0.2" +  domain-browser@^1.2.0:    version "1.2.0"    resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" @@ -2336,7 +2502,7 @@ error@^7.0.0:    dependencies:      string-template "~0.2.1" -es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.5, es-abstract@^1.20.0: +es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5, es-abstract@^1.20.0:    version "1.20.4"    resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.4.tgz#1d103f9f8d78d4cf0713edcd6d0ed1a46eed5861"    integrity sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA== @@ -2366,6 +2532,13 @@ es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.5, es-abstract@^1.20      string.prototype.trimstart "^1.0.5"      unbox-primitive "^1.0.2" +es-shim-unscopables@^1.0.0: +  version "1.0.0" +  resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" +  integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== +  dependencies: +    has "^1.0.3" +  es-to-primitive@^1.2.1:    version "1.2.1"    resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -2445,6 +2618,11 @@ escape-string-regexp@^1.0.5:    resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"    integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== +escape-string-regexp@^4.0.0: +  version "4.0.0" +  resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" +  integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +  escodegen@^1.11.1:    version "1.14.3"    resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" @@ -2457,16 +2635,139 @@ escodegen@^1.11.1:    optionalDependencies:      source-map "~0.6.1" +eslint-plugin-react-hooks@^4.6.0: +  version "4.6.0" +  resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" +  integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== + +eslint-plugin-react@^7.31.10: +  version "7.31.10" +  resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.31.10.tgz#6782c2c7fe91c09e715d536067644bbb9491419a" +  integrity sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA== +  dependencies: +    array-includes "^3.1.5" +    array.prototype.flatmap "^1.3.0" +    doctrine "^2.1.0" +    estraverse "^5.3.0" +    jsx-ast-utils "^2.4.1 || ^3.0.0" +    minimatch "^3.1.2" +    object.entries "^1.1.5" +    object.fromentries "^2.0.5" +    object.hasown "^1.1.1" +    object.values "^1.1.5" +    prop-types "^15.8.1" +    resolve "^2.0.0-next.3" +    semver "^6.3.0" +    string.prototype.matchall "^4.0.7" + +eslint-scope@^7.1.1: +  version "7.1.1" +  resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" +  integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== +  dependencies: +    esrecurse "^4.3.0" +    estraverse "^5.2.0" + +eslint-utils@^3.0.0: +  version "3.0.0" +  resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" +  integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== +  dependencies: +    eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^2.0.0: +  version "2.1.0" +  resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" +  integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint-visitor-keys@^3.3.0: +  version "3.3.0" +  resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" +  integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== + +eslint@^8.26.0: +  version "8.26.0" +  resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.26.0.tgz#2bcc8836e6c424c4ac26a5674a70d44d84f2181d" +  integrity sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg== +  dependencies: +    "@eslint/eslintrc" "^1.3.3" +    "@humanwhocodes/config-array" "^0.11.6" +    "@humanwhocodes/module-importer" "^1.0.1" +    "@nodelib/fs.walk" "^1.2.8" +    ajv "^6.10.0" +    chalk "^4.0.0" +    cross-spawn "^7.0.2" +    debug "^4.3.2" +    doctrine "^3.0.0" +    escape-string-regexp "^4.0.0" +    eslint-scope "^7.1.1" +    eslint-utils "^3.0.0" +    eslint-visitor-keys "^3.3.0" +    espree "^9.4.0" +    esquery "^1.4.0" +    esutils "^2.0.2" +    fast-deep-equal "^3.1.3" +    file-entry-cache "^6.0.1" +    find-up "^5.0.0" +    glob-parent "^6.0.2" +    globals "^13.15.0" +    grapheme-splitter "^1.0.4" +    ignore "^5.2.0" +    import-fresh "^3.0.0" +    imurmurhash "^0.1.4" +    is-glob "^4.0.0" +    is-path-inside "^3.0.3" +    js-sdsl "^4.1.4" +    js-yaml "^4.1.0" +    json-stable-stringify-without-jsonify "^1.0.1" +    levn "^0.4.1" +    lodash.merge "^4.6.2" +    minimatch "^3.1.2" +    natural-compare "^1.4.0" +    optionator "^0.9.1" +    regexpp "^3.2.0" +    strip-ansi "^6.0.1" +    strip-json-comments "^3.1.0" +    text-table "^0.2.0" + +espree@^9.4.0: +  version "9.4.0" +  resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" +  integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== +  dependencies: +    acorn "^8.8.0" +    acorn-jsx "^5.3.2" +    eslint-visitor-keys "^3.3.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== +esquery@^1.4.0: +  version "1.4.0" +  resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" +  integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== +  dependencies: +    estraverse "^5.1.0" + +esrecurse@^4.3.0: +  version "4.3.0" +  resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" +  integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== +  dependencies: +    estraverse "^5.2.0" +  estraverse@^4.2.0:    version "4.3.0"    resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"    integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== +estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: +  version "5.3.0" +  resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" +  integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== +  estree-is-function@^1.0.0:    version "1.0.0"    resolved "https://registry.yarnpkg.com/estree-is-function/-/estree-is-function-1.0.0.tgz#c0adc29806d7f18a74db7df0f3b2666702e37ad2" @@ -2579,7 +2880,17 @@ factor-bundle@^2.5.0:      through2 "^0.5.1"      xtend "^4.0.0" -fast-levenshtein@~2.0.6: +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: +  version "3.1.3" +  resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" +  integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: +  version "2.1.0" +  resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" +  integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:    version "2.0.6"    resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"    integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== @@ -2589,6 +2900,13 @@ fast-safe-stringify@^2.0.7:    resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884"    integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== +fastq@^1.6.0: +  version "1.13.0" +  resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" +  integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== +  dependencies: +    reusify "^1.0.4" +  faye-websocket@^0.11.3:    version "0.11.4"    resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" @@ -2596,6 +2914,13 @@ faye-websocket@^0.11.3:    dependencies:      websocket-driver ">=0.5.1" +file-entry-cache@^6.0.1: +  version "6.0.1" +  resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" +  integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== +  dependencies: +    flat-cache "^3.0.4" +  fill-range@^7.0.1:    version "7.0.1"    resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -2621,6 +2946,27 @@ find-cycle@^1.0.0:    resolved "https://registry.yarnpkg.com/find-cycle/-/find-cycle-1.0.0.tgz#9d4a84b853540e121fd7a2bd7fbc4a6d425364b9"    integrity sha512-um47oVzW1wGgkEb1Pbhs/Scb1xYP+RErujOAQCpngJDhG9YHXfOh7HV2l4tFwrNs60XawH4kDul3BvG+ZuTKvQ== +find-up@^5.0.0: +  version "5.0.0" +  resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" +  integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== +  dependencies: +    locate-path "^6.0.0" +    path-exists "^4.0.0" + +flat-cache@^3.0.4: +  version "3.0.4" +  resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" +  integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== +  dependencies: +    flatted "^3.1.0" +    rimraf "^3.0.2" + +flatted@^3.1.0: +  version "3.2.7" +  resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" +  integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +  flatten@^1.0.3:    version "1.0.3"    resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" @@ -2742,6 +3088,13 @@ get-symbol-description@^1.0.0:      call-bind "^1.0.2"      get-intrinsic "^1.1.1" +glob-parent@^6.0.2: +  version "6.0.2" +  resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" +  integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== +  dependencies: +    is-glob "^4.0.3" +  glob-parent@~5.1.2:    version "5.1.2"    resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -2766,6 +3119,18 @@ globals@^11.1.0:    resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"    integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +globals@^13.15.0: +  version "13.17.0" +  resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" +  integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== +  dependencies: +    type-fest "^0.20.2" + +grapheme-splitter@^1.0.4: +  version "1.0.4" +  resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" +  integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== +  has-bigints@^1.0.1, has-bigints@^1.0.2:    version "1.0.2"    resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" @@ -2933,11 +3298,29 @@ ieee754@^1.1.13, ieee754@^1.1.4:    resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"    integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +ignore@^5.2.0: +  version "5.2.0" +  resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" +  integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== +  immer@^9.0.7:    version "9.0.16"    resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.16.tgz#8e7caab80118c2b54b37ad43e05758cdefad0198"    integrity sha512-qenGE7CstVm1NrHQbMh8YaSzTZTFNP3zPqr3YU0S0UY441j4bJTg4A2Hh5KAhwgaiU6ZZ1Ar6y/2f4TblnMReQ== +import-fresh@^3.0.0, import-fresh@^3.2.1: +  version "3.3.0" +  resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" +  integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== +  dependencies: +    parent-module "^1.0.0" +    resolve-from "^4.0.0" + +imurmurhash@^0.1.4: +  version "0.1.4" +  resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" +  integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== +  indent-string@^4.0.0:    version "4.0.0"    resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" @@ -3088,7 +3471,7 @@ is-generator-function@^1.0.7:    dependencies:      has-tostringtag "^1.0.0" -is-glob@^4.0.1, is-glob@~4.0.1: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:    version "4.0.3"    resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"    integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -3112,6 +3495,11 @@ is-number@^7.0.0:    resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"    integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-path-inside@^3.0.3: +  version "3.0.3" +  resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" +  integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== +  is-plain-obj@^2.1.0:    version "2.1.0"    resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" @@ -3196,16 +3584,33 @@ isarray@~1.0.0:    resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"    integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== +isexe@^2.0.0: +  version "2.0.0" +  resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" +  integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +  js-file-download@^0.4.12:    version "0.4.12"    resolved "https://registry.yarnpkg.com/js-file-download/-/js-file-download-0.4.12.tgz#10c70ef362559a5b23cdbdc3bd6f399c3d91d821"    integrity sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg== +js-sdsl@^4.1.4: +  version "4.1.5" +  resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.5.tgz#1ff1645e6b4d1b028cd3f862db88c9d887f26e2a" +  integrity sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q== +  "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:    version "4.0.0"    resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"    integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-yaml@^4.1.0: +  version "4.1.0" +  resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" +  integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== +  dependencies: +    argparse "^2.0.1" +  jsesc@^2.5.1:    version "2.5.2"    resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -3216,6 +3621,16 @@ jsesc@~0.5.0:    resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"    integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== +json-schema-traverse@^0.4.1: +  version "0.4.1" +  resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" +  integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: +  version "1.0.1" +  resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" +  integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +  json5@^1.0.1:    version "1.0.1"    resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" @@ -3238,6 +3653,14 @@ jsonparse@^1.2.0:    resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"    integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== +"jsx-ast-utils@^2.4.1 || ^3.0.0": +  version "3.3.3" +  resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" +  integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== +  dependencies: +    array-includes "^3.1.5" +    object.assign "^4.1.3" +  labeled-stream-splicer@^1.0.0:    version "1.0.2"    resolved "https://registry.yarnpkg.com/labeled-stream-splicer/-/labeled-stream-splicer-1.0.2.tgz#4615331537784981e8fd264e1f3a434c4e0ddd65" @@ -3260,6 +3683,14 @@ langs@^2.0.0:    resolved "https://registry.yarnpkg.com/langs/-/langs-2.0.0.tgz#00c32ce48152a49a614450b9ba2632ab58a0a364"    integrity sha512-v4pxOBEQVN1WBTfB1crhTtxzNLZU9HPWgadlwzWKISJtt6Ku/CnpBrwVy+jFv8StjxsPfwPFzO0CMwdZLJ0/BA== +levn@^0.4.1: +  version "0.4.1" +  resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" +  integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== +  dependencies: +    prelude-ls "^1.2.1" +    type-check "~0.4.0" +  levn@~0.3.0:    version "0.3.0"    resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -3287,6 +3718,13 @@ loader-utils@^1.1.0:      emojis-list "^3.0.0"      json5 "^1.0.1" +locate-path@^6.0.0: +  version "6.0.0" +  resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" +  integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== +  dependencies: +    p-locate "^5.0.0" +  lodash.debounce@^4.0.8:    version "4.0.8"    resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -3297,7 +3735,12 @@ lodash.memoize@~3.0.3:    resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f"    integrity sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A== -loose-envify@^1.1.0: +lodash.merge@^4.6.2: +  version "4.6.2" +  resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" +  integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +loose-envify@^1.1.0, loose-envify@^1.4.0:    version "1.4.0"    resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"    integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -3397,7 +3840,7 @@ minimalistic-crypto-utils@^1.0.1:    resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"    integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== -minimatch@^3.0.2, minimatch@^3.1.1: +minimatch@^3.0.2, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:    version "3.1.2"    resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"    integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -3475,6 +3918,11 @@ nanoid@^3.3.4:    resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"    integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== +natural-compare@^1.4.0: +  version "1.4.0" +  resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" +  integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== +  negotiator@0.6.3:    version "0.6.3"    resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" @@ -3520,7 +3968,7 @@ object-keys@^1.1.1:    resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"    integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.4: +object.assign@^4.1.3, object.assign@^4.1.4:    version "4.1.4"    resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f"    integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== @@ -3530,7 +3978,16 @@ object.assign@^4.1.4:      has-symbols "^1.0.3"      object-keys "^1.1.1" -object.fromentries@^2.0.1: +object.entries@^1.1.5: +  version "1.1.5" +  resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" +  integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== +  dependencies: +    call-bind "^1.0.2" +    define-properties "^1.1.3" +    es-abstract "^1.19.1" + +object.fromentries@^2.0.1, object.fromentries@^2.0.5:    version "2.0.5"    resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251"    integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw== @@ -3539,6 +3996,23 @@ object.fromentries@^2.0.1:      define-properties "^1.1.3"      es-abstract "^1.19.1" +object.hasown@^1.1.1: +  version "1.1.1" +  resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.1.tgz#ad1eecc60d03f49460600430d97f23882cf592a3" +  integrity sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A== +  dependencies: +    define-properties "^1.1.4" +    es-abstract "^1.19.5" + +object.values@^1.1.5: +  version "1.1.5" +  resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" +  integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== +  dependencies: +    call-bind "^1.0.2" +    define-properties "^1.1.3" +    es-abstract "^1.19.1" +  on-finished@2.4.1:    version "2.4.1"    resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -3565,6 +4039,18 @@ optionator@^0.8.1:      type-check "~0.3.2"      word-wrap "~1.2.3" +optionator@^0.9.1: +  version "0.9.1" +  resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" +  integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== +  dependencies: +    deep-is "^0.1.3" +    fast-levenshtein "^2.0.6" +    levn "^0.4.1" +    prelude-ls "^1.2.1" +    type-check "^0.4.0" +    word-wrap "^1.2.3" +  os-browserify@~0.3.0:    version "0.3.0"    resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" @@ -3577,11 +4063,32 @@ outpipe@^1.1.0:    dependencies:      shell-quote "^1.4.2" +p-limit@^3.0.2: +  version "3.1.0" +  resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" +  integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== +  dependencies: +    yocto-queue "^0.1.0" + +p-locate@^5.0.0: +  version "5.0.0" +  resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" +  integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== +  dependencies: +    p-limit "^3.0.2" +  pako@~1.0.5:    version "1.0.11"    resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"    integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== +parent-module@^1.0.0: +  version "1.0.1" +  resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" +  integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== +  dependencies: +    callsites "^3.0.0" +  parents@^1.0.0, parents@^1.0.1:    version "1.0.1"    resolved "https://registry.yarnpkg.com/parents/-/parents-1.0.1.tgz#fedd4d2bf193a77745fe71e371d73c3307d9c751" @@ -3615,11 +4122,21 @@ path-browserify@^1.0.0:    resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"    integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== +path-exists@^4.0.0: +  version "4.0.0" +  resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" +  integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== +  path-is-absolute@^1.0.0, path-is-absolute@^1.0.1:    version "1.0.1"    resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"    integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== +path-key@^3.1.0: +  version "3.1.1" +  resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" +  integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +  path-parse@^1.0.7:    version "1.0.7"    resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" @@ -3742,6 +4259,11 @@ postcss@^8.4.12, postcss@^8.4.18:      picocolors "^1.0.0"      source-map-js "^1.0.2" +prelude-ls@^1.2.1: +  version "1.2.1" +  resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" +  integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +  prelude-ls@~1.1.2:    version "1.1.2"    resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -3769,6 +4291,15 @@ process@~0.11.0:    resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"    integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== +prop-types@^15.8.1: +  version "15.8.1" +  resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" +  integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== +  dependencies: +    loose-envify "^1.4.0" +    object-assign "^4.1.1" +    react-is "^16.13.1" +  proxy-addr@~2.0.7:    version "2.0.7"    resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -3799,7 +4330,7 @@ punycode@^1.3.2:    resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"    integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== -punycode@^2.1.1: +punycode@^2.1.0, punycode@^2.1.1:    version "2.1.1"    resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"    integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -3821,6 +4352,11 @@ querystring@0.2.0:    resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"    integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== +queue-microtask@^1.2.2: +  version "1.2.3" +  resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" +  integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +  randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:    version "2.1.0"    resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -3874,7 +4410,7 @@ react-error-boundary@^3.1.4:    dependencies:      "@babel/runtime" "^7.12.5" -react-is@^16.7.0: +react-is@^16.13.1, react-is@^16.7.0:    version "16.13.1"    resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"    integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -4019,7 +4555,7 @@ regenerator-transform@^0.15.0:    dependencies:      "@babel/runtime" "^7.8.4" -regexp.prototype.flags@^1.4.3: +regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3:    version "1.4.3"    resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"    integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== @@ -4028,6 +4564,11 @@ regexp.prototype.flags@^1.4.3:      define-properties "^1.1.3"      functions-have-names "^1.2.2" +regexpp@^3.2.0: +  version "3.2.0" +  resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" +  integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== +  regexpu-core@^5.1.0:    version "5.2.1"    resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.2.1.tgz#a69c26f324c1e962e9ffd0b88b055caba8089139" @@ -4062,6 +4603,11 @@ reselect@^4.1.5:    resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.6.tgz#19ca2d3d0b35373a74dc1c98692cdaffb6602656"    integrity sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ== +resolve-from@^4.0.0: +  version "4.0.0" +  resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" +  integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +  resolve@^1.1.4, resolve@^1.1.7, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.4.0:    version "1.22.1"    resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" @@ -4071,6 +4617,15 @@ resolve@^1.1.4, resolve@^1.1.7, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.4.0      path-parse "^1.0.7"      supports-preserve-symlinks-flag "^1.0.0" +resolve@^2.0.0-next.3: +  version "2.0.0-next.4" +  resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660" +  integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== +  dependencies: +    is-core-module "^2.9.0" +    path-parse "^1.0.7" +    supports-preserve-symlinks-flag "^1.0.0" +  resp-modifier@^6.0.0:    version "6.0.2"    resolved "https://registry.yarnpkg.com/resp-modifier/-/resp-modifier-6.0.2.tgz#b124de5c4fbafcba541f48ffa73970f4aa456b4f" @@ -4079,6 +4634,11 @@ resp-modifier@^6.0.0:      debug "^2.2.0"      minimatch "^3.0.2" +reusify@^1.0.4: +  version "1.0.4" +  resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" +  integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +  reversepoint@~0.2.0:    version "0.2.1"    resolved "https://registry.yarnpkg.com/reversepoint/-/reversepoint-0.2.1.tgz#d2ac3ff4d665cf0ff72296b7a78ee7237f6593f5" @@ -4099,6 +4659,13 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:      hash-base "^3.0.0"      inherits "^2.0.1" +run-parallel@^1.1.9: +  version "1.2.0" +  resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" +  integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== +  dependencies: +    queue-microtask "^1.2.2" +  safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0:    version "5.2.1"    resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -4207,6 +4774,18 @@ shasum-object@^1.0.0:    dependencies:      fast-safe-stringify "^2.0.7" +shebang-command@^2.0.0: +  version "2.0.0" +  resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" +  integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== +  dependencies: +    shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: +  version "3.0.0" +  resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" +  integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +  shell-quote@^1.4.2, shell-quote@^1.6.1:    version "1.7.4"    resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.4.tgz#33fe15dee71ab2a81fcbd3a52106c5cfb9fb75d8" @@ -4411,6 +4990,20 @@ string-template@~0.2.1:    resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add"    integrity sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw== +string.prototype.matchall@^4.0.7: +  version "4.0.7" +  resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz#8e6ecb0d8a1fb1fda470d81acecb2dba057a481d" +  integrity sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg== +  dependencies: +    call-bind "^1.0.2" +    define-properties "^1.1.3" +    es-abstract "^1.19.1" +    get-intrinsic "^1.1.1" +    has-symbols "^1.0.3" +    internal-slot "^1.0.3" +    regexp.prototype.flags "^1.4.1" +    side-channel "^1.0.4" +  string.prototype.trimend@^1.0.5:    version "1.0.5"    resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" @@ -4448,6 +5041,18 @@ string_decoder@~1.1.1:    dependencies:      safe-buffer "~5.1.0" +strip-ansi@^6.0.1: +  version "6.0.1" +  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" +  integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== +  dependencies: +    ansi-regex "^5.0.1" + +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +  version "3.1.1" +  resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" +  integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +  subarg@^1.0.0:    version "1.0.0"    resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2" @@ -4497,6 +5102,11 @@ terser@^3.7.5:      source-map "~0.6.1"      source-map-support "~0.5.10" +text-table@^0.2.0: +  version "0.2.0" +  resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" +  integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== +  through2@^0.5.1:    version "0.5.1"    resolved "https://registry.yarnpkg.com/through2/-/through2-0.5.1.tgz#dfdd012eb9c700e2323fd334f38ac622ab372da7" @@ -4574,6 +5184,13 @@ tty-browserify@0.0.1:    resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811"    integrity sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw== +type-check@^0.4.0, type-check@~0.4.0: +  version "0.4.0" +  resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" +  integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== +  dependencies: +    prelude-ls "^1.2.1" +  type-check@~0.3.2:    version "0.3.2"    resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -4581,6 +5198,11 @@ type-check@~0.3.2:    dependencies:      prelude-ls "~1.1.2" +type-fest@^0.20.2: +  version "0.20.2" +  resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" +  integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +  type-is@~1.6.18:    version "1.6.18"    resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -4677,6 +5299,13 @@ update-browserslist-db@^1.0.9:      escalade "^3.1.1"      picocolors "^1.0.0" +uri-js@^4.2.2: +  version "4.4.1" +  resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" +  integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== +  dependencies: +    punycode "^2.1.0" +  url@~0.11.0:    version "0.11.0"    resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -4788,7 +5417,14 @@ which-typed-array@^1.1.2:      has-tostringtag "^1.0.0"      is-typed-array "^1.1.9" -word-wrap@~1.2.3: +which@^2.0.1: +  version "2.0.2" +  resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" +  integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== +  dependencies: +    isexe "^2.0.0" + +word-wrap@^1.2.3, word-wrap@~1.2.3:    version "1.2.3"    resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"    integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== @@ -4812,3 +5448,8 @@ xtend@~3.0.0:    version "3.0.0"    resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a"    integrity sha512-sp/sT9OALMjRW1fKDlPeuSZlDQpkqReA0pyJukniWbTGoEKefHxhGJynE3PNhUMlcM8qWIjPwecwCw4LArS5Eg== + +yocto-queue@^0.1.0: +  version "0.1.0" +  resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" +  integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== | 
