From cc0cc154b9506d1961d08cb29fbc29ad815bad69 Mon Sep 17 00:00:00 2001 From: crupest Date: Mon, 24 Aug 2020 22:59:45 +0800 Subject: ... --- Timeline/ClientApp/src/app/common/AlertHost.tsx | 192 +++--- Timeline/ClientApp/src/app/common/AppBar.tsx | 214 +++--- Timeline/ClientApp/src/app/common/BlobImage.tsx | 58 +- Timeline/ClientApp/src/app/common/FileInput.tsx | 82 +-- Timeline/ClientApp/src/app/common/ImageCropper.tsx | 612 ++++++++--------- Timeline/ClientApp/src/app/common/LoadingPage.tsx | 24 +- .../ClientApp/src/app/common/OperationDialog.tsx | 762 ++++++++++----------- Timeline/ClientApp/src/app/common/SearchInput.tsx | 126 ++-- Timeline/ClientApp/src/app/common/TimelineLogo.tsx | 52 +- .../ClientApp/src/app/common/UserTimelineLogo.tsx | 52 +- Timeline/ClientApp/src/app/common/alert-service.ts | 122 ++-- Timeline/ClientApp/src/app/common/alert.sass | 30 +- Timeline/ClientApp/src/app/common/common.sass | 66 +- 13 files changed, 1196 insertions(+), 1196 deletions(-) (limited to 'Timeline/ClientApp/src/app/common') diff --git a/Timeline/ClientApp/src/app/common/AlertHost.tsx b/Timeline/ClientApp/src/app/common/AlertHost.tsx index 89831073..e22354fa 100644 --- a/Timeline/ClientApp/src/app/common/AlertHost.tsx +++ b/Timeline/ClientApp/src/app/common/AlertHost.tsx @@ -1,96 +1,96 @@ -import React, { useCallback } from 'react'; -import { Alert } from 'reactstrap'; -import without from 'lodash/without'; -import concat from 'lodash/concat'; - -import { - alertService, - AlertInfoEx, - kAlertHostId, - AlertInfo, -} from './alert-service'; -import { useTranslation } from 'react-i18next'; - -interface AutoCloseAlertProps { - alert: AlertInfo; - close: () => void; -} - -export const AutoCloseAlert: React.FC = (props) => { - const { alert } = props; - const { dismissTime } = alert; - - const { t } = useTranslation(); - - React.useEffect(() => { - const tag = - dismissTime === 'never' - ? null - : typeof dismissTime === 'number' - ? window.setTimeout(props.close, dismissTime) - : window.setTimeout(props.close, 5000); - return () => { - if (tag != null) { - window.clearTimeout(tag); - } - }; - }, [dismissTime, props.close]); - - return ( - - {(() => { - const { message } = alert; - if (typeof message === 'function') { - const Message = message; - return ; - } else if (typeof message === 'object' && message.type === 'i18n') { - return t(message.key); - } else return alert.message; - })()} - - ); -}; - -// oh what a bad name! -interface AlertInfoExEx extends AlertInfoEx { - close: () => void; -} - -export const AlertHost: React.FC = () => { - const [alerts, setAlerts] = React.useState([]); - - // react guarantee that state setters are stable, so we don't need to add it to dependency list - - const consume = useCallback((alert: AlertInfoEx): void => { - const alertEx: AlertInfoExEx = { - ...alert, - close: () => { - setAlerts((oldAlerts) => { - return without(oldAlerts, alertEx); - }); - }, - }; - setAlerts((oldAlerts) => { - return concat(oldAlerts, alertEx); - }); - }, []); - - React.useEffect(() => { - alertService.registerConsumer(consume); - return () => { - alertService.unregisterConsumer(consume); - }; - }, [consume]); - - return ( -
- {alerts.map((alert) => { - return ( - - ); - })} -
- ); -}; - -export default AlertHost; +import React, { useCallback } from "react"; +import { Alert } from "reactstrap"; +import without from "lodash/without"; +import concat from "lodash/concat"; + +import { + alertService, + AlertInfoEx, + kAlertHostId, + AlertInfo, +} from "./alert-service"; +import { useTranslation } from "react-i18next"; + +interface AutoCloseAlertProps { + alert: AlertInfo; + close: () => void; +} + +export const AutoCloseAlert: React.FC = (props) => { + const { alert } = props; + const { dismissTime } = alert; + + const { t } = useTranslation(); + + React.useEffect(() => { + const tag = + dismissTime === "never" + ? null + : typeof dismissTime === "number" + ? window.setTimeout(props.close, dismissTime) + : window.setTimeout(props.close, 5000); + return () => { + if (tag != null) { + window.clearTimeout(tag); + } + }; + }, [dismissTime, props.close]); + + return ( + + {(() => { + const { message } = alert; + if (typeof message === "function") { + const Message = message; + return ; + } else if (typeof message === "object" && message.type === "i18n") { + return t(message.key); + } else return alert.message; + })()} + + ); +}; + +// oh what a bad name! +interface AlertInfoExEx extends AlertInfoEx { + close: () => void; +} + +export const AlertHost: React.FC = () => { + const [alerts, setAlerts] = React.useState([]); + + // react guarantee that state setters are stable, so we don't need to add it to dependency list + + const consume = useCallback((alert: AlertInfoEx): void => { + const alertEx: AlertInfoExEx = { + ...alert, + close: () => { + setAlerts((oldAlerts) => { + return without(oldAlerts, alertEx); + }); + }, + }; + setAlerts((oldAlerts) => { + return concat(oldAlerts, alertEx); + }); + }, []); + + React.useEffect(() => { + alertService.registerConsumer(consume); + return () => { + alertService.unregisterConsumer(consume); + }; + }, [consume]); + + return ( +
+ {alerts.map((alert) => { + return ( + + ); + })} +
+ ); +}; + +export default AlertHost; diff --git a/Timeline/ClientApp/src/app/common/AppBar.tsx b/Timeline/ClientApp/src/app/common/AppBar.tsx index 8349aef7..59239696 100644 --- a/Timeline/ClientApp/src/app/common/AppBar.tsx +++ b/Timeline/ClientApp/src/app/common/AppBar.tsx @@ -1,107 +1,107 @@ -import React from 'react'; -import { useHistory, matchPath } from 'react-router'; -import { Link, NavLink } from 'react-router-dom'; -import { Navbar, NavbarToggler, Collapse, Nav, NavItem } from 'reactstrap'; -import { useMediaQuery } from 'react-responsive'; -import { useTranslation } from 'react-i18next'; - -import { useUser, useAvatar } from '../data/user'; - -import TimelineLogo from './TimelineLogo'; -import BlobImage from './BlobImage'; - -const AppBar: React.FC = (_) => { - const history = useHistory(); - const user = useUser(); - const avatar = useAvatar(user?.username); - - const { t } = useTranslation(); - - const isUpMd = useMediaQuery({ - minWidth: getComputedStyle(document.documentElement).getPropertyValue( - '--breakpoint-md' - ), - }); - - const [isMenuOpen, setIsMenuOpen] = React.useState(false); - - const toggleMenu = React.useCallback((): void => { - setIsMenuOpen((oldIsMenuOpen) => !oldIsMenuOpen); - }, []); - - const isAdministrator = user && user.administrator; - - const rightArea = ( -
- {user != null ? ( - - - - ) : ( - - {t('nav.login')} - - )} -
- ); - - return ( - - - - Timeline - - - {isUpMd ? null : rightArea} - - - - - {isUpMd ? rightArea : null} - - - ); -}; - -export default AppBar; +import React from "react"; +import { useHistory, matchPath } from "react-router"; +import { Link, NavLink } from "react-router-dom"; +import { Navbar, NavbarToggler, Collapse, Nav, NavItem } from "reactstrap"; +import { useMediaQuery } from "react-responsive"; +import { useTranslation } from "react-i18next"; + +import { useUser, useAvatar } from "../data/user"; + +import TimelineLogo from "./TimelineLogo"; +import BlobImage from "./BlobImage"; + +const AppBar: React.FC = (_) => { + const history = useHistory(); + const user = useUser(); + const avatar = useAvatar(user?.username); + + const { t } = useTranslation(); + + const isUpMd = useMediaQuery({ + minWidth: getComputedStyle(document.documentElement).getPropertyValue( + "--breakpoint-md" + ), + }); + + const [isMenuOpen, setIsMenuOpen] = React.useState(false); + + const toggleMenu = React.useCallback((): void => { + setIsMenuOpen((oldIsMenuOpen) => !oldIsMenuOpen); + }, []); + + const isAdministrator = user && user.administrator; + + const rightArea = ( +
+ {user != null ? ( + + + + ) : ( + + {t("nav.login")} + + )} +
+ ); + + return ( + + + + Timeline + + + {isUpMd ? null : rightArea} + + + + + {isUpMd ? rightArea : null} + + + ); +}; + +export default AppBar; diff --git a/Timeline/ClientApp/src/app/common/BlobImage.tsx b/Timeline/ClientApp/src/app/common/BlobImage.tsx index 7e5e2447..8602f550 100644 --- a/Timeline/ClientApp/src/app/common/BlobImage.tsx +++ b/Timeline/ClientApp/src/app/common/BlobImage.tsx @@ -1,29 +1,29 @@ -import React from 'react'; - -import { ExcludeKey } from '../utilities/type'; - -const BlobImage: React.FC< - ExcludeKey, 'src'> & { - blob?: Blob | unknown; - } -> = (props) => { - const { blob, ...otherProps } = props; - - const [url, setUrl] = React.useState(undefined); - - React.useEffect(() => { - if (blob instanceof Blob) { - const url = URL.createObjectURL(blob); - setUrl(url); - return () => { - URL.revokeObjectURL(url); - }; - } else { - setUrl(undefined); - } - }, [blob]); - - return ; -}; - -export default BlobImage; +import React from "react"; + +import { ExcludeKey } from "../utilities/type"; + +const BlobImage: React.FC< + ExcludeKey, "src"> & { + blob?: Blob | unknown; + } +> = (props) => { + const { blob, ...otherProps } = props; + + const [url, setUrl] = React.useState(undefined); + + React.useEffect(() => { + if (blob instanceof Blob) { + const url = URL.createObjectURL(blob); + setUrl(url); + return () => { + URL.revokeObjectURL(url); + }; + } else { + setUrl(undefined); + } + }, [blob]); + + return ; +}; + +export default BlobImage; diff --git a/Timeline/ClientApp/src/app/common/FileInput.tsx b/Timeline/ClientApp/src/app/common/FileInput.tsx index 94f4aa43..3d1bc2b3 100644 --- a/Timeline/ClientApp/src/app/common/FileInput.tsx +++ b/Timeline/ClientApp/src/app/common/FileInput.tsx @@ -1,41 +1,41 @@ -import React from 'react'; -import clsx from 'clsx'; - -import { ExcludeKey } from '../utilities/type'; - -export interface FileInputProps - extends ExcludeKey< - React.InputHTMLAttributes, - 'type' | 'id' - > { - inputId?: string; - labelText: string; - color?: string; - className?: string; -} - -const FileInput: React.FC = props => { - const { inputId, labelText, color, className, ...otherProps } = props; - - const realInputId = React.useMemo(() => { - if (inputId != null) return inputId; - return ( - 'file-input-' + - (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1) - ); - }, [inputId]); - - return ( - <> - - - - ); -}; - -export default FileInput; +import React from "react"; +import clsx from "clsx"; + +import { ExcludeKey } from "../utilities/type"; + +export interface FileInputProps + extends ExcludeKey< + React.InputHTMLAttributes, + "type" | "id" + > { + inputId?: string; + labelText: string; + color?: string; + className?: string; +} + +const FileInput: React.FC = (props) => { + const { inputId, labelText, color, className, ...otherProps } = props; + + const realInputId = React.useMemo(() => { + if (inputId != null) return inputId; + return ( + "file-input-" + + (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1) + ); + }, [inputId]); + + return ( + <> + + + + ); +}; + +export default FileInput; diff --git a/Timeline/ClientApp/src/app/common/ImageCropper.tsx b/Timeline/ClientApp/src/app/common/ImageCropper.tsx index fb9bb4f9..cd510969 100644 --- a/Timeline/ClientApp/src/app/common/ImageCropper.tsx +++ b/Timeline/ClientApp/src/app/common/ImageCropper.tsx @@ -1,306 +1,306 @@ -import * as React from 'react'; -import clsx from 'clsx'; - -import { UiLogicError } from '../common'; - -export interface Clip { - left: number; - top: number; - width: number; -} - -interface NormailizedClip extends Clip { - height: number; -} - -interface ImageInfo { - width: number; - height: number; - landscape: boolean; - ratio: number; - maxClipWidth: number; - maxClipHeight: number; -} - -interface ImageCropperSavedState { - clip: NormailizedClip; - x: number; - y: number; - pointerId: number; -} - -export interface ImageCropperProps { - clip: Clip | null; - imageUrl: string; - onChange: (clip: Clip) => void; - imageElementCallback?: (element: HTMLImageElement | null) => void; - className?: string; -} - -const ImageCropper = (props: ImageCropperProps): React.ReactElement => { - const { clip, imageUrl, onChange, imageElementCallback, className } = props; - - const [oldState, setOldState] = React.useState( - null - ); - const [imageInfo, setImageInfo] = React.useState(null); - - const normalizeClip = (c: Clip | null | undefined): NormailizedClip => { - if (c == null) { - return { left: 0, top: 0, width: 0, height: 0 }; - } - - return { - left: c.left || 0, - top: c.top || 0, - width: c.width || 0, - height: imageInfo != null ? (c.width || 0) / imageInfo.ratio : 0, - }; - }; - - const c = normalizeClip(clip); - - const imgElementRef = React.useRef(null); - - const onImageRef = React.useCallback( - (e: HTMLImageElement | null) => { - imgElementRef.current = e; - if (imageElementCallback != null && e == null) { - imageElementCallback(null); - } - }, - [imageElementCallback] - ); - - const onImageLoad = React.useCallback( - (e: React.SyntheticEvent) => { - const img = e.currentTarget; - const landscape = img.naturalWidth >= img.naturalHeight; - - const info = { - width: img.naturalWidth, - height: img.naturalHeight, - landscape, - ratio: img.naturalHeight / img.naturalWidth, - maxClipWidth: landscape ? img.naturalHeight / img.naturalWidth : 1, - maxClipHeight: landscape ? 1 : img.naturalWidth / img.naturalHeight, - }; - setImageInfo(info); - onChange({ left: 0, top: 0, width: info.maxClipWidth }); - if (imageElementCallback != null) { - imageElementCallback(img); - } - }, - [onChange, imageElementCallback] - ); - - const onPointerDown = React.useCallback( - (e: React.PointerEvent) => { - if (oldState != null) return; - e.currentTarget.setPointerCapture(e.pointerId); - setOldState({ - x: e.clientX, - y: e.clientY, - clip: c, - pointerId: e.pointerId, - }); - }, - [oldState, c] - ); - - const onPointerUp = React.useCallback( - (e: React.PointerEvent) => { - if (oldState == null || oldState.pointerId !== e.pointerId) return; - e.currentTarget.releasePointerCapture(e.pointerId); - setOldState(null); - }, - [oldState] - ); - - const onPointerMove = React.useCallback( - (e: React.PointerEvent) => { - if (oldState == null) return; - - const oldClip = oldState.clip; - - const movement = { x: e.clientX - oldState.x, y: e.clientY - oldState.y }; - - const { current: imgElement } = imgElementRef; - - if (imgElement == null) throw new UiLogicError('Image element is null.'); - - const moveRatio = { - x: movement.x / imgElement.width, - y: movement.y / imgElement.height, - }; - - const newRatio = { - x: oldClip.left + moveRatio.x, - y: oldClip.top + moveRatio.y, - }; - if (newRatio.x < 0) { - newRatio.x = 0; - } else if (newRatio.x > 1 - oldClip.width) { - newRatio.x = 1 - oldClip.width; - } - if (newRatio.y < 0) { - newRatio.y = 0; - } else if (newRatio.y > 1 - oldClip.height) { - newRatio.y = 1 - oldClip.height; - } - - onChange({ left: newRatio.x, top: newRatio.y, width: oldClip.width }); - }, - [oldState, onChange] - ); - - const onHandlerPointerMove = React.useCallback( - (e: React.PointerEvent) => { - if (oldState == null) return; - - const oldClip = oldState.clip; - - const movement = { x: e.clientX - oldState.x, y: e.clientY - oldState.y }; - - const ratio = imageInfo == null ? 1 : imageInfo.ratio; - - const { current: imgElement } = imgElementRef; - - if (imgElement == null) throw new UiLogicError('Image element is null.'); - - const moveRatio = { - x: movement.x / imgElement.width, - y: movement.x / imgElement.width / ratio, - }; - - const newRatio = { - x: oldClip.width + moveRatio.x, - y: oldClip.height + moveRatio.y, - }; - - const maxRatio = { - x: Math.min(1 - oldClip.left, newRatio.x), - y: Math.min(1 - oldClip.top, newRatio.y), - }; - - const maxWidthRatio = Math.min(maxRatio.x, maxRatio.y * ratio); - - let newWidth; - if (newRatio.x < 0) { - newWidth = 0; - } else if (newRatio.x > maxWidthRatio) { - newWidth = maxWidthRatio; - } else { - newWidth = newRatio.x; - } - - onChange({ left: oldClip.left, top: oldClip.top, width: newWidth }); - }, - [imageInfo, oldState, onChange] - ); - - const toPercentage = (n: number): string => `${n}%`; - - // fuck!!! I just can't find a better way to implement this in pure css - const containerStyle: React.CSSProperties = (() => { - if (imageInfo == null) { - return { width: '100%', paddingTop: '100%', height: 0 }; - } else { - if (imageInfo.ratio > 1) { - return { - width: toPercentage(100 / imageInfo.ratio), - paddingTop: '100%', - height: 0, - }; - } else { - return { - width: '100%', - paddingTop: toPercentage(100 * imageInfo.ratio), - height: 0, - }; - } - } - })(); - - return ( -
- to crop -
-
-
-
-
- ); -}; - -export default ImageCropper; - -export function applyClipToImage( - image: HTMLImageElement, - clip: Clip, - mimeType: string -): Promise { - return new Promise((resolve, reject) => { - const naturalSize = { - width: image.naturalWidth, - height: image.naturalHeight, - }; - const clipArea = { - x: naturalSize.width * clip.left, - y: naturalSize.height * clip.top, - length: naturalSize.width * clip.width, - }; - - const canvas = document.createElement('canvas'); - canvas.width = clipArea.length; - canvas.height = clipArea.length; - const context = canvas.getContext('2d'); - - if (context == null) throw new Error('Failed to create context.'); - - context.drawImage( - image, - clipArea.x, - clipArea.y, - clipArea.length, - clipArea.length, - 0, - 0, - clipArea.length, - clipArea.length - ); - - canvas.toBlob((blob) => { - if (blob == null) { - reject(new Error('canvas.toBlob returns null')); - } else { - resolve(blob); - } - }, mimeType); - }); -} +import * as React from "react"; +import clsx from "clsx"; + +import { UiLogicError } from "../common"; + +export interface Clip { + left: number; + top: number; + width: number; +} + +interface NormailizedClip extends Clip { + height: number; +} + +interface ImageInfo { + width: number; + height: number; + landscape: boolean; + ratio: number; + maxClipWidth: number; + maxClipHeight: number; +} + +interface ImageCropperSavedState { + clip: NormailizedClip; + x: number; + y: number; + pointerId: number; +} + +export interface ImageCropperProps { + clip: Clip | null; + imageUrl: string; + onChange: (clip: Clip) => void; + imageElementCallback?: (element: HTMLImageElement | null) => void; + className?: string; +} + +const ImageCropper = (props: ImageCropperProps): React.ReactElement => { + const { clip, imageUrl, onChange, imageElementCallback, className } = props; + + const [oldState, setOldState] = React.useState( + null + ); + const [imageInfo, setImageInfo] = React.useState(null); + + const normalizeClip = (c: Clip | null | undefined): NormailizedClip => { + if (c == null) { + return { left: 0, top: 0, width: 0, height: 0 }; + } + + return { + left: c.left || 0, + top: c.top || 0, + width: c.width || 0, + height: imageInfo != null ? (c.width || 0) / imageInfo.ratio : 0, + }; + }; + + const c = normalizeClip(clip); + + const imgElementRef = React.useRef(null); + + const onImageRef = React.useCallback( + (e: HTMLImageElement | null) => { + imgElementRef.current = e; + if (imageElementCallback != null && e == null) { + imageElementCallback(null); + } + }, + [imageElementCallback] + ); + + const onImageLoad = React.useCallback( + (e: React.SyntheticEvent) => { + const img = e.currentTarget; + const landscape = img.naturalWidth >= img.naturalHeight; + + const info = { + width: img.naturalWidth, + height: img.naturalHeight, + landscape, + ratio: img.naturalHeight / img.naturalWidth, + maxClipWidth: landscape ? img.naturalHeight / img.naturalWidth : 1, + maxClipHeight: landscape ? 1 : img.naturalWidth / img.naturalHeight, + }; + setImageInfo(info); + onChange({ left: 0, top: 0, width: info.maxClipWidth }); + if (imageElementCallback != null) { + imageElementCallback(img); + } + }, + [onChange, imageElementCallback] + ); + + const onPointerDown = React.useCallback( + (e: React.PointerEvent) => { + if (oldState != null) return; + e.currentTarget.setPointerCapture(e.pointerId); + setOldState({ + x: e.clientX, + y: e.clientY, + clip: c, + pointerId: e.pointerId, + }); + }, + [oldState, c] + ); + + const onPointerUp = React.useCallback( + (e: React.PointerEvent) => { + if (oldState == null || oldState.pointerId !== e.pointerId) return; + e.currentTarget.releasePointerCapture(e.pointerId); + setOldState(null); + }, + [oldState] + ); + + const onPointerMove = React.useCallback( + (e: React.PointerEvent) => { + if (oldState == null) return; + + const oldClip = oldState.clip; + + const movement = { x: e.clientX - oldState.x, y: e.clientY - oldState.y }; + + const { current: imgElement } = imgElementRef; + + if (imgElement == null) throw new UiLogicError("Image element is null."); + + const moveRatio = { + x: movement.x / imgElement.width, + y: movement.y / imgElement.height, + }; + + const newRatio = { + x: oldClip.left + moveRatio.x, + y: oldClip.top + moveRatio.y, + }; + if (newRatio.x < 0) { + newRatio.x = 0; + } else if (newRatio.x > 1 - oldClip.width) { + newRatio.x = 1 - oldClip.width; + } + if (newRatio.y < 0) { + newRatio.y = 0; + } else if (newRatio.y > 1 - oldClip.height) { + newRatio.y = 1 - oldClip.height; + } + + onChange({ left: newRatio.x, top: newRatio.y, width: oldClip.width }); + }, + [oldState, onChange] + ); + + const onHandlerPointerMove = React.useCallback( + (e: React.PointerEvent) => { + if (oldState == null) return; + + const oldClip = oldState.clip; + + const movement = { x: e.clientX - oldState.x, y: e.clientY - oldState.y }; + + const ratio = imageInfo == null ? 1 : imageInfo.ratio; + + const { current: imgElement } = imgElementRef; + + if (imgElement == null) throw new UiLogicError("Image element is null."); + + const moveRatio = { + x: movement.x / imgElement.width, + y: movement.x / imgElement.width / ratio, + }; + + const newRatio = { + x: oldClip.width + moveRatio.x, + y: oldClip.height + moveRatio.y, + }; + + const maxRatio = { + x: Math.min(1 - oldClip.left, newRatio.x), + y: Math.min(1 - oldClip.top, newRatio.y), + }; + + const maxWidthRatio = Math.min(maxRatio.x, maxRatio.y * ratio); + + let newWidth; + if (newRatio.x < 0) { + newWidth = 0; + } else if (newRatio.x > maxWidthRatio) { + newWidth = maxWidthRatio; + } else { + newWidth = newRatio.x; + } + + onChange({ left: oldClip.left, top: oldClip.top, width: newWidth }); + }, + [imageInfo, oldState, onChange] + ); + + const toPercentage = (n: number): string => `${n}%`; + + // fuck!!! I just can't find a better way to implement this in pure css + const containerStyle: React.CSSProperties = (() => { + if (imageInfo == null) { + return { width: "100%", paddingTop: "100%", height: 0 }; + } else { + if (imageInfo.ratio > 1) { + return { + width: toPercentage(100 / imageInfo.ratio), + paddingTop: "100%", + height: 0, + }; + } else { + return { + width: "100%", + paddingTop: toPercentage(100 * imageInfo.ratio), + height: 0, + }; + } + } + })(); + + return ( +
+ to crop +
+
+
+
+
+ ); +}; + +export default ImageCropper; + +export function applyClipToImage( + image: HTMLImageElement, + clip: Clip, + mimeType: string +): Promise { + return new Promise((resolve, reject) => { + const naturalSize = { + width: image.naturalWidth, + height: image.naturalHeight, + }; + const clipArea = { + x: naturalSize.width * clip.left, + y: naturalSize.height * clip.top, + length: naturalSize.width * clip.width, + }; + + const canvas = document.createElement("canvas"); + canvas.width = clipArea.length; + canvas.height = clipArea.length; + const context = canvas.getContext("2d"); + + if (context == null) throw new Error("Failed to create context."); + + context.drawImage( + image, + clipArea.x, + clipArea.y, + clipArea.length, + clipArea.length, + 0, + 0, + clipArea.length, + clipArea.length + ); + + canvas.toBlob((blob) => { + if (blob == null) { + reject(new Error("canvas.toBlob returns null")); + } else { + resolve(blob); + } + }, mimeType); + }); +} diff --git a/Timeline/ClientApp/src/app/common/LoadingPage.tsx b/Timeline/ClientApp/src/app/common/LoadingPage.tsx index c1bc7105..a849126d 100644 --- a/Timeline/ClientApp/src/app/common/LoadingPage.tsx +++ b/Timeline/ClientApp/src/app/common/LoadingPage.tsx @@ -1,12 +1,12 @@ -import React from 'react'; -import { Spinner } from 'reactstrap'; - -const LoadingPage: React.FC = () => { - return ( -
- -
- ); -}; - -export default LoadingPage; +import React from "react"; +import { Spinner } from "reactstrap"; + +const LoadingPage: React.FC = () => { + return ( +
+ +
+ ); +}; + +export default LoadingPage; diff --git a/Timeline/ClientApp/src/app/common/OperationDialog.tsx b/Timeline/ClientApp/src/app/common/OperationDialog.tsx index 501a353e..bca4580c 100644 --- a/Timeline/ClientApp/src/app/common/OperationDialog.tsx +++ b/Timeline/ClientApp/src/app/common/OperationDialog.tsx @@ -1,381 +1,381 @@ -import React, { useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { - Spinner, - Container, - ModalBody, - Label, - Input, - FormGroup, - FormFeedback, - ModalFooter, - Button, - Modal, - ModalHeader, - FormText, -} from 'reactstrap'; - -import { UiLogicError } from '../common'; - -const DefaultProcessPrompt: React.FC = (_) => { - return ( - - - - ); -}; - -interface DefaultErrorPromptProps { - error?: string; -} - -const DefaultErrorPrompt: React.FC = (props) => { - const { t } = useTranslation(); - - let result =

{t('operationDialog.error')}

; - - if (props.error != null) { - result = ( - <> - {result} -

{props.error}

- - ); - } - - return result; -}; - -export type OperationInputOptionalError = undefined | null | string; - -export interface OperationInputErrorInfo { - [index: number]: OperationInputOptionalError; -} - -export type OperationInputValidator = ( - value: TValue, - values: (string | boolean)[] -) => OperationInputOptionalError | OperationInputErrorInfo; - -export interface OperationTextInputInfo { - type: 'text'; - password?: boolean; - label?: string; - initValue?: string; - textFieldProps?: Omit< - React.InputHTMLAttributes, - 'type' | 'value' | 'onChange' - >; - helperText?: string; - validator?: OperationInputValidator; -} - -export interface OperationBoolInputInfo { - type: 'bool'; - label: string; - initValue?: boolean; -} - -export interface OperationSelectInputInfoOption { - value: string; - label: string; - icon?: React.ReactElement; -} - -export interface OperationSelectInputInfo { - type: 'select'; - label: string; - options: OperationSelectInputInfoOption[]; - initValue?: string; -} - -export type OperationInputInfo = - | OperationTextInputInfo - | OperationBoolInputInfo - | OperationSelectInputInfo; - -interface OperationResult { - type: 'success' | 'failure'; - data: unknown; -} - -interface OperationDialogProps { - open: boolean; - close: () => void; - title: React.ReactNode; - titleColor?: 'default' | 'dangerous' | 'create' | string; - onProcess: (inputs: (string | boolean)[]) => Promise; - inputScheme?: OperationInputInfo[]; - inputPrompt?: string | (() => React.ReactNode); - processPrompt?: () => React.ReactNode; - successPrompt?: (data: unknown) => React.ReactNode; - failurePrompt?: (error: unknown) => React.ReactNode; - onSuccessAndClose?: () => void; -} - -const OperationDialog: React.FC = (props) => { - const inputScheme = props.inputScheme ?? []; - - const { t } = useTranslation(); - - type Step = 'input' | 'process' | OperationResult; - const [step, setStep] = useState('input'); - const [values, setValues] = useState<(boolean | string)[]>( - inputScheme.map((i) => { - if (i.type === 'bool') { - return i.initValue ?? false; - } else if (i.type === 'text' || i.type === 'select') { - return i.initValue ?? ''; - } else { - throw new UiLogicError('Unknown input scheme.'); - } - }) - ); - const [inputError, setInputError] = useState({}); - - const close = (): void => { - if (step !== 'process') { - props.close(); - if ( - typeof step === 'object' && - step.type === 'success' && - props.onSuccessAndClose - ) { - props.onSuccessAndClose(); - } - } else { - console.log('Attempt to close modal when processing.'); - } - }; - - const onConfirm = (): void => { - setStep('process'); - props.onProcess(values).then( - (d: unknown) => { - setStep({ - type: 'success', - data: d, - }); - }, - (e: unknown) => { - setStep({ - type: 'failure', - data: e, - }); - } - ); - }; - - let body: React.ReactNode; - if (step === 'input') { - let inputPrompt = - typeof props.inputPrompt === 'function' - ? props.inputPrompt() - : props.inputPrompt; - inputPrompt =
{inputPrompt}
; - - const updateValue = ( - index: number, - newValue: string | boolean - ): (string | boolean)[] => { - const oldValues = values; - const newValues = oldValues.slice(); - newValues[index] = newValue; - setValues(newValues); - return newValues; - }; - - const testErrorInfo = (errorInfo: OperationInputErrorInfo): boolean => { - for (let i = 0; i < inputScheme.length; i++) { - if (inputScheme[i].type === 'text' && errorInfo[i] != null) { - return true; - } - } - return false; - }; - - const calculateError = ( - oldError: OperationInputErrorInfo, - index: number, - newError: OperationInputOptionalError | OperationInputErrorInfo - ): OperationInputErrorInfo => { - if (newError === undefined) { - return oldError; - } else if (newError === null || typeof newError === 'string') { - return { ...oldError, [index]: newError }; - } else { - const newInputError: OperationInputErrorInfo = { ...oldError }; - for (const [index, error] of Object.entries(newError)) { - if (error !== undefined) { - newInputError[+index] = error as OperationInputOptionalError; - } - } - return newInputError; - } - }; - - const validateAll = (): boolean => { - let newInputError = inputError; - for (let i = 0; i < inputScheme.length; i++) { - const item = inputScheme[i]; - if (item.type === 'text') { - newInputError = calculateError( - newInputError, - i, - item.validator?.(values[i] as string, values) - ); - } - } - const result = !testErrorInfo(newInputError); - setInputError(newInputError); - return result; - }; - - body = ( - <> - - {inputPrompt} - {inputScheme.map((item, index) => { - const value = values[index]; - const error: string | undefined = ((e) => - typeof e === 'string' ? t(e) : undefined)(inputError?.[index]); - - if (item.type === 'text') { - return ( - - {item.label && } - { - const v = e.target.value; - const newValues = updateValue(index, v); - setInputError( - calculateError( - inputError, - index, - item.validator?.(v, newValues) - ) - ); - }} - invalid={error != null} - {...item.textFieldProps} - /> - {error != null && {error}} - {item.helperText && {t(item.helperText)}} - - ); - } else if (item.type === 'bool') { - return ( - - { - updateValue( - index, - (e.target as HTMLInputElement).checked - ); - }} - /> - - - ); - } else if (item.type === 'select') { - return ( - - - { - updateValue(index, event.target.value); - }} - > - {item.options.map((option, i) => { - return ( - - ); - })} - - - ); - } - })} - - - - - - - ); - } else if (step === 'process') { - body = ( - - {props.processPrompt?.() ?? } - - ); - } else { - let content: React.ReactNode; - const result = step; - if (result.type === 'success') { - content = - props.successPrompt?.(result.data) ?? t('operationDialog.success'); - if (typeof content === 'string') - content =

{content}

; - } else { - content = props.failurePrompt?.(result.data) ?? ; - if (typeof content === 'string') - content = ; - } - body = ( - <> - {content} - - - - - ); - } - - const title = typeof props.title === 'string' ? t(props.title) : props.title; - - return ( - - - {title} - - {body} - - ); -}; - -export default OperationDialog; +import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { + Spinner, + Container, + ModalBody, + Label, + Input, + FormGroup, + FormFeedback, + ModalFooter, + Button, + Modal, + ModalHeader, + FormText, +} from "reactstrap"; + +import { UiLogicError } from "../common"; + +const DefaultProcessPrompt: React.FC = (_) => { + return ( + + + + ); +}; + +interface DefaultErrorPromptProps { + error?: string; +} + +const DefaultErrorPrompt: React.FC = (props) => { + const { t } = useTranslation(); + + let result =

{t("operationDialog.error")}

; + + if (props.error != null) { + result = ( + <> + {result} +

{props.error}

+ + ); + } + + return result; +}; + +export type OperationInputOptionalError = undefined | null | string; + +export interface OperationInputErrorInfo { + [index: number]: OperationInputOptionalError; +} + +export type OperationInputValidator = ( + value: TValue, + values: (string | boolean)[] +) => OperationInputOptionalError | OperationInputErrorInfo; + +export interface OperationTextInputInfo { + type: "text"; + password?: boolean; + label?: string; + initValue?: string; + textFieldProps?: Omit< + React.InputHTMLAttributes, + "type" | "value" | "onChange" + >; + helperText?: string; + validator?: OperationInputValidator; +} + +export interface OperationBoolInputInfo { + type: "bool"; + label: string; + initValue?: boolean; +} + +export interface OperationSelectInputInfoOption { + value: string; + label: string; + icon?: React.ReactElement; +} + +export interface OperationSelectInputInfo { + type: "select"; + label: string; + options: OperationSelectInputInfoOption[]; + initValue?: string; +} + +export type OperationInputInfo = + | OperationTextInputInfo + | OperationBoolInputInfo + | OperationSelectInputInfo; + +interface OperationResult { + type: "success" | "failure"; + data: unknown; +} + +interface OperationDialogProps { + open: boolean; + close: () => void; + title: React.ReactNode; + titleColor?: "default" | "dangerous" | "create" | string; + onProcess: (inputs: (string | boolean)[]) => Promise; + inputScheme?: OperationInputInfo[]; + inputPrompt?: string | (() => React.ReactNode); + processPrompt?: () => React.ReactNode; + successPrompt?: (data: unknown) => React.ReactNode; + failurePrompt?: (error: unknown) => React.ReactNode; + onSuccessAndClose?: () => void; +} + +const OperationDialog: React.FC = (props) => { + const inputScheme = props.inputScheme ?? []; + + const { t } = useTranslation(); + + type Step = "input" | "process" | OperationResult; + const [step, setStep] = useState("input"); + const [values, setValues] = useState<(boolean | string)[]>( + inputScheme.map((i) => { + if (i.type === "bool") { + return i.initValue ?? false; + } else if (i.type === "text" || i.type === "select") { + return i.initValue ?? ""; + } else { + throw new UiLogicError("Unknown input scheme."); + } + }) + ); + const [inputError, setInputError] = useState({}); + + const close = (): void => { + if (step !== "process") { + props.close(); + if ( + typeof step === "object" && + step.type === "success" && + props.onSuccessAndClose + ) { + props.onSuccessAndClose(); + } + } else { + console.log("Attempt to close modal when processing."); + } + }; + + const onConfirm = (): void => { + setStep("process"); + props.onProcess(values).then( + (d: unknown) => { + setStep({ + type: "success", + data: d, + }); + }, + (e: unknown) => { + setStep({ + type: "failure", + data: e, + }); + } + ); + }; + + let body: React.ReactNode; + if (step === "input") { + let inputPrompt = + typeof props.inputPrompt === "function" + ? props.inputPrompt() + : props.inputPrompt; + inputPrompt =
{inputPrompt}
; + + const updateValue = ( + index: number, + newValue: string | boolean + ): (string | boolean)[] => { + const oldValues = values; + const newValues = oldValues.slice(); + newValues[index] = newValue; + setValues(newValues); + return newValues; + }; + + const testErrorInfo = (errorInfo: OperationInputErrorInfo): boolean => { + for (let i = 0; i < inputScheme.length; i++) { + if (inputScheme[i].type === "text" && errorInfo[i] != null) { + return true; + } + } + return false; + }; + + const calculateError = ( + oldError: OperationInputErrorInfo, + index: number, + newError: OperationInputOptionalError | OperationInputErrorInfo + ): OperationInputErrorInfo => { + if (newError === undefined) { + return oldError; + } else if (newError === null || typeof newError === "string") { + return { ...oldError, [index]: newError }; + } else { + const newInputError: OperationInputErrorInfo = { ...oldError }; + for (const [index, error] of Object.entries(newError)) { + if (error !== undefined) { + newInputError[+index] = error as OperationInputOptionalError; + } + } + return newInputError; + } + }; + + const validateAll = (): boolean => { + let newInputError = inputError; + for (let i = 0; i < inputScheme.length; i++) { + const item = inputScheme[i]; + if (item.type === "text") { + newInputError = calculateError( + newInputError, + i, + item.validator?.(values[i] as string, values) + ); + } + } + const result = !testErrorInfo(newInputError); + setInputError(newInputError); + return result; + }; + + body = ( + <> + + {inputPrompt} + {inputScheme.map((item, index) => { + const value = values[index]; + const error: string | undefined = ((e) => + typeof e === "string" ? t(e) : undefined)(inputError?.[index]); + + if (item.type === "text") { + return ( + + {item.label && } + { + const v = e.target.value; + const newValues = updateValue(index, v); + setInputError( + calculateError( + inputError, + index, + item.validator?.(v, newValues) + ) + ); + }} + invalid={error != null} + {...item.textFieldProps} + /> + {error != null && {error}} + {item.helperText && {t(item.helperText)}} + + ); + } else if (item.type === "bool") { + return ( + + { + updateValue( + index, + (e.target as HTMLInputElement).checked + ); + }} + /> + + + ); + } else if (item.type === "select") { + return ( + + + { + updateValue(index, event.target.value); + }} + > + {item.options.map((option, i) => { + return ( + + ); + })} + + + ); + } + })} + + + + + + + ); + } else if (step === "process") { + body = ( + + {props.processPrompt?.() ?? } + + ); + } else { + let content: React.ReactNode; + const result = step; + if (result.type === "success") { + content = + props.successPrompt?.(result.data) ?? t("operationDialog.success"); + if (typeof content === "string") + content =

{content}

; + } else { + content = props.failurePrompt?.(result.data) ?? ; + if (typeof content === "string") + content = ; + } + body = ( + <> + {content} + + + + + ); + } + + const title = typeof props.title === "string" ? t(props.title) : props.title; + + return ( + + + {title} + + {body} + + ); +}; + +export default OperationDialog; diff --git a/Timeline/ClientApp/src/app/common/SearchInput.tsx b/Timeline/ClientApp/src/app/common/SearchInput.tsx index 46fb00d1..5a0b0eaa 100644 --- a/Timeline/ClientApp/src/app/common/SearchInput.tsx +++ b/Timeline/ClientApp/src/app/common/SearchInput.tsx @@ -1,63 +1,63 @@ -import React, { useCallback } from 'react'; -import clsx from 'clsx'; -import { Spinner, Input, Button } from 'reactstrap'; -import { useTranslation } from 'react-i18next'; - -export interface SearchInputProps { - value: string; - onChange: (value: string) => void; - onButtonClick: () => void; - className?: string; - loading?: boolean; - buttonText?: string; - placeholder?: string; - additionalButton?: React.ReactNode; -} - -const SearchInput: React.FC = (props) => { - const { onChange, onButtonClick } = props; - - const { t } = useTranslation(); - - const onInputChange = useCallback( - (event: React.ChangeEvent): void => { - onChange(event.currentTarget.value); - }, - [onChange] - ); - - const onInputKeyPress = useCallback( - (event: React.KeyboardEvent): void => { - if (event.key === 'Enter') { - onButtonClick(); - } - }, - [onButtonClick] - ); - - return ( -
- -
- {props.additionalButton} -
-
- {props.loading ? ( - - ) : ( - - )} -
-
- ); -}; - -export default SearchInput; +import React, { useCallback } from "react"; +import clsx from "clsx"; +import { Spinner, Input, Button } from "reactstrap"; +import { useTranslation } from "react-i18next"; + +export interface SearchInputProps { + value: string; + onChange: (value: string) => void; + onButtonClick: () => void; + className?: string; + loading?: boolean; + buttonText?: string; + placeholder?: string; + additionalButton?: React.ReactNode; +} + +const SearchInput: React.FC = (props) => { + const { onChange, onButtonClick } = props; + + const { t } = useTranslation(); + + const onInputChange = useCallback( + (event: React.ChangeEvent): void => { + onChange(event.currentTarget.value); + }, + [onChange] + ); + + const onInputKeyPress = useCallback( + (event: React.KeyboardEvent): void => { + if (event.key === "Enter") { + onButtonClick(); + } + }, + [onButtonClick] + ); + + return ( +
+ +
+ {props.additionalButton} +
+
+ {props.loading ? ( + + ) : ( + + )} +
+
+ ); +}; + +export default SearchInput; diff --git a/Timeline/ClientApp/src/app/common/TimelineLogo.tsx b/Timeline/ClientApp/src/app/common/TimelineLogo.tsx index 1ec62021..27d188fc 100644 --- a/Timeline/ClientApp/src/app/common/TimelineLogo.tsx +++ b/Timeline/ClientApp/src/app/common/TimelineLogo.tsx @@ -1,26 +1,26 @@ -import React, { SVGAttributes } from 'react'; - -export interface TimelineLogoProps extends SVGAttributes { - color?: string; -} - -const TimelineLogo: React.FC = props => { - const { color, ...forwardProps } = props; - const coercedColor = color ?? 'currentcolor'; - return ( - - - - - - ); -}; - -export default TimelineLogo; +import React, { SVGAttributes } from "react"; + +export interface TimelineLogoProps extends SVGAttributes { + color?: string; +} + +const TimelineLogo: React.FC = (props) => { + const { color, ...forwardProps } = props; + const coercedColor = color ?? "currentcolor"; + return ( + + + + + + ); +}; + +export default TimelineLogo; diff --git a/Timeline/ClientApp/src/app/common/UserTimelineLogo.tsx b/Timeline/ClientApp/src/app/common/UserTimelineLogo.tsx index 3b721985..29f6a69f 100644 --- a/Timeline/ClientApp/src/app/common/UserTimelineLogo.tsx +++ b/Timeline/ClientApp/src/app/common/UserTimelineLogo.tsx @@ -1,26 +1,26 @@ -import React, { SVGAttributes } from 'react'; - -export interface UserTimelineLogoProps extends SVGAttributes { - color?: string; -} - -const UserTimelineLogo: React.FC = props => { - const { color, ...forwardProps } = props; - const coercedColor = color ?? 'currentcolor'; - - return ( - - - - - - - - - - - - ); -}; - -export default UserTimelineLogo; +import React, { SVGAttributes } from "react"; + +export interface UserTimelineLogoProps extends SVGAttributes { + color?: string; +} + +const UserTimelineLogo: React.FC = (props) => { + const { color, ...forwardProps } = props; + const coercedColor = color ?? "currentcolor"; + + return ( + + + + + + + + + + + + ); +}; + +export default UserTimelineLogo; diff --git a/Timeline/ClientApp/src/app/common/alert-service.ts b/Timeline/ClientApp/src/app/common/alert-service.ts index 957c5e10..e4c0e653 100644 --- a/Timeline/ClientApp/src/app/common/alert-service.ts +++ b/Timeline/ClientApp/src/app/common/alert-service.ts @@ -1,61 +1,61 @@ -import React from 'react'; -import pull from 'lodash/pull'; - -export interface AlertInfo { - type?: 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info'; - message: string | React.FC | { type: 'i18n'; key: string }; - dismissTime?: number | 'never'; -} - -export interface AlertInfoEx extends AlertInfo { - id: number; -} - -export type AlertConsumer = (alerts: AlertInfoEx) => void; - -export class AlertService { - private consumers: AlertConsumer[] = []; - private savedAlerts: AlertInfoEx[] = []; - private currentId = 1; - - private produce(alert: AlertInfoEx): void { - for (const consumer of this.consumers) { - consumer(alert); - } - } - - registerConsumer(consumer: AlertConsumer): void { - this.consumers.push(consumer); - if (this.savedAlerts.length !== 0) { - for (const alert of this.savedAlerts) { - this.produce(alert); - } - this.savedAlerts = []; - } - } - - unregisterConsumer(consumer: AlertConsumer): void { - pull(this.consumers, consumer); - } - - push(alert: AlertInfo): void { - const newAlert: AlertInfoEx = { ...alert, id: this.currentId++ }; - if (this.consumers.length === 0) { - this.savedAlerts.push(newAlert); - } else { - this.produce(newAlert); - } - } -} - -export const alertService = new AlertService(); - -export function pushAlert(alert: AlertInfo): void { - alertService.push(alert); -} - -export const kAlertHostId = 'alert-host'; - -export function getAlertHost(): HTMLElement | null { - return document.getElementById(kAlertHostId); -} +import React from "react"; +import pull from "lodash/pull"; + +export interface AlertInfo { + type?: "primary" | "secondary" | "success" | "danger" | "warning" | "info"; + message: string | React.FC | { type: "i18n"; key: string }; + dismissTime?: number | "never"; +} + +export interface AlertInfoEx extends AlertInfo { + id: number; +} + +export type AlertConsumer = (alerts: AlertInfoEx) => void; + +export class AlertService { + private consumers: AlertConsumer[] = []; + private savedAlerts: AlertInfoEx[] = []; + private currentId = 1; + + private produce(alert: AlertInfoEx): void { + for (const consumer of this.consumers) { + consumer(alert); + } + } + + registerConsumer(consumer: AlertConsumer): void { + this.consumers.push(consumer); + if (this.savedAlerts.length !== 0) { + for (const alert of this.savedAlerts) { + this.produce(alert); + } + this.savedAlerts = []; + } + } + + unregisterConsumer(consumer: AlertConsumer): void { + pull(this.consumers, consumer); + } + + push(alert: AlertInfo): void { + const newAlert: AlertInfoEx = { ...alert, id: this.currentId++ }; + if (this.consumers.length === 0) { + this.savedAlerts.push(newAlert); + } else { + this.produce(newAlert); + } + } +} + +export const alertService = new AlertService(); + +export function pushAlert(alert: AlertInfo): void { + alertService.push(alert); +} + +export const kAlertHostId = "alert-host"; + +export function getAlertHost(): HTMLElement | null { + return document.getElementById(kAlertHostId); +} diff --git a/Timeline/ClientApp/src/app/common/alert.sass b/Timeline/ClientApp/src/app/common/alert.sass index c3560b87..5b6e65c2 100644 --- a/Timeline/ClientApp/src/app/common/alert.sass +++ b/Timeline/ClientApp/src/app/common/alert.sass @@ -1,15 +1,15 @@ -.alert-container - position: fixed - z-index: $zindex-popover - -@include media-breakpoint-up(sm) - .alert-container - bottom: 0 - right: 0 - -@include media-breakpoint-down(sm) - .alert-container - bottom: 0 - right: 0 - left: 0 - text-align: center +.alert-container + position: fixed + z-index: $zindex-popover + +@include media-breakpoint-up(sm) + .alert-container + bottom: 0 + right: 0 + +@include media-breakpoint-down(sm) + .alert-container + bottom: 0 + right: 0 + left: 0 + text-align: center diff --git a/Timeline/ClientApp/src/app/common/common.sass b/Timeline/ClientApp/src/app/common/common.sass index 78e6fd14..15d34d7c 100644 --- a/Timeline/ClientApp/src/app/common/common.sass +++ b/Timeline/ClientApp/src/app/common/common.sass @@ -1,33 +1,33 @@ -.image-cropper-container - position: relative - box-sizing: border-box - user-select: none - -.image-cropper-container img - position: absolute - left: 0 - top: 0 - width: 100% - height: 100% - -.image-cropper-mask-container - position: absolute - left: 0 - top: 0 - right: 0 - bottom: 0 - overflow: hidden - -.image-cropper-mask - position: absolute - box-shadow: 0 0 0 10000px rgba(255, 255, 255, 80%) - touch-action: none - -.image-cropper-handler - position: absolute - width: 26px - height: 26px - border: black solid 2px - border-radius: 50% - background: white - touch-action: none +.image-cropper-container + position: relative + box-sizing: border-box + user-select: none + +.image-cropper-container img + position: absolute + left: 0 + top: 0 + width: 100% + height: 100% + +.image-cropper-mask-container + position: absolute + left: 0 + top: 0 + right: 0 + bottom: 0 + overflow: hidden + +.image-cropper-mask + position: absolute + box-shadow: 0 0 0 10000px rgba(255, 255, 255, 80%) + touch-action: none + +.image-cropper-handler + position: absolute + width: 26px + height: 26px + border: black solid 2px + border-radius: 50% + background: white + touch-action: none -- cgit v1.2.3 From 8e297d2b659f447814e07676423e973f0f41e560 Mon Sep 17 00:00:00 2001 From: crupest Date: Mon, 24 Aug 2020 23:51:20 +0800 Subject: ... --- Timeline/ClientApp/.eslintignore | 1 - Timeline/ClientApp/.eslintrc.js | 58 ++-- Timeline/ClientApp/.pnp.js | 360 +++++++++++++++++++++ Timeline/ClientApp/package.json | 2 + Timeline/ClientApp/src/app/App.tsx | 1 - Timeline/ClientApp/src/app/about/About.tsx | 4 +- Timeline/ClientApp/src/app/admin/Admin.tsx | 4 +- Timeline/ClientApp/src/app/admin/UserAdmin.tsx | 1 - Timeline/ClientApp/src/app/common/AlertHost.tsx | 4 +- Timeline/ClientApp/src/app/data/timeline.ts | 18 +- Timeline/ClientApp/src/app/data/user.ts | 7 +- Timeline/ClientApp/src/app/home/BoardWithUser.tsx | 1 - .../ClientApp/src/app/home/BoardWithoutUser.tsx | 1 - Timeline/ClientApp/src/app/home/Home.tsx | 2 +- Timeline/ClientApp/src/app/home/OfflineBoard.tsx | 1 - Timeline/ClientApp/src/app/home/TimelineBoard.tsx | 1 - .../src/app/home/TimelineCreateDialog.tsx | 1 - Timeline/ClientApp/src/app/http/mock/user.ts | 1 - Timeline/ClientApp/src/app/http/timeline.ts | 1 + Timeline/ClientApp/src/app/settings/Settings.tsx | 1 - .../src/app/timeline/TimelineInfoCard.tsx | 2 +- .../ClientApp/src/app/timeline/TimelineItem.tsx | 2 - .../ClientApp/src/app/timeline/TimelineMember.tsx | 1 - .../ClientApp/src/app/timeline/TimelinePage.tsx | 3 +- .../src/app/timeline/TimelinePageTemplate.tsx | 2 +- .../src/app/timeline/TimelinePageTemplateUI.tsx | 3 +- .../src/app/timeline/TimelinePostEdit.tsx | 2 - .../app/timeline/TimelinePropertyChangeDialog.tsx | 1 - Timeline/ClientApp/src/app/user/Login.tsx | 7 +- Timeline/ClientApp/src/app/user/User.tsx | 4 +- Timeline/ClientApp/src/app/user/UserInfoCard.tsx | 1 - Timeline/ClientApp/src/app/user/UserPage.tsx | 2 +- Timeline/ClientApp/yarn.lock | 355 +++++++++++++++++++- 33 files changed, 768 insertions(+), 87 deletions(-) (limited to 'Timeline/ClientApp/src/app/common') diff --git a/Timeline/ClientApp/.eslintignore b/Timeline/ClientApp/.eslintignore index 371b5fcb..de5aa4fc 100644 --- a/Timeline/ClientApp/.eslintignore +++ b/Timeline/ClientApp/.eslintignore @@ -1,5 +1,4 @@ .yarn node_modules dist -webpack.*.js .eslintrc.js diff --git a/Timeline/ClientApp/.eslintrc.js b/Timeline/ClientApp/.eslintrc.js index 2013f23d..830a2aa4 100644 --- a/Timeline/ClientApp/.eslintrc.js +++ b/Timeline/ClientApp/.eslintrc.js @@ -1,48 +1,62 @@ +const path = require("path"); + module.exports = { env: { browser: true, - es6: true, + es2020: true, }, extends: [ - 'eslint:recommended', - 'plugin:react/recommended', - 'plugin:@typescript-eslint/eslint-recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', - 'plugin:prettier/recommended', - 'prettier/react', - 'prettier/@typescript-eslint', - 'plugin:react-hooks/recommended', + "eslint:recommended", + "plugin:react/recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", + "plugin:prettier/recommended", + "prettier/react", + "prettier/@typescript-eslint", + "plugin:react-hooks/recommended", + "plugin:import/recommended", + "plugin:import/typescript", ], globals: { - Atomics: 'readonly', - SharedArrayBuffer: 'readonly', + Atomics: "readonly", + SharedArrayBuffer: "readonly", }, - parser: '@typescript-eslint/parser', + parser: "@typescript-eslint/parser", parserOptions: { - project: ['./src/app/tsconfig.json', './src/sw/tsconfig.json'], + project: ["./src/app/tsconfig.json", "./src/sw/tsconfig.json"], ecmaFeatures: { jsx: true, }, - ecmaVersion: 2018, - sourceType: 'module', + sourceType: "module", }, - plugins: ['react', '@typescript-eslint', 'react-hooks'], + plugins: ["react", "@typescript-eslint", "react-hooks", "import"], settings: { react: { - version: 'detect', + version: "detect", + }, + "import/resolver": { + webpack: { + config: path.resolve(__dirname, "webpack.config.dev.js"), + }, }, }, rules: { - 'react/prop-types': 'off', - '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], - '@typescript-eslint/explicit-function-return-type': [ - 'warn', + "react/prop-types": "off", + "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }], + "@typescript-eslint/explicit-function-return-type": [ + "warn", { allowExpressions: true, allowTypedFunctionExpressions: true, allowHigherOrderFunctions: true, }, ], + "import/order": [ + "warn", + { + "newlines-between": "always", + }, + ], }, }; diff --git a/Timeline/ClientApp/.pnp.js b/Timeline/ClientApp/.pnp.js index 4b0d0ff5..ef53bd2c 100644 --- a/Timeline/ClientApp/.pnp.js +++ b/Timeline/ClientApp/.pnp.js @@ -185,6 +185,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "eslint-config-prettier", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:6.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-config-prettier%2Fdownload%2Feslint-config-prettier-6.11.0.tgz" ], + [ + "eslint-import-resolver-webpack", + "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:0.12.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-webpack%2Fdownload%2Feslint-import-resolver-webpack-0.12.2.tgz" + ], + [ + "eslint-plugin-import", + "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.22.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-import%2Fdownload%2Feslint-plugin-import-2.22.0.tgz" + ], [ "eslint-plugin-prettier", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.1.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-prettier%2Fdownload%2Feslint-plugin-prettier-3.1.4.tgz" @@ -404,6 +412,8 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["css-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.2.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-loader%2Fdownload%2Fcss-loader-4.2.1.tgz"], ["eslint", "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"], ["eslint-config-prettier", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:6.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-config-prettier%2Fdownload%2Feslint-config-prettier-6.11.0.tgz"], + ["eslint-import-resolver-webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:0.12.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-webpack%2Fdownload%2Feslint-import-resolver-webpack-0.12.2.tgz"], + ["eslint-plugin-import", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.22.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-import%2Fdownload%2Feslint-plugin-import-2.22.0.tgz"], ["eslint-plugin-prettier", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.1.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-prettier%2Fdownload%2Feslint-plugin-prettier-3.1.4.tgz"], ["eslint-plugin-react", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.20.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react%2Fdownload%2Feslint-plugin-react-7.20.6.tgz"], ["eslint-plugin-react-hooks", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react-hooks%2Fdownload%2Feslint-plugin-react-hooks-4.1.0.tgz"], @@ -3291,6 +3301,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["@types/json5", [ + ["npm:0.0.29::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fjson5%2Fdownload%2F%40types%2Fjson5-0.0.29.tgz", { + "packageLocation": "./.yarn/cache/@types-json5-npm-0.0.29-663cfa6df5-66e9ac0143.zip/node_modules/@types/json5/", + "packageDependencies": [ + ["@types/json5", "npm:0.0.29::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fjson5%2Fdownload%2F%40types%2Fjson5-0.0.29.tgz"] + ], + "linkType": "HARD", + }] + ]], ["@types/keyv", [ ["npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fkeyv%2Fdownload%2F%40types%2Fkeyv-3.1.1.tgz", { "packageLocation": "./.yarn/cache/@types-keyv-npm-3.1.1-f9769fb0ae-3aaf557d5b.zip/node_modules/@types/keyv/", @@ -4251,6 +4270,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["array-find", [ + ["npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-find%2Fdownload%2Farray-find-1.0.0.tgz", { + "packageLocation": "./.yarn/cache/array-find-npm-1.0.0-93a6fccf45-1f6f5270a3.zip/node_modules/array-find/", + "packageDependencies": [ + ["array-find", "npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-find%2Fdownload%2Farray-find-1.0.0.tgz"] + ], + "linkType": "HARD", + }] + ]], ["array-flatten", [ ["npm:1.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-flatten%2Fdownload%2Farray-flatten-1.1.1.tgz", { "packageLocation": "./.yarn/cache/array-flatten-npm-1.1.1-612a788b2c-de7a056451.zip/node_modules/array-flatten/", @@ -4314,6 +4342,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["array.prototype.flat", [ + ["npm:1.2.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray.prototype.flat%2Fdownload%2Farray.prototype.flat-1.2.3.tgz", { + "packageLocation": "./.yarn/cache/array.prototype.flat-npm-1.2.3-d28d243808-f88a474d1c.zip/node_modules/array.prototype.flat/", + "packageDependencies": [ + ["array.prototype.flat", "npm:1.2.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray.prototype.flat%2Fdownload%2Farray.prototype.flat-1.2.3.tgz"], + ["define-properties", "npm:1.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdefine-properties%2Fdownload%2Fdefine-properties-1.1.3.tgz"], + ["es-abstract", "npm:1.17.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fes-abstract%2Fdownload%2Fes-abstract-1.17.6.tgz"] + ], + "linkType": "HARD", + }] + ]], ["array.prototype.flatmap", [ ["npm:1.2.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray.prototype.flatmap%2Fdownload%2Farray.prototype.flatmap-1.2.3.tgz", { "packageLocation": "./.yarn/cache/array.prototype.flatmap-npm-1.2.3-fddf0cc1de-adbf30f271.zip/node_modules/array.prototype.flatmap/", @@ -5676,6 +5715,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["contains-path", [ + ["npm:0.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcontains-path%2Fdownload%2Fcontains-path-0.1.0.tgz", { + "packageLocation": "./.yarn/cache/contains-path-npm-0.1.0-bf2953afcb-59920a59a0.zip/node_modules/contains-path/", + "packageDependencies": [ + ["contains-path", "npm:0.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcontains-path%2Fdownload%2Fcontains-path-0.1.0.tgz"] + ], + "linkType": "HARD", + }] + ]], ["content-disposition", [ ["npm:0.5.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcontent-disposition%2Fdownload%2Fcontent-disposition-0.5.3.tgz", { "packageLocation": "./.yarn/cache/content-disposition-npm-0.5.3-e98afeed39-8f1f235c04.zip/node_modules/content-disposition/", @@ -6428,6 +6476,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }] ]], ["doctrine", [ + ["npm:1.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdoctrine%2Fdownload%2Fdoctrine-1.5.0.tgz", { + "packageLocation": "./.yarn/cache/doctrine-npm-1.5.0-53163999e1-aaffea02f9.zip/node_modules/doctrine/", + "packageDependencies": [ + ["doctrine", "npm:1.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdoctrine%2Fdownload%2Fdoctrine-1.5.0.tgz"], + ["esutils", "npm:2.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fesutils%2Fdownload%2Fesutils-2.0.3.tgz"], + ["isarray", "npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fisarray%2Fdownload%2Fisarray-1.0.0.tgz"] + ], + "linkType": "HARD", + }], ["npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdoctrine%2Fdownload%2Fdoctrine-2.1.0.tgz", { "packageLocation": "./.yarn/cache/doctrine-npm-2.1.0-4199f60fea-4aa55e4675.zip/node_modules/doctrine/", "packageDependencies": [ @@ -6684,6 +6741,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }] ]], ["enhanced-resolve", [ + ["npm:0.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-0.9.1.tgz", { + "packageLocation": "./.yarn/cache/enhanced-resolve-npm-0.9.1-447a118155-c814cd9282.zip/node_modules/enhanced-resolve/", + "packageDependencies": [ + ["enhanced-resolve", "npm:0.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-0.9.1.tgz"], + ["graceful-fs", "npm:4.2.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fgraceful-fs%2Fdownload%2Fgraceful-fs-4.2.4.tgz"], + ["memory-fs", "npm:0.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.2.0.tgz"], + ["tapable", "npm:0.1.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftapable%2Fdownload%2Ftapable-0.1.10.tgz"] + ], + "linkType": "HARD", + }], ["npm:4.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-4.3.0.tgz", { "packageLocation": "./.yarn/cache/enhanced-resolve-npm-4.3.0-a66c6355f8-aecdc0b208.zip/node_modules/enhanced-resolve/", "packageDependencies": [ @@ -6868,6 +6935,79 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["eslint-import-resolver-node", [ + ["npm:0.3.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-node%2Fdownload%2Feslint-import-resolver-node-0.3.4.tgz", { + "packageLocation": "./.yarn/cache/eslint-import-resolver-node-npm-0.3.4-7b7632365b-825e34e662.zip/node_modules/eslint-import-resolver-node/", + "packageDependencies": [ + ["eslint-import-resolver-node", "npm:0.3.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-node%2Fdownload%2Feslint-import-resolver-node-0.3.4.tgz"], + ["debug", "virtual:8c8a8763bc4d11063ade310ae62bd0668563a9ee3e13ffce549c878905c5cfe13a5d3cbcb6ca33a1c75125112870784d9f483ab0575378e363fa1033ba794f97#npm:2.6.9::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz"], + ["resolve", "patch:resolve@npm%3A1.17.0%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Fresolve%252Fdownload%252Fresolve-1.17.0.tgz#builtin::version=1.17.0&hash=3388aa"] + ], + "linkType": "HARD", + }] + ]], + ["eslint-import-resolver-webpack", [ + ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:0.12.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-webpack%2Fdownload%2Feslint-import-resolver-webpack-0.12.2.tgz", { + "packageLocation": "./.yarn/$$virtual/eslint-import-resolver-webpack-virtual-3187d8a474/0/cache/eslint-import-resolver-webpack-npm-0.12.2-e8bad217fb-5310d4383e.zip/node_modules/eslint-import-resolver-webpack/", + "packageDependencies": [ + ["eslint-import-resolver-webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:0.12.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-webpack%2Fdownload%2Feslint-import-resolver-webpack-0.12.2.tgz"], + ["array-find", "npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-find%2Fdownload%2Farray-find-1.0.0.tgz"], + ["debug", "virtual:8c8a8763bc4d11063ade310ae62bd0668563a9ee3e13ffce549c878905c5cfe13a5d3cbcb6ca33a1c75125112870784d9f483ab0575378e363fa1033ba794f97#npm:2.6.9::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz"], + ["enhanced-resolve", "npm:0.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-0.9.1.tgz"], + ["eslint-plugin-import", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.22.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-import%2Fdownload%2Feslint-plugin-import-2.22.0.tgz"], + ["find-root", "npm:1.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-root%2Fdownload%2Ffind-root-1.1.0.tgz"], + ["has", "npm:1.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas%2Fdownload%2Fhas-1.0.3.tgz"], + ["interpret", "npm:1.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Finterpret%2Fdownload%2Finterpret-1.4.0.tgz"], + ["lodash", "npm:4.17.19::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.19.tgz"], + ["node-libs-browser", "npm:2.2.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-libs-browser%2Fdownload%2Fnode-libs-browser-2.2.1.tgz"], + ["resolve", "patch:resolve@npm%3A1.17.0%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Fresolve%252Fdownload%252Fresolve-1.17.0.tgz#builtin::version=1.17.0&hash=3388aa"], + ["semver", "npm:5.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz"], + ["webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.44.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack%2Fdownload%2Fwebpack-4.44.1.tgz"] + ], + "packagePeers": [ + "eslint-plugin-import", + "webpack" + ], + "linkType": "HARD", + }] + ]], + ["eslint-module-utils", [ + ["npm:2.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-module-utils%2Fdownload%2Feslint-module-utils-2.6.0.tgz", { + "packageLocation": "./.yarn/cache/eslint-module-utils-npm-2.6.0-57b7c7dc6a-f584af1764.zip/node_modules/eslint-module-utils/", + "packageDependencies": [ + ["eslint-module-utils", "npm:2.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-module-utils%2Fdownload%2Feslint-module-utils-2.6.0.tgz"], + ["debug", "virtual:8c8a8763bc4d11063ade310ae62bd0668563a9ee3e13ffce549c878905c5cfe13a5d3cbcb6ca33a1c75125112870784d9f483ab0575378e363fa1033ba794f97#npm:2.6.9::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz"], + ["pkg-dir", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-2.0.0.tgz"] + ], + "linkType": "HARD", + }] + ]], + ["eslint-plugin-import", [ + ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.22.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-import%2Fdownload%2Feslint-plugin-import-2.22.0.tgz", { + "packageLocation": "./.yarn/$$virtual/eslint-plugin-import-virtual-bb7e8375cb/0/cache/eslint-plugin-import-npm-2.22.0-e8b10e811e-ad41aec63d.zip/node_modules/eslint-plugin-import/", + "packageDependencies": [ + ["eslint-plugin-import", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.22.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-import%2Fdownload%2Feslint-plugin-import-2.22.0.tgz"], + ["array-includes", "npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-includes%2Fdownload%2Farray-includes-3.1.1.tgz"], + ["array.prototype.flat", "npm:1.2.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray.prototype.flat%2Fdownload%2Farray.prototype.flat-1.2.3.tgz"], + ["contains-path", "npm:0.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcontains-path%2Fdownload%2Fcontains-path-0.1.0.tgz"], + ["debug", "virtual:8c8a8763bc4d11063ade310ae62bd0668563a9ee3e13ffce549c878905c5cfe13a5d3cbcb6ca33a1c75125112870784d9f483ab0575378e363fa1033ba794f97#npm:2.6.9::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz"], + ["doctrine", "npm:1.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdoctrine%2Fdownload%2Fdoctrine-1.5.0.tgz"], + ["eslint", "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"], + ["eslint-import-resolver-node", "npm:0.3.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-node%2Fdownload%2Feslint-import-resolver-node-0.3.4.tgz"], + ["eslint-module-utils", "npm:2.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-module-utils%2Fdownload%2Feslint-module-utils-2.6.0.tgz"], + ["has", "npm:1.0.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas%2Fdownload%2Fhas-1.0.3.tgz"], + ["minimatch", "npm:3.0.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fminimatch%2Fdownload%2Fminimatch-3.0.4.tgz"], + ["object.values", "npm:1.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fobject.values%2Fdownload%2Fobject.values-1.1.1.tgz"], + ["read-pkg-up", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg-up%2Fdownload%2Fread-pkg-up-2.0.0.tgz"], + ["resolve", "patch:resolve@npm%3A1.17.0%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Fresolve%252Fdownload%252Fresolve-1.17.0.tgz#builtin::version=1.17.0&hash=3388aa"], + ["tsconfig-paths", "npm:3.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsconfig-paths%2Fdownload%2Ftsconfig-paths-3.9.0.tgz"] + ], + "packagePeers": [ + "eslint" + ], + "linkType": "HARD", + }] + ]], ["eslint-plugin-prettier", [ ["virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.1.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-prettier%2Fdownload%2Feslint-plugin-prettier-3.1.4.tgz", { "packageLocation": "./.yarn/$$virtual/eslint-plugin-prettier-virtual-b3c2338d79/0/cache/eslint-plugin-prettier-npm-3.1.4-d88d887708-4e4df15579.zip/node_modules/eslint-plugin-prettier/", @@ -7416,7 +7556,24 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["find-root", [ + ["npm:1.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-root%2Fdownload%2Ffind-root-1.1.0.tgz", { + "packageLocation": "./.yarn/cache/find-root-npm-1.1.0-80f44a9a17-34f9eeb725.zip/node_modules/find-root/", + "packageDependencies": [ + ["find-root", "npm:1.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-root%2Fdownload%2Ffind-root-1.1.0.tgz"] + ], + "linkType": "HARD", + }] + ]], ["find-up", [ + ["npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-2.1.0.tgz", { + "packageLocation": "./.yarn/cache/find-up-npm-2.1.0-cd7301714d-9dedb89f93.zip/node_modules/find-up/", + "packageDependencies": [ + ["find-up", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-2.1.0.tgz"], + ["locate-path", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocate-path%2Fdownload%2Flocate-path-2.0.0.tgz"] + ], + "linkType": "HARD", + }], ["npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-3.0.0.tgz", { "packageLocation": "./.yarn/cache/find-up-npm-3.0.0-cee70ed7ef-c5422fc723.zip/node_modules/find-up/", "packageDependencies": [ @@ -8167,6 +8324,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["hosted-git-info", [ + ["npm:2.8.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhosted-git-info%2Fdownload%2Fhosted-git-info-2.8.8.tgz", { + "packageLocation": "./.yarn/cache/hosted-git-info-npm-2.8.8-7d1b32a089-3ecc389dc6.zip/node_modules/hosted-git-info/", + "packageDependencies": [ + ["hosted-git-info", "npm:2.8.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhosted-git-info%2Fdownload%2Fhosted-git-info-2.8.8.tgz"] + ], + "linkType": "HARD", + }] + ]], ["hpack.js", [ ["npm:2.1.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhpack.js%2Fdownload%2Fhpack.js-2.1.6.tgz", { "packageLocation": "./.yarn/cache/hpack.js-npm-2.1.6-23e0bbd2b9-a22a28aa31.zip/node_modules/hpack.js/", @@ -9392,6 +9558,19 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["load-json-file", [ + ["npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fload-json-file%2Fdownload%2Fload-json-file-2.0.0.tgz", { + "packageLocation": "./.yarn/cache/load-json-file-npm-2.0.0-6c4dbfa60e-c6ea93d360.zip/node_modules/load-json-file/", + "packageDependencies": [ + ["load-json-file", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fload-json-file%2Fdownload%2Fload-json-file-2.0.0.tgz"], + ["graceful-fs", "npm:4.2.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fgraceful-fs%2Fdownload%2Fgraceful-fs-4.2.4.tgz"], + ["parse-json", "npm:2.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-2.2.0.tgz"], + ["pify", "npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpify%2Fdownload%2Fpify-2.3.0.tgz"], + ["strip-bom", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-bom%2Fdownload%2Fstrip-bom-3.0.0.tgz"] + ], + "linkType": "HARD", + }] + ]], ["loader-runner", [ ["npm:2.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-runner%2Fdownload%2Floader-runner-2.4.0.tgz", { "packageLocation": "./.yarn/cache/loader-runner-npm-2.4.0-ec901bb9ff-9173b602e8.zip/node_modules/loader-runner/", @@ -9434,6 +9613,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }] ]], ["locate-path", [ + ["npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocate-path%2Fdownload%2Flocate-path-2.0.0.tgz", { + "packageLocation": "./.yarn/cache/locate-path-npm-2.0.0-2561ff48c2-ee5a888d68.zip/node_modules/locate-path/", + "packageDependencies": [ + ["locate-path", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocate-path%2Fdownload%2Flocate-path-2.0.0.tgz"], + ["p-locate", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-2.0.0.tgz"], + ["path-exists", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-exists%2Fdownload%2Fpath-exists-3.0.0.tgz"] + ], + "linkType": "HARD", + }], ["npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocate-path%2Fdownload%2Flocate-path-3.0.0.tgz", { "packageLocation": "./.yarn/cache/locate-path-npm-3.0.0-05cc4c2e8a-0b6bf0c1bb.zip/node_modules/locate-path/", "packageDependencies": [ @@ -9644,6 +9832,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }] ]], ["memory-fs", [ + ["npm:0.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.2.0.tgz", { + "packageLocation": "./.yarn/cache/memory-fs-npm-0.2.0-d4de38f132-373cf2a451.zip/node_modules/memory-fs/", + "packageDependencies": [ + ["memory-fs", "npm:0.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.2.0.tgz"] + ], + "linkType": "HARD", + }], ["npm:0.4.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.4.1.tgz", { "packageLocation": "./.yarn/cache/memory-fs-npm-0.4.1-75bd36d5b4-ba79207118.zip/node_modules/memory-fs/", "packageDependencies": [ @@ -10221,6 +10416,19 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["normalize-package-data", [ + ["npm:2.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnormalize-package-data%2Fdownload%2Fnormalize-package-data-2.5.0.tgz", { + "packageLocation": "./.yarn/cache/normalize-package-data-npm-2.5.0-4d392e3f0a-97d4d6b061.zip/node_modules/normalize-package-data/", + "packageDependencies": [ + ["normalize-package-data", "npm:2.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnormalize-package-data%2Fdownload%2Fnormalize-package-data-2.5.0.tgz"], + ["hosted-git-info", "npm:2.8.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhosted-git-info%2Fdownload%2Fhosted-git-info-2.8.8.tgz"], + ["resolve", "patch:resolve@npm%3A1.17.0%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Fresolve%252Fdownload%252Fresolve-1.17.0.tgz#builtin::version=1.17.0&hash=3388aa"], + ["semver", "npm:5.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz"], + ["validate-npm-package-license", "npm:3.0.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fvalidate-npm-package-license%2Fdownload%2Fvalidate-npm-package-license-3.0.4.tgz"] + ], + "linkType": "HARD", + }] + ]], ["normalize-path", [ ["npm:2.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnormalize-path%2Fdownload%2Fnormalize-path-2.1.1.tgz", { "packageLocation": "./.yarn/cache/normalize-path-npm-2.1.1-0182e75f79-9eb82b2f6a.zip/node_modules/normalize-path/", @@ -10606,6 +10814,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }] ]], ["p-limit", [ + ["npm:1.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-limit%2Fdownload%2Fp-limit-1.3.0.tgz", { + "packageLocation": "./.yarn/cache/p-limit-npm-1.3.0-8733d5eba4-579cbd3d6c.zip/node_modules/p-limit/", + "packageDependencies": [ + ["p-limit", "npm:1.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-limit%2Fdownload%2Fp-limit-1.3.0.tgz"], + ["p-try", "npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-try%2Fdownload%2Fp-try-1.0.0.tgz"] + ], + "linkType": "HARD", + }], ["npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-limit%2Fdownload%2Fp-limit-2.3.0.tgz", { "packageLocation": "./.yarn/cache/p-limit-npm-2.3.0-1a838d725f-5f20492a25.zip/node_modules/p-limit/", "packageDependencies": [ @@ -10624,6 +10840,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }] ]], ["p-locate", [ + ["npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-2.0.0.tgz", { + "packageLocation": "./.yarn/cache/p-locate-npm-2.0.0-d80a803b39-b6dabbd855.zip/node_modules/p-locate/", + "packageDependencies": [ + ["p-locate", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-2.0.0.tgz"], + ["p-limit", "npm:1.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-limit%2Fdownload%2Fp-limit-1.3.0.tgz"] + ], + "linkType": "HARD", + }], ["npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-3.0.0.tgz", { "packageLocation": "./.yarn/cache/p-locate-npm-3.0.0-e428a293a5-3ee9e3ed0b.zip/node_modules/p-locate/", "packageDependencies": [ @@ -10669,6 +10893,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }] ]], ["p-try", [ + ["npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-try%2Fdownload%2Fp-try-1.0.0.tgz", { + "packageLocation": "./.yarn/cache/p-try-npm-1.0.0-8c8e61438d-85739d77b3.zip/node_modules/p-try/", + "packageDependencies": [ + ["p-try", "npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-try%2Fdownload%2Fp-try-1.0.0.tgz"] + ], + "linkType": "HARD", + }], ["npm:2.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-try%2Fdownload%2Fp-try-2.2.0.tgz", { "packageLocation": "./.yarn/cache/p-try-npm-2.2.0-ed6cbde710-20983f3765.zip/node_modules/p-try/", "packageDependencies": [ @@ -10735,6 +10966,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }] ]], ["parse-json", [ + ["npm:2.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-2.2.0.tgz", { + "packageLocation": "./.yarn/cache/parse-json-npm-2.2.0-801beb0840-920582196a.zip/node_modules/parse-json/", + "packageDependencies": [ + ["parse-json", "npm:2.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-2.2.0.tgz"], + ["error-ex", "npm:1.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ferror-ex%2Fdownload%2Ferror-ex-1.3.2.tgz"] + ], + "linkType": "HARD", + }], ["npm:4.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-4.0.0.tgz", { "packageLocation": "./.yarn/cache/parse-json-npm-4.0.0-8cd06cd604-fa9d23708f.zip/node_modules/parse-json/", "packageDependencies": [ @@ -10878,6 +11117,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }] ]], ["path-type", [ + ["npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-type%2Fdownload%2Fpath-type-2.0.0.tgz", { + "packageLocation": "./.yarn/cache/path-type-npm-2.0.0-59132af1ec-d028f828df.zip/node_modules/path-type/", + "packageDependencies": [ + ["path-type", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-type%2Fdownload%2Fpath-type-2.0.0.tgz"], + ["pify", "npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpify%2Fdownload%2Fpify-2.3.0.tgz"] + ], + "linkType": "HARD", + }], ["npm:4.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-type%2Fdownload%2Fpath-type-4.0.0.tgz", { "packageLocation": "./.yarn/cache/path-type-npm-4.0.0-307bedbdb8-ef5835f2eb.zip/node_modules/path-type/", "packageDependencies": [ @@ -10963,6 +11210,14 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }] ]], ["pkg-dir", [ + ["npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-2.0.0.tgz", { + "packageLocation": "./.yarn/cache/pkg-dir-npm-2.0.0-bed7e047e5-f8ae3a1517.zip/node_modules/pkg-dir/", + "packageDependencies": [ + ["pkg-dir", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-2.0.0.tgz"], + ["find-up", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-2.1.0.tgz"] + ], + "linkType": "HARD", + }], ["npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-3.0.0.tgz", { "packageLocation": "./.yarn/cache/pkg-dir-npm-3.0.0-0903fcee43-f29a7d0134.zip/node_modules/pkg-dir/", "packageDependencies": [ @@ -12094,6 +12349,29 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["read-pkg", [ + ["npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg%2Fdownload%2Fread-pkg-2.0.0.tgz", { + "packageLocation": "./.yarn/cache/read-pkg-npm-2.0.0-33997d44e1-ddf911317f.zip/node_modules/read-pkg/", + "packageDependencies": [ + ["read-pkg", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg%2Fdownload%2Fread-pkg-2.0.0.tgz"], + ["load-json-file", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fload-json-file%2Fdownload%2Fload-json-file-2.0.0.tgz"], + ["normalize-package-data", "npm:2.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnormalize-package-data%2Fdownload%2Fnormalize-package-data-2.5.0.tgz"], + ["path-type", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-type%2Fdownload%2Fpath-type-2.0.0.tgz"] + ], + "linkType": "HARD", + }] + ]], + ["read-pkg-up", [ + ["npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg-up%2Fdownload%2Fread-pkg-up-2.0.0.tgz", { + "packageLocation": "./.yarn/cache/read-pkg-up-npm-2.0.0-bf8b4f9d8a-f35e4cb457.zip/node_modules/read-pkg-up/", + "packageDependencies": [ + ["read-pkg-up", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg-up%2Fdownload%2Fread-pkg-up-2.0.0.tgz"], + ["find-up", "npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-2.1.0.tgz"], + ["read-pkg", "npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg%2Fdownload%2Fread-pkg-2.0.0.tgz"] + ], + "linkType": "HARD", + }] + ]], ["readable-stream", [ ["npm:2.3.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freadable-stream%2Fdownload%2Freadable-stream-2.3.7.tgz", { "packageLocation": "./.yarn/cache/readable-stream-npm-2.3.7-f79a45df7e-6e38265606.zip/node_modules/readable-stream/", @@ -13135,6 +13413,46 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["spdx-correct", [ + ["npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-correct%2Fdownload%2Fspdx-correct-3.1.1.tgz", { + "packageLocation": "./.yarn/cache/spdx-correct-npm-3.1.1-f3740410f8-f3413eb225.zip/node_modules/spdx-correct/", + "packageDependencies": [ + ["spdx-correct", "npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-correct%2Fdownload%2Fspdx-correct-3.1.1.tgz"], + ["spdx-expression-parse", "npm:3.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-expression-parse%2Fdownload%2Fspdx-expression-parse-3.0.1.tgz"], + ["spdx-license-ids", "npm:3.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-license-ids%2Fdownload%2Fspdx-license-ids-3.0.5.tgz"] + ], + "linkType": "HARD", + }] + ]], + ["spdx-exceptions", [ + ["npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-exceptions%2Fdownload%2Fspdx-exceptions-2.3.0.tgz", { + "packageLocation": "./.yarn/cache/spdx-exceptions-npm-2.3.0-b9d007563f-3cbd249889.zip/node_modules/spdx-exceptions/", + "packageDependencies": [ + ["spdx-exceptions", "npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-exceptions%2Fdownload%2Fspdx-exceptions-2.3.0.tgz"] + ], + "linkType": "HARD", + }] + ]], + ["spdx-expression-parse", [ + ["npm:3.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-expression-parse%2Fdownload%2Fspdx-expression-parse-3.0.1.tgz", { + "packageLocation": "./.yarn/cache/spdx-expression-parse-npm-3.0.1-e386dadbb9-f0211cada3.zip/node_modules/spdx-expression-parse/", + "packageDependencies": [ + ["spdx-expression-parse", "npm:3.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-expression-parse%2Fdownload%2Fspdx-expression-parse-3.0.1.tgz"], + ["spdx-exceptions", "npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-exceptions%2Fdownload%2Fspdx-exceptions-2.3.0.tgz"], + ["spdx-license-ids", "npm:3.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-license-ids%2Fdownload%2Fspdx-license-ids-3.0.5.tgz"] + ], + "linkType": "HARD", + }] + ]], + ["spdx-license-ids", [ + ["npm:3.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-license-ids%2Fdownload%2Fspdx-license-ids-3.0.5.tgz", { + "packageLocation": "./.yarn/cache/spdx-license-ids-npm-3.0.5-d72e7a737e-4ff7c0615a.zip/node_modules/spdx-license-ids/", + "packageDependencies": [ + ["spdx-license-ids", "npm:3.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-license-ids%2Fdownload%2Fspdx-license-ids-3.0.5.tgz"] + ], + "linkType": "HARD", + }] + ]], ["spdy", [ ["npm:4.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdy%2Fdownload%2Fspdy-4.0.2.tgz", { "packageLocation": "./.yarn/cache/spdy-npm-4.0.2-c75dcd93ce-388d39324d.zip/node_modules/spdy/", @@ -13439,6 +13757,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["strip-bom", [ + ["npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-bom%2Fdownload%2Fstrip-bom-3.0.0.tgz", { + "packageLocation": "./.yarn/cache/strip-bom-npm-3.0.0-ed0d0bfd30-361dd1dd08.zip/node_modules/strip-bom/", + "packageDependencies": [ + ["strip-bom", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-bom%2Fdownload%2Fstrip-bom-3.0.0.tgz"] + ], + "linkType": "HARD", + }] + ]], ["strip-comments", [ ["npm:1.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-comments%2Fdownload%2Fstrip-comments-1.0.2.tgz", { "packageLocation": "./.yarn/cache/strip-comments-npm-1.0.2-f0a6d3bb12-21d667d3ba.zip/node_modules/strip-comments/", @@ -13530,6 +13857,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }] ]], ["tapable", [ + ["npm:0.1.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftapable%2Fdownload%2Ftapable-0.1.10.tgz", { + "packageLocation": "./.yarn/cache/tapable-npm-0.1.10-47dee951fe-5604e1127d.zip/node_modules/tapable/", + "packageDependencies": [ + ["tapable", "npm:0.1.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftapable%2Fdownload%2Ftapable-0.1.10.tgz"] + ], + "linkType": "HARD", + }], ["npm:1.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftapable%2Fdownload%2Ftapable-1.1.3.tgz", { "packageLocation": "./.yarn/cache/tapable-npm-1.1.3-5d1594602f-b2c2ab2026.zip/node_modules/tapable/", "packageDependencies": [ @@ -13695,6 +14029,8 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["css-loader", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.2.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcss-loader%2Fdownload%2Fcss-loader-4.2.1.tgz"], ["eslint", "npm:7.7.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.7.0.tgz"], ["eslint-config-prettier", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:6.11.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-config-prettier%2Fdownload%2Feslint-config-prettier-6.11.0.tgz"], + ["eslint-import-resolver-webpack", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:0.12.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-webpack%2Fdownload%2Feslint-import-resolver-webpack-0.12.2.tgz"], + ["eslint-plugin-import", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:2.22.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-import%2Fdownload%2Feslint-plugin-import-2.22.0.tgz"], ["eslint-plugin-prettier", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:3.1.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-prettier%2Fdownload%2Feslint-plugin-prettier-3.1.4.tgz"], ["eslint-plugin-react", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:7.20.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react%2Fdownload%2Feslint-plugin-react-7.20.6.tgz"], ["eslint-plugin-react-hooks", "virtual:71f98ed0939a4e8e7ea376e302a494701bc5b6aa7a7eb81870139ee3950a7c417a3d13b346b5b526d93952a598dffe628a0fac2148047debade23536cb3d7957#npm:4.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-react-hooks%2Fdownload%2Feslint-plugin-react-hooks-4.1.0.tgz"], @@ -13888,6 +14224,19 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["tsconfig-paths", [ + ["npm:3.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsconfig-paths%2Fdownload%2Ftsconfig-paths-3.9.0.tgz", { + "packageLocation": "./.yarn/cache/tsconfig-paths-npm-3.9.0-39cafa29c9-5383ba626b.zip/node_modules/tsconfig-paths/", + "packageDependencies": [ + ["tsconfig-paths", "npm:3.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsconfig-paths%2Fdownload%2Ftsconfig-paths-3.9.0.tgz"], + ["@types/json5", "npm:0.0.29::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fjson5%2Fdownload%2F%40types%2Fjson5-0.0.29.tgz"], + ["json5", "npm:1.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-1.0.1.tgz"], + ["minimist", "npm:1.2.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fminimist%2Fdownload%2Fminimist-1.2.5.tgz"], + ["strip-bom", "npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-bom%2Fdownload%2Fstrip-bom-3.0.0.tgz"] + ], + "linkType": "HARD", + }] + ]], ["tslib", [ ["npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.13.0.tgz", { "packageLocation": "./.yarn/cache/tslib-npm-1.13.0-630f8c4e72-5dc3bdaea3.zip/node_modules/tslib/", @@ -14322,6 +14671,17 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD", }] ]], + ["validate-npm-package-license", [ + ["npm:3.0.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fvalidate-npm-package-license%2Fdownload%2Fvalidate-npm-package-license-3.0.4.tgz", { + "packageLocation": "./.yarn/cache/validate-npm-package-license-npm-3.0.4-f515d7a10c-940899bd4e.zip/node_modules/validate-npm-package-license/", + "packageDependencies": [ + ["validate-npm-package-license", "npm:3.0.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fvalidate-npm-package-license%2Fdownload%2Fvalidate-npm-package-license-3.0.4.tgz"], + ["spdx-correct", "npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-correct%2Fdownload%2Fspdx-correct-3.1.1.tgz"], + ["spdx-expression-parse", "npm:3.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-expression-parse%2Fdownload%2Fspdx-expression-parse-3.0.1.tgz"] + ], + "linkType": "HARD", + }] + ]], ["value-equal", [ ["npm:1.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fvalue-equal%2Fdownload%2Fvalue-equal-1.0.1.tgz", { "packageLocation": "./.yarn/cache/value-equal-npm-1.0.1-ce12345615-ae8cc7bbb2.zip/node_modules/value-equal/", diff --git a/Timeline/ClientApp/package.json b/Timeline/ClientApp/package.json index a2f6e051..b633630b 100644 --- a/Timeline/ClientApp/package.json +++ b/Timeline/ClientApp/package.json @@ -86,6 +86,8 @@ "css-loader": "^4.2.1", "eslint": "^7.7.0", "eslint-config-prettier": "^6.11.0", + "eslint-import-resolver-webpack": "^0.12.2", + "eslint-plugin-import": "^2.22.0", "eslint-plugin-prettier": "^3.1.4", "eslint-plugin-react": "^7.20.6", "eslint-plugin-react-hooks": "^4.1.0", diff --git a/Timeline/ClientApp/src/app/App.tsx b/Timeline/ClientApp/src/app/App.tsx index 7b382c2f..74deddda 100644 --- a/Timeline/ClientApp/src/app/App.tsx +++ b/Timeline/ClientApp/src/app/App.tsx @@ -11,7 +11,6 @@ import About from "./about/About"; import User from "./user/User"; import TimelinePage from "./timeline/TimelinePage"; import AlertHost from "./common/AlertHost"; - import { dataStorage } from "./data/common"; import { userService, useRawUser } from "./data/user"; diff --git a/Timeline/ClientApp/src/app/about/About.tsx b/Timeline/ClientApp/src/app/about/About.tsx index 751fca14..519eef18 100644 --- a/Timeline/ClientApp/src/app/about/About.tsx +++ b/Timeline/ClientApp/src/app/about/About.tsx @@ -1,11 +1,11 @@ import React from "react"; import { useTranslation, Trans } from "react-i18next"; +import AppBar from "../common/AppBar"; + import authorAvatarUrl from "./author-avatar.png"; import githubLogoUrl from "./github.png"; -import AppBar from "../common/AppBar"; - const frontendCredits: { name: string; url: string; diff --git a/Timeline/ClientApp/src/app/admin/Admin.tsx b/Timeline/ClientApp/src/app/admin/Admin.tsx index 2f8b2c05..e2f71091 100644 --- a/Timeline/ClientApp/src/app/admin/Admin.tsx +++ b/Timeline/ClientApp/src/app/admin/Admin.tsx @@ -10,10 +10,10 @@ import { import classnames from "classnames"; import AppBar from "../common/AppBar"; -import UserAdmin from "./UserAdmin"; - import { UserWithToken } from "../data/user"; +import UserAdmin from "./UserAdmin"; + interface AdminProps { user: UserWithToken; } diff --git a/Timeline/ClientApp/src/app/admin/UserAdmin.tsx b/Timeline/ClientApp/src/app/admin/UserAdmin.tsx index 57eed455..1bf3bda1 100644 --- a/Timeline/ClientApp/src/app/admin/UserAdmin.tsx +++ b/Timeline/ClientApp/src/app/admin/UserAdmin.tsx @@ -13,7 +13,6 @@ import { import axios from "axios"; import OperationDialog from "../common/OperationDialog"; - import { User, UserWithToken } from "../data/user"; const apiBaseUrl = "/api"; diff --git a/Timeline/ClientApp/src/app/common/AlertHost.tsx b/Timeline/ClientApp/src/app/common/AlertHost.tsx index e22354fa..bfcf5c00 100644 --- a/Timeline/ClientApp/src/app/common/AlertHost.tsx +++ b/Timeline/ClientApp/src/app/common/AlertHost.tsx @@ -2,6 +2,7 @@ import React, { useCallback } from "react"; import { Alert } from "reactstrap"; import without from "lodash/without"; import concat from "lodash/concat"; +import { useTranslation } from "react-i18next"; import { alertService, @@ -9,7 +10,6 @@ import { kAlertHostId, AlertInfo, } from "./alert-service"; -import { useTranslation } from "react-i18next"; interface AutoCloseAlertProps { alert: AlertInfo; @@ -56,7 +56,7 @@ interface AlertInfoExEx extends AlertInfoEx { close: () => void; } -export const AlertHost: React.FC = () => { +const AlertHost: React.FC = () => { const [alerts, setAlerts] = React.useState([]); // react guarantee that state setters are stable, so we don't need to add it to dependency list diff --git a/Timeline/ClientApp/src/app/data/timeline.ts b/Timeline/ClientApp/src/app/data/timeline.ts index ed6cffd6..8e8860a3 100644 --- a/Timeline/ClientApp/src/app/data/timeline.ts +++ b/Timeline/ClientApp/src/app/data/timeline.ts @@ -5,16 +5,6 @@ import { map, switchMap, startWith } from "rxjs/operators"; import { uniqBy } from "lodash"; import { convertError } from "../utilities/rxjs"; - -import { dataStorage, throwIfNotNetworkError, BlobOrStatus } from "./common"; -import { DataHub, WithSyncStatus } from "./DataHub"; - -import { UserAuthInfo, checkLogin, userService, userInfoService } from "./user"; - -export { kTimelineVisibilities } from "../http/timeline"; - -export type { TimelineVisibility } from "../http/timeline"; - import { TimelineVisibility, HttpTimelineInfo, @@ -32,6 +22,14 @@ import { import { BlobWithEtag, NotModified, HttpForbiddenError } from "../http/common"; import { HttpUser } from "../http/user"; +import { dataStorage, throwIfNotNetworkError, BlobOrStatus } from "./common"; +import { DataHub, WithSyncStatus } from "./DataHub"; +import { UserAuthInfo, checkLogin, userService, userInfoService } from "./user"; + +export { kTimelineVisibilities } from "../http/timeline"; + +export type { TimelineVisibility } from "../http/timeline"; + export type TimelineInfo = HttpTimelineInfo; export type TimelineChangePropertyRequest = HttpTimelinePatchRequest; export type TimelineCreatePostRequest = HttpTimelinePostPostRequest; diff --git a/Timeline/ClientApp/src/app/data/user.ts b/Timeline/ClientApp/src/app/data/user.ts index 8aee0c5f..ceabdbe2 100644 --- a/Timeline/ClientApp/src/app/data/user.ts +++ b/Timeline/ClientApp/src/app/data/user.ts @@ -5,10 +5,6 @@ import { map, filter } from "rxjs/operators"; import { UiLogicError } from "../common"; import { convertError } from "../utilities/rxjs"; import { pushAlert } from "../common/alert-service"; - -import { dataStorage, throwIfNotNetworkError } from "./common"; -import { DataHub } from "./DataHub"; - import { HttpNetworkError, BlobWithEtag, NotModified } from "../http/common"; import { getHttpTokenClient, @@ -20,6 +16,9 @@ import { HttpUser, } from "../http/user"; +import { DataHub } from "./DataHub"; +import { dataStorage, throwIfNotNetworkError } from "./common"; + export type User = HttpUser; export interface UserAuthInfo { diff --git a/Timeline/ClientApp/src/app/home/BoardWithUser.tsx b/Timeline/ClientApp/src/app/home/BoardWithUser.tsx index 4910aebe..22a4667c 100644 --- a/Timeline/ClientApp/src/app/home/BoardWithUser.tsx +++ b/Timeline/ClientApp/src/app/home/BoardWithUser.tsx @@ -4,7 +4,6 @@ import { useTranslation } from "react-i18next"; import { UserWithToken } from "../data/user"; import { TimelineInfo } from "../data/timeline"; - import { getHttpTimelineClient } from "../http/timeline"; import TimelineBoard from "./TimelineBoard"; diff --git a/Timeline/ClientApp/src/app/home/BoardWithoutUser.tsx b/Timeline/ClientApp/src/app/home/BoardWithoutUser.tsx index a7dc36be..972c1b25 100644 --- a/Timeline/ClientApp/src/app/home/BoardWithoutUser.tsx +++ b/Timeline/ClientApp/src/app/home/BoardWithoutUser.tsx @@ -2,7 +2,6 @@ import React from "react"; import { Row, Col } from "reactstrap"; import { TimelineInfo } from "../data/timeline"; - import { getHttpTimelineClient } from "../http/timeline"; import TimelineBoard from "./TimelineBoard"; diff --git a/Timeline/ClientApp/src/app/home/Home.tsx b/Timeline/ClientApp/src/app/home/Home.tsx index 00e6ff5a..910c9a01 100644 --- a/Timeline/ClientApp/src/app/home/Home.tsx +++ b/Timeline/ClientApp/src/app/home/Home.tsx @@ -4,9 +4,9 @@ import { Row, Container, Button, Col } from "reactstrap"; import { useTranslation } from "react-i18next"; import { useUser } from "../data/user"; - import AppBar from "../common/AppBar"; import SearchInput from "../common/SearchInput"; + import BoardWithoutUser from "./BoardWithoutUser"; import BoardWithUser from "./BoardWithUser"; import TimelineCreateDialog from "./TimelineCreateDialog"; diff --git a/Timeline/ClientApp/src/app/home/OfflineBoard.tsx b/Timeline/ClientApp/src/app/home/OfflineBoard.tsx index 458166ac..fbd37efd 100644 --- a/Timeline/ClientApp/src/app/home/OfflineBoard.tsx +++ b/Timeline/ClientApp/src/app/home/OfflineBoard.tsx @@ -3,7 +3,6 @@ import { Link } from "react-router-dom"; import { Trans } from "react-i18next"; import { getAllCachedTimelineNames } from "../data/timeline"; - import UserTimelineLogo from "../common/UserTimelineLogo"; import TimelineLogo from "../common/TimelineLogo"; diff --git a/Timeline/ClientApp/src/app/home/TimelineBoard.tsx b/Timeline/ClientApp/src/app/home/TimelineBoard.tsx index 91bf2b77..21dcac3f 100644 --- a/Timeline/ClientApp/src/app/home/TimelineBoard.tsx +++ b/Timeline/ClientApp/src/app/home/TimelineBoard.tsx @@ -5,7 +5,6 @@ import { Spinner } from "reactstrap"; import { Trans } from "react-i18next"; import { TimelineInfo } from "../data/timeline"; - import TimelineLogo from "../common/TimelineLogo"; import UserTimelineLogo from "../common/UserTimelineLogo"; diff --git a/Timeline/ClientApp/src/app/home/TimelineCreateDialog.tsx b/Timeline/ClientApp/src/app/home/TimelineCreateDialog.tsx index c5ba64e7..911dd60c 100644 --- a/Timeline/ClientApp/src/app/home/TimelineCreateDialog.tsx +++ b/Timeline/ClientApp/src/app/home/TimelineCreateDialog.tsx @@ -2,7 +2,6 @@ import React from "react"; import { useHistory } from "react-router"; import { validateTimelineName, timelineService } from "../data/timeline"; - import OperationDialog from "../common/OperationDialog"; interface TimelineCreateDialogProps { diff --git a/Timeline/ClientApp/src/app/http/mock/user.ts b/Timeline/ClientApp/src/app/http/mock/user.ts index 1ecd7365..7948da11 100644 --- a/Timeline/ClientApp/src/app/http/mock/user.ts +++ b/Timeline/ClientApp/src/app/http/mock/user.ts @@ -10,7 +10,6 @@ import { } from "../user"; import { mockStorage, sha1, mockPrepare } from "./common"; - import defaultAvatarUrl from "./default-avatar.png"; let _defaultAvatar: BlobWithEtag | undefined = undefined; diff --git a/Timeline/ClientApp/src/app/http/timeline.ts b/Timeline/ClientApp/src/app/http/timeline.ts index 4a325bca..a9511c64 100644 --- a/Timeline/ClientApp/src/app/http/timeline.ts +++ b/Timeline/ClientApp/src/app/http/timeline.ts @@ -1,6 +1,7 @@ import axios, { AxiosError } from "axios"; import { updateQueryString, applyQueryParameters } from "../utilities/url"; + import { apiBaseUrl, extractResponseData, diff --git a/Timeline/ClientApp/src/app/settings/Settings.tsx b/Timeline/ClientApp/src/app/settings/Settings.tsx index dd648538..64851ce2 100644 --- a/Timeline/ClientApp/src/app/settings/Settings.tsx +++ b/Timeline/ClientApp/src/app/settings/Settings.tsx @@ -14,7 +14,6 @@ import { } from "reactstrap"; import { useUser, userService } from "../data/user"; - import AppBar from "../common/AppBar"; import OperationDialog, { OperationInputErrorInfo, diff --git a/Timeline/ClientApp/src/app/timeline/TimelineInfoCard.tsx b/Timeline/ClientApp/src/app/timeline/TimelineInfoCard.tsx index 3591b6f9..c11c3376 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelineInfoCard.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelineInfoCard.tsx @@ -12,9 +12,9 @@ import { fromEvent } from "rxjs"; import { useAvatar } from "../data/user"; import { timelineVisibilityTooltipTranslationMap } from "../data/timeline"; +import BlobImage from "../common/BlobImage"; import { TimelineCardComponentProps } from "./TimelinePageTemplateUI"; -import BlobImage from "../common/BlobImage"; export type OrdinaryTimelineManageItem = "delete"; diff --git a/Timeline/ClientApp/src/app/timeline/TimelineItem.tsx b/Timeline/ClientApp/src/app/timeline/TimelineItem.tsx index 0d62b0e7..33f0741e 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelineItem.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelineItem.tsx @@ -12,12 +12,10 @@ import { import { Link } from "react-router-dom"; import { useTranslation } from "react-i18next"; import Svg from "react-inlinesvg"; - import chevronDownIcon from "bootstrap-icons/icons/chevron-down.svg"; import trashIcon from "bootstrap-icons/icons/trash.svg"; import BlobImage from "../common/BlobImage"; - import { useAvatar } from "../data/user"; import { TimelinePostInfo } from "../data/timeline"; diff --git a/Timeline/ClientApp/src/app/timeline/TimelineMember.tsx b/Timeline/ClientApp/src/app/timeline/TimelineMember.tsx index 559750d2..f334c6e9 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelineMember.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelineMember.tsx @@ -11,7 +11,6 @@ import { } from "reactstrap"; import { User, useAvatar } from "../data/user"; - import SearchInput from "../common/SearchInput"; import BlobImage from "../common/BlobImage"; diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePage.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePage.tsx index 0771b40e..21d52db1 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelinePage.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelinePage.tsx @@ -1,8 +1,9 @@ import React from "react"; import { useParams } from "react-router"; -import TimelinePageUI from "./TimelinePageUI"; import TimelinePageTemplate from "../timeline/TimelinePageTemplate"; + +import TimelinePageUI from "./TimelinePageUI"; import { OrdinaryTimelineManageItem } from "./TimelineInfoCard"; import TimelineDeleteDialog from "./TimelineDeleteDialog"; diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePageTemplate.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePageTemplate.tsx index be96a09e..3f470826 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelinePageTemplate.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelinePageTemplate.tsx @@ -11,13 +11,13 @@ import { usePostList, useTimelineInfo, } from "../data/timeline"; +import { UiLogicError } from "../common"; import { TimelineDeleteCallback } from "./Timeline"; import { TimelineMemberDialog } from "./TimelineMember"; import TimelinePropertyChangeDialog from "./TimelinePropertyChangeDialog"; import { TimelinePageTemplateUIProps } from "./TimelinePageTemplateUI"; import { TimelinePostSendCallback } from "./TimelinePostEdit"; -import { UiLogicError } from "../common"; export interface TimelinePageTemplateProps { name: string; diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx index 2066ceb1..e6514478 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx @@ -4,7 +4,6 @@ import { useTranslation } from "react-i18next"; import { fromEvent } from "rxjs"; import Svg from "react-inlinesvg"; import clsx from "clsx"; - import arrowsAngleContractIcon from "bootstrap-icons/icons/arrows-angle-contract.svg"; import arrowsAngleExpandIcon from "bootstrap-icons/icons/arrows-angle-expand.svg"; @@ -16,12 +15,12 @@ import { timelineService, } from "../data/timeline"; import { userService } from "../data/user"; +import AppBar from "../common/AppBar"; import Timeline, { TimelinePostInfoEx, TimelineDeleteCallback, } from "./Timeline"; -import AppBar from "../common/AppBar"; import TimelinePostEdit, { TimelinePostSendCallback } from "./TimelinePostEdit"; type TimelinePostSyncState = "syncing" | "synced" | "offline"; diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx index 151df40a..b30dc8d3 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelinePostEdit.tsx @@ -2,13 +2,11 @@ import React from "react"; import { Button, Spinner, Row, Col } from "reactstrap"; import { useTranslation } from "react-i18next"; import Svg from "react-inlinesvg"; - import textIcon from "bootstrap-icons/icons/card-text.svg"; import imageIcon from "bootstrap-icons/icons/image.svg"; import { pushAlert } from "../common/alert-service"; import { TimelineCreatePostRequest } from "../data/timeline"; - import FileInput from "../common/FileInput"; import { UiLogicError } from "../common"; diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePropertyChangeDialog.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePropertyChangeDialog.tsx index a0eea775..bb0e3ea2 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelinePropertyChangeDialog.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelinePropertyChangeDialog.tsx @@ -5,7 +5,6 @@ import { kTimelineVisibilities, TimelineChangePropertyRequest, } from "../data/timeline"; - import OperationDialog, { OperationSelectInputInfoOption, } from "../common/OperationDialog"; diff --git a/Timeline/ClientApp/src/app/user/Login.tsx b/Timeline/ClientApp/src/app/user/Login.tsx index 4f9cd05d..db6c43c4 100644 --- a/Timeline/ClientApp/src/app/user/Login.tsx +++ b/Timeline/ClientApp/src/app/user/Login.tsx @@ -1,10 +1,6 @@ import React, { Fragment, useState, useEffect } from "react"; import { useHistory } from "react-router"; import { useTranslation } from "react-i18next"; - -import AppBar from "../common/AppBar"; - -import { useUser, userService } from "../data/user"; import { Label, FormGroup, @@ -15,6 +11,9 @@ import { Button, } from "reactstrap"; +import AppBar from "../common/AppBar"; +import { useUser, userService } from "../data/user"; + const Login: React.FC = (_) => { const { t } = useTranslation(); const history = useHistory(); diff --git a/Timeline/ClientApp/src/app/user/User.tsx b/Timeline/ClientApp/src/app/user/User.tsx index 6f61cacf..56058ce7 100644 --- a/Timeline/ClientApp/src/app/user/User.tsx +++ b/Timeline/ClientApp/src/app/user/User.tsx @@ -3,12 +3,12 @@ import { useParams } from "react-router"; import { UiLogicError } from "../common"; import { useUser, userInfoService } from "../data/user"; -import { changeNickname } from "./api"; +import TimelinePageTemplate from "../timeline/TimelinePageTemplate"; +import { changeNickname } from "./api"; import UserPage from "./UserPage"; import ChangeNicknameDialog from "./ChangeNicknameDialog"; import ChangeAvatarDialog from "./ChangeAvatarDialog"; -import TimelinePageTemplate from "../timeline/TimelinePageTemplate"; import { PersonalTimelineManageItem } from "./UserInfoCard"; const User: React.FC = (_) => { diff --git a/Timeline/ClientApp/src/app/user/UserInfoCard.tsx b/Timeline/ClientApp/src/app/user/UserInfoCard.tsx index 9ce46e3c..d6e648cc 100644 --- a/Timeline/ClientApp/src/app/user/UserInfoCard.tsx +++ b/Timeline/ClientApp/src/app/user/UserInfoCard.tsx @@ -12,7 +12,6 @@ import { fromEvent } from "rxjs"; import { timelineVisibilityTooltipTranslationMap } from "../data/timeline"; import { useAvatar } from "../data/user"; - import { TimelineCardComponentProps } from "../timeline/TimelinePageTemplateUI"; import BlobImage from "../common/BlobImage"; diff --git a/Timeline/ClientApp/src/app/user/UserPage.tsx b/Timeline/ClientApp/src/app/user/UserPage.tsx index 42f174d9..ab498f30 100644 --- a/Timeline/ClientApp/src/app/user/UserPage.tsx +++ b/Timeline/ClientApp/src/app/user/UserPage.tsx @@ -1,10 +1,10 @@ import React from "react"; import { ExcludeKey } from "../utilities/type"; - import TimelinePageTemplateUI, { TimelinePageTemplateUIProps, } from "../timeline/TimelinePageTemplateUI"; + import UserInfoCard, { PersonalTimelineManageItem } from "./UserInfoCard"; export type UserPageProps = ExcludeKey< diff --git a/Timeline/ClientApp/yarn.lock b/Timeline/ClientApp/yarn.lock index c5ddde3b..8562343a 100644 --- a/Timeline/ClientApp/yarn.lock +++ b/Timeline/ClientApp/yarn.lock @@ -1835,6 +1835,13 @@ __metadata: languageName: node linkType: hard +"@types/json5@npm:^0.0.29": + version: 0.0.29 + resolution: "@types/json5@npm:0.0.29::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fjson5%2Fdownload%2F%40types%2Fjson5-0.0.29.tgz" + checksum: 66e9ac0143ec521522c7bb670301e9836ee886207eeed1aab6d4854a1b19b404ab3a54cd8d449f9b1f13acc357f540be96f8ac2d1e86e301eab52ae0f9a4066f + languageName: node + linkType: hard + "@types/keyv@npm:*": version: 3.1.1 resolution: "@types/keyv@npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fkeyv%2Fdownload%2F%40types%2Fkeyv-3.1.1.tgz" @@ -2679,6 +2686,13 @@ __metadata: languageName: node linkType: hard +"array-find@npm:^1.0.0": + version: 1.0.0 + resolution: "array-find@npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-find%2Fdownload%2Farray-find-1.0.0.tgz" + checksum: 1f6f5270a3e4a02324815e732a66ef962becaf69d064e45d8377c023a29cec5abd7236e2fe00036fdf622c0ce178649d78fd83452464644f78c346d6336c1d6c + languageName: node + linkType: hard + "array-flatten@npm:1.1.1": version: 1.1.1 resolution: "array-flatten@npm:1.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-flatten%2Fdownload%2Farray-flatten-1.1.1.tgz" @@ -2734,6 +2748,16 @@ __metadata: languageName: node linkType: hard +"array.prototype.flat@npm:^1.2.3": + version: 1.2.3 + resolution: "array.prototype.flat@npm:1.2.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray.prototype.flat%2Fdownload%2Farray.prototype.flat-1.2.3.tgz" + dependencies: + define-properties: ^1.1.3 + es-abstract: ^1.17.0-next.1 + checksum: f88a474d1cb3bfb2cfa44a5d36047bad146324f1beabbc743689d34fa36f29fab277008446ab56601c48721e1d50c5f47e5b3fae2583cc3724d1e6073cbdd901 + languageName: node + linkType: hard + "array.prototype.flatmap@npm:^1.2.3": version: 1.2.3 resolution: "array.prototype.flatmap@npm:1.2.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Farray.prototype.flatmap%2Fdownload%2Farray.prototype.flatmap-1.2.3.tgz" @@ -3949,6 +3973,13 @@ __metadata: languageName: node linkType: hard +"contains-path@npm:^0.1.0": + version: 0.1.0 + resolution: "contains-path@npm:0.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcontains-path%2Fdownload%2Fcontains-path-0.1.0.tgz" + checksum: 59920a59a0c7d1244235d76b8cfd2b2e7a8dcc463fa578ef9d4d5a5a73eeb14d75dada6b21188e0b35f2474ae9efd10c3698372e674db9c6a904b281998b97d6 + languageName: node + linkType: hard + "content-disposition@npm:0.5.3": version: 0.5.3 resolution: "content-disposition@npm:0.5.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fcontent-disposition%2Fdownload%2Fcontent-disposition-0.5.3.tgz" @@ -4332,7 +4363,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:2.6.9, debug@npm:^2.2.0, debug@npm:^2.3.3, debug@npm:^2.6.8": +"debug@npm:2.6.9, debug@npm:^2.2.0, debug@npm:^2.3.3, debug@npm:^2.6.8, debug@npm:^2.6.9": version: 2.6.9 resolution: "debug@npm:2.6.9::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-2.6.9.tgz" dependencies: @@ -4598,6 +4629,16 @@ __metadata: languageName: node linkType: hard +"doctrine@npm:1.5.0": + version: 1.5.0 + resolution: "doctrine@npm:1.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdoctrine%2Fdownload%2Fdoctrine-1.5.0.tgz" + dependencies: + esutils: ^2.0.2 + isarray: ^1.0.0 + checksum: aaffea02f963b8b07a78b1e27d7cef29be65d31be2c6681cb2872c2fb3781e14615bd05d4dff6036f75dcf3f191216058409fbfec805d3a7277a8647cd5bdee1 + languageName: node + linkType: hard + "doctrine@npm:^2.1.0": version: 2.1.0 resolution: "doctrine@npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fdoctrine%2Fdownload%2Fdoctrine-2.1.0.tgz" @@ -4829,6 +4870,17 @@ __metadata: languageName: node linkType: hard +"enhanced-resolve@npm:^0.9.1": + version: 0.9.1 + resolution: "enhanced-resolve@npm:0.9.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-0.9.1.tgz" + dependencies: + graceful-fs: ^4.1.2 + memory-fs: ^0.2.0 + tapable: ^0.1.8 + checksum: c814cd928250e8c0133132e9557ca96f125dcfe974ec8a9818c08deb0d1f280b5ad0f5a3cb74b63be1af029f1d1584f51fa11ce355e944d42d7c543b7795f8fb + languageName: node + linkType: hard + "enhanced-resolve@npm:^4.0.0, enhanced-resolve@npm:^4.1.1, enhanced-resolve@npm:^4.3.0": version: 4.3.0 resolution: "enhanced-resolve@npm:4.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fenhanced-resolve%2Fdownload%2Fenhanced-resolve-4.3.0.tgz" @@ -4881,7 +4933,7 @@ __metadata: languageName: node linkType: hard -"error-ex@npm:^1.3.1": +"error-ex@npm:^1.2.0, error-ex@npm:^1.3.1": version: 1.3.2 resolution: "error-ex@npm:1.3.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ferror-ex%2Fdownload%2Ferror-ex-1.3.2.tgz" dependencies: @@ -4954,6 +5006,70 @@ __metadata: languageName: node linkType: hard +"eslint-import-resolver-node@npm:^0.3.3": + version: 0.3.4 + resolution: "eslint-import-resolver-node@npm:0.3.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-node%2Fdownload%2Feslint-import-resolver-node-0.3.4.tgz" + dependencies: + debug: ^2.6.9 + resolve: ^1.13.1 + checksum: 825e34e662c988ece8229e6956a95f12d2fa19265b429e3e3db14e58bfe72e270c999cda0cfc690793ed6e6a3e49ffa8df0e0a8842d668a1f0f7de5ae1aa36f9 + languageName: node + linkType: hard + +"eslint-import-resolver-webpack@npm:^0.12.2": + version: 0.12.2 + resolution: "eslint-import-resolver-webpack@npm:0.12.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-import-resolver-webpack%2Fdownload%2Feslint-import-resolver-webpack-0.12.2.tgz" + dependencies: + array-find: ^1.0.0 + debug: ^2.6.9 + enhanced-resolve: ^0.9.1 + find-root: ^1.1.0 + has: ^1.0.3 + interpret: ^1.2.0 + lodash: ^4.17.15 + node-libs-browser: ^1.0.0 || ^2.0.0 + resolve: ^1.13.1 + semver: ^5.7.1 + peerDependencies: + eslint-plugin-import: ">=1.4.0" + webpack: ">=1.11.0" + checksum: 5310d4383e443387b45e2ea2371b9e0725812b7cb996fa5be9f0e9c4e0716fa9fa1aebadd85def4067fced274e68479d23a4e4397e4277e5acb64793da6d30b6 + languageName: node + linkType: hard + +"eslint-module-utils@npm:^2.6.0": + version: 2.6.0 + resolution: "eslint-module-utils@npm:2.6.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-module-utils%2Fdownload%2Feslint-module-utils-2.6.0.tgz" + dependencies: + debug: ^2.6.9 + pkg-dir: ^2.0.0 + checksum: f584af176480a702eedcdb3f610797f8b8d1293c3835ed71fadb579ec28400b91ded5283729418f63d48dc27c6358bd66f2bd839614d565a1b78d3c3440ee8f7 + languageName: node + linkType: hard + +"eslint-plugin-import@npm:^2.22.0": + version: 2.22.0 + resolution: "eslint-plugin-import@npm:2.22.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-import%2Fdownload%2Feslint-plugin-import-2.22.0.tgz" + dependencies: + array-includes: ^3.1.1 + array.prototype.flat: ^1.2.3 + contains-path: ^0.1.0 + debug: ^2.6.9 + doctrine: 1.5.0 + eslint-import-resolver-node: ^0.3.3 + eslint-module-utils: ^2.6.0 + has: ^1.0.3 + minimatch: ^3.0.4 + object.values: ^1.1.1 + read-pkg-up: ^2.0.0 + resolve: ^1.17.0 + tsconfig-paths: ^3.9.0 + peerDependencies: + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 + checksum: ad41aec63d8986e0a0e279bb2877e1f36029573b8f310112159509fd52d7344a2e91bd4bb9c6d2b131838a3538a0bc5e3998217df1b88304df9872ad9fb30c84 + languageName: node + linkType: hard + "eslint-plugin-prettier@npm:^3.1.4": version: 3.1.4 resolution: "eslint-plugin-prettier@npm:3.1.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-prettier%2Fdownload%2Feslint-plugin-prettier-3.1.4.tgz" @@ -5488,6 +5604,22 @@ __metadata: languageName: node linkType: hard +"find-root@npm:^1.1.0": + version: 1.1.0 + resolution: "find-root@npm:1.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-root%2Fdownload%2Ffind-root-1.1.0.tgz" + checksum: 34f9eeb7258b3b5e270824a11bae4a8e6075efe79a319c034a3c5cae90cdb558c524c42ff7938b1200f648349c9dc04e860c8eaef852c802f5a1c26fa04d5ab1 + languageName: node + linkType: hard + +"find-up@npm:^2.0.0, find-up@npm:^2.1.0": + version: 2.1.0 + resolution: "find-up@npm:2.1.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-2.1.0.tgz" + dependencies: + locate-path: ^2.0.0 + checksum: 9dedb89f936b572f7c9fda3f66ebe146b0000fe9ef16fad94a77c25ce9585962e910bb32c1e08bab9b423985ff20221d2af4b7e4130b27c0f5f60c1aad3f6a7f + languageName: node + linkType: hard + "find-up@npm:^3.0.0": version: 3.0.0 resolution: "find-up@npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ffind-up%2Fdownload%2Ffind-up-3.0.0.tgz" @@ -6188,6 +6320,13 @@ fsevents@~2.1.2: languageName: node linkType: hard +"hosted-git-info@npm:^2.1.4": + version: 2.8.8 + resolution: "hosted-git-info@npm:2.8.8::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhosted-git-info%2Fdownload%2Fhosted-git-info-2.8.8.tgz" + checksum: 3ecc389dc6ecbd5463fada7e04461e96f3c817fe2f989ca41e9dd3b503745a0bfa26fba405861b2831ca64edc1abc5d2fbc97ee977303f89650dac4fbfdc2d7a + languageName: node + linkType: hard + "hpack.js@npm:^2.1.6": version: 2.1.6 resolution: "hpack.js@npm:2.1.6::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fhpack.js%2Fdownload%2Fhpack.js-2.1.6.tgz" @@ -6605,7 +6744,7 @@ fsevents@~2.1.2: languageName: node linkType: hard -"interpret@npm:^1.4.0": +"interpret@npm:^1.2.0, interpret@npm:^1.4.0": version: 1.4.0 resolution: "interpret@npm:1.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Finterpret%2Fdownload%2Finterpret-1.4.0.tgz" checksum: f15725d76206525546f559030ddc967db025c6db904eb8798a70ec3c07e42c5537c5cbc73a15eafd4ae5cdabad35601abf8878261c03dcc8217747e8037575fe @@ -7282,6 +7421,18 @@ fsevents@~2.1.2: languageName: node linkType: hard +"load-json-file@npm:^2.0.0": + version: 2.0.0 + resolution: "load-json-file@npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fload-json-file%2Fdownload%2Fload-json-file-2.0.0.tgz" + dependencies: + graceful-fs: ^4.1.2 + parse-json: ^2.2.0 + pify: ^2.0.0 + strip-bom: ^3.0.0 + checksum: c6ea93d36099dd6e778c6c018c9e184ad65d278a9538c2280f959b040b1a9a756d8856bdaf8a38c8f1454eca19bf4798ea59f79ccd8bb1c33aa8b7ecbe157f0c + languageName: node + linkType: hard + "loader-runner@npm:^2.4.0": version: 2.4.0 resolution: "loader-runner@npm:2.4.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Floader-runner%2Fdownload%2Floader-runner-2.4.0.tgz" @@ -7320,6 +7471,16 @@ fsevents@~2.1.2: languageName: node linkType: hard +"locate-path@npm:^2.0.0": + version: 2.0.0 + resolution: "locate-path@npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocate-path%2Fdownload%2Flocate-path-2.0.0.tgz" + dependencies: + p-locate: ^2.0.0 + path-exists: ^3.0.0 + checksum: ee5a888d686f8d555ebfa6c4f6f3b7c5cdfa5f382dee17e0b3fde7456fc68301ddb6a79790a412659d1e067f2f58fd74c683b203fc20368deaed45fb985b4fda + languageName: node + linkType: hard + "locate-path@npm:^3.0.0": version: 3.0.0 resolution: "locate-path@npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Flocate-path%2Fdownload%2Flocate-path-3.0.0.tgz" @@ -7511,6 +7672,13 @@ fsevents@~2.1.2: languageName: node linkType: hard +"memory-fs@npm:^0.2.0": + version: 0.2.0 + resolution: "memory-fs@npm:0.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.2.0.tgz" + checksum: 373cf2a451883983f904df0074fce05951f92a45f927be32312d192208657d3e0f69688017c1f9571abbc0c554301bc4f925825cb1cd15f558d3a22e02c789d0 + languageName: node + linkType: hard + "memory-fs@npm:^0.4.1": version: 0.4.1 resolution: "memory-fs@npm:0.4.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fmemory-fs%2Fdownload%2Fmemory-fs-0.4.1.tgz" @@ -7976,7 +8144,7 @@ fsevents@~2.1.2: languageName: node linkType: hard -"node-libs-browser@npm:^2.2.1": +"node-libs-browser@npm:^1.0.0 || ^2.0.0, node-libs-browser@npm:^2.2.1": version: 2.2.1 resolution: "node-libs-browser@npm:2.2.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-libs-browser%2Fdownload%2Fnode-libs-browser-2.2.1.tgz" dependencies: @@ -8043,6 +8211,18 @@ fsevents@~2.1.2: languageName: node linkType: hard +"normalize-package-data@npm:^2.3.2": + version: 2.5.0 + resolution: "normalize-package-data@npm:2.5.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnormalize-package-data%2Fdownload%2Fnormalize-package-data-2.5.0.tgz" + dependencies: + hosted-git-info: ^2.1.4 + resolve: ^1.10.0 + semver: 2 || 3 || 4 || 5 + validate-npm-package-license: ^3.0.1 + checksum: 97d4d6b061cab51425ddb05c38d126d7a1a2a6f2c9949bef2b5ad7ef19c005df12099ea442e4cb09190929b7770008f94f87b10342a66f739acf92a7ebb9d9f2 + languageName: node + linkType: hard + "normalize-path@npm:^2.1.1": version: 2.1.1 resolution: "normalize-path@npm:2.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fnormalize-path%2Fdownload%2Fnormalize-path-2.1.1.tgz" @@ -8380,6 +8560,15 @@ fsevents@~2.1.2: languageName: node linkType: hard +"p-limit@npm:^1.1.0": + version: 1.3.0 + resolution: "p-limit@npm:1.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-limit%2Fdownload%2Fp-limit-1.3.0.tgz" + dependencies: + p-try: ^1.0.0 + checksum: 579cbd3d6c606058aa624c464e2cb3c4b56d04ed4cbafdb705633cbe62ba36d77ba2c4289023335ba382f4fbf32c15709465eea18a0e1547c5ebc4b887f2a7da + languageName: node + linkType: hard + "p-limit@npm:^2.0.0, p-limit@npm:^2.2.0": version: 2.3.0 resolution: "p-limit@npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-limit%2Fdownload%2Fp-limit-2.3.0.tgz" @@ -8398,6 +8587,15 @@ fsevents@~2.1.2: languageName: node linkType: hard +"p-locate@npm:^2.0.0": + version: 2.0.0 + resolution: "p-locate@npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-2.0.0.tgz" + dependencies: + p-limit: ^1.1.0 + checksum: b6dabbd855fba9bfa74b77882f96d0eac6c25d9966e61ab0ed7bf3d19f2e3b766f290ded1aada1ac4ce2627217b00342cf7a1d36482bada59ba6789be412dad7 + languageName: node + linkType: hard + "p-locate@npm:^3.0.0": version: 3.0.0 resolution: "p-locate@npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-locate%2Fdownload%2Fp-locate-3.0.0.tgz" @@ -8441,6 +8639,13 @@ fsevents@~2.1.2: languageName: node linkType: hard +"p-try@npm:^1.0.0": + version: 1.0.0 + resolution: "p-try@npm:1.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-try%2Fdownload%2Fp-try-1.0.0.tgz" + checksum: 85739d77b3e9f6a52a8545f1adc53621fb5df4d6ef9b59a3f54f3f3159b45c4100d4e63128a1e790e9ff8ff8b86213ace314ff6d2d327c3edcceea18891baa42 + languageName: node + linkType: hard + "p-try@npm:^2.0.0": version: 2.2.0 resolution: "p-try@npm:2.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fp-try%2Fdownload%2Fp-try-2.2.0.tgz" @@ -8499,6 +8704,15 @@ fsevents@~2.1.2: languageName: node linkType: hard +"parse-json@npm:^2.2.0": + version: 2.2.0 + resolution: "parse-json@npm:2.2.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-2.2.0.tgz" + dependencies: + error-ex: ^1.2.0 + checksum: 920582196a8edebb3d3c4623b2f057987218272b35ae4d2d310c00bc1bd7e89b87c79358d7e009d54f047ca2eea82eab8d7e1b14e1f7cbbb345ef29fcda29731 + languageName: node + linkType: hard + "parse-json@npm:^4.0.0": version: 4.0.0 resolution: "parse-json@npm:4.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fparse-json%2Fdownload%2Fparse-json-4.0.0.tgz" @@ -8619,6 +8833,15 @@ fsevents@~2.1.2: languageName: node linkType: hard +"path-type@npm:^2.0.0": + version: 2.0.0 + resolution: "path-type@npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-type%2Fdownload%2Fpath-type-2.0.0.tgz" + dependencies: + pify: ^2.0.0 + checksum: d028f828dffe48a0062dc4370d5118a0c45f5fb075b013a1dfb13eadd1426eba0c8c2a13fa78f19fc4fd8771ef2012e9d062f8f970c8e56df36d4fbbe5073b26 + languageName: node + linkType: hard + "path-type@npm:^4.0.0": version: 4.0.0 resolution: "path-type@npm:4.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpath-type%2Fdownload%2Fpath-type-4.0.0.tgz" @@ -8690,6 +8913,15 @@ fsevents@~2.1.2: languageName: node linkType: hard +"pkg-dir@npm:^2.0.0": + version: 2.0.0 + resolution: "pkg-dir@npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-2.0.0.tgz" + dependencies: + find-up: ^2.1.0 + checksum: f8ae3a151714c61283aeb24385b10355a238732fab822a560145c670c21350da2024f01918231222bcdfce53ec5d69056681be2c2cffe3f3a06e462b9ef2ac29 + languageName: node + linkType: hard + "pkg-dir@npm:^3.0.0": version: 3.0.0 resolution: "pkg-dir@npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fpkg-dir%2Fdownload%2Fpkg-dir-3.0.0.tgz" @@ -9688,6 +9920,27 @@ fsevents@~2.1.2: languageName: node linkType: hard +"read-pkg-up@npm:^2.0.0": + version: 2.0.0 + resolution: "read-pkg-up@npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg-up%2Fdownload%2Fread-pkg-up-2.0.0.tgz" + dependencies: + find-up: ^2.0.0 + read-pkg: ^2.0.0 + checksum: f35e4cb4577b994fc9497886672c748de766ab034e24f029111b6bbbfe757b2e27b6d2b82a28a38f45d9d89ea8a9b1d3c04854e5f991d5deed48f4c9ff7baeb9 + languageName: node + linkType: hard + +"read-pkg@npm:^2.0.0": + version: 2.0.0 + resolution: "read-pkg@npm:2.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fread-pkg%2Fdownload%2Fread-pkg-2.0.0.tgz" + dependencies: + load-json-file: ^2.0.0 + normalize-package-data: ^2.3.2 + path-type: ^2.0.0 + checksum: ddf911317fba54abb447b1d76dd1785c37e1360f7b1e39d83201f6f3807572391ab7392f11727a9c4d90600ebc6616d22e72514d2291688c89ebd440148840b4 + languageName: node + linkType: hard + "readable-stream@npm:1 || 2, readable-stream@npm:^2.0.0, readable-stream@npm:^2.0.1, readable-stream@npm:^2.0.2, readable-stream@npm:^2.0.6, readable-stream@npm:^2.1.5, readable-stream@npm:^2.2.2, readable-stream@npm:^2.3.3, readable-stream@npm:^2.3.6, readable-stream@npm:~2.3.6": version: 2.3.7 resolution: "readable-stream@npm:2.3.7::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Freadable-stream%2Fdownload%2Freadable-stream-2.3.7.tgz" @@ -9983,7 +10236,7 @@ fsevents@~2.1.2: languageName: node linkType: hard -"resolve@^1.14.2, resolve@^1.17.0, resolve@^1.3.2": +"resolve@^1.10.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.3.2": version: 1.17.0 resolution: "resolve@npm:1.17.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fresolve%2Fdownload%2Fresolve-1.17.0.tgz" dependencies: @@ -9992,7 +10245,7 @@ fsevents@~2.1.2: languageName: node linkType: hard -"resolve@patch:resolve@^1.14.2#builtin, resolve@patch:resolve@^1.17.0#builtin, resolve@patch:resolve@^1.3.2#builtin": +"resolve@patch:resolve@^1.10.0#builtin, resolve@patch:resolve@^1.13.1#builtin, resolve@patch:resolve@^1.14.2#builtin, resolve@patch:resolve@^1.17.0#builtin, resolve@patch:resolve@^1.3.2#builtin": version: 1.17.0 resolution: "resolve@patch:resolve@npm%3A1.17.0%3A%3A__archiveUrl=https%253A%252F%252Fregistry.npm.taobao.org%252Fresolve%252Fdownload%252Fresolve-1.17.0.tgz#builtin::version=1.17.0&hash=3388aa" dependencies: @@ -10270,6 +10523,15 @@ fsevents@~2.1.2: languageName: node linkType: hard +"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.4.1, semver@npm:^5.5.0, semver@npm:^5.6.0, semver@npm:^5.7.1": + version: 5.7.1 + resolution: "semver@npm:5.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz" + bin: + semver: ./bin/semver + checksum: 06ff0ed753ebf741b7602be8faad620d6e160a2cb3f61019d00d919c8bca141638aa23c34da779b8595afdc9faa3678bfbb5f60366b6a4f65f98cf86605bbcdb + languageName: node + linkType: hard + "semver@npm:7.0.0": version: 7.0.0 resolution: "semver@npm:7.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-7.0.0.tgz" @@ -10279,15 +10541,6 @@ fsevents@~2.1.2: languageName: node linkType: hard -"semver@npm:^5.4.1, semver@npm:^5.5.0, semver@npm:^5.6.0": - version: 5.7.1 - resolution: "semver@npm:5.7.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz" - bin: - semver: ./bin/semver - checksum: 06ff0ed753ebf741b7602be8faad620d6e160a2cb3f61019d00d919c8bca141638aa23c34da779b8595afdc9faa3678bfbb5f60366b6a4f65f98cf86605bbcdb - languageName: node - linkType: hard - "semver@npm:^6.0.0, semver@npm:^6.3.0": version: 6.3.0 resolution: "semver@npm:6.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-6.3.0.tgz" @@ -10647,6 +10900,40 @@ fsevents@~2.1.2: languageName: node linkType: hard +"spdx-correct@npm:^3.0.0": + version: 3.1.1 + resolution: "spdx-correct@npm:3.1.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-correct%2Fdownload%2Fspdx-correct-3.1.1.tgz" + dependencies: + spdx-expression-parse: ^3.0.0 + spdx-license-ids: ^3.0.0 + checksum: f3413eb225ef9f13aa2ec05230ff7669bffad055a7f62ec85164dd27f00a9f1e19880554a8fa5350fc434764ff895836c207f98813511a0180b0e929581bfe01 + languageName: node + linkType: hard + +"spdx-exceptions@npm:^2.1.0": + version: 2.3.0 + resolution: "spdx-exceptions@npm:2.3.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-exceptions%2Fdownload%2Fspdx-exceptions-2.3.0.tgz" + checksum: 3cbd2498897dc384158666a9dd7435e3b42ece5da42fd967b218b790e248381d001ec77a676d13d1f4e8da317d97b7bc0ebf4fff37bfbb95923d49b024030c96 + languageName: node + linkType: hard + +"spdx-expression-parse@npm:^3.0.0": + version: 3.0.1 + resolution: "spdx-expression-parse@npm:3.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-expression-parse%2Fdownload%2Fspdx-expression-parse-3.0.1.tgz" + dependencies: + spdx-exceptions: ^2.1.0 + spdx-license-ids: ^3.0.0 + checksum: f0211cada3fa7cd9db2243143fb0e66e28a46d72d8268f38ad2196aac49408d87892cda6e5600d43d6b05ed2707cb2f4148deb27b092aafabc50a67038f4cbf5 + languageName: node + linkType: hard + +"spdx-license-ids@npm:^3.0.0": + version: 3.0.5 + resolution: "spdx-license-ids@npm:3.0.5::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdx-license-ids%2Fdownload%2Fspdx-license-ids-3.0.5.tgz" + checksum: 4ff7c0615a3c69a195b206a425e6a633ccb24e680ac21f5464b249b57ebb5c3f356f84a8e713599758be69ee4a849319d7fce7041b69e29acd9d31daed3fb8eb + languageName: node + linkType: hard + "spdy-transport@npm:^3.0.0": version: 3.0.0 resolution: "spdy-transport@npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fspdy-transport%2Fdownload%2Fspdy-transport-3.0.0.tgz" @@ -10932,6 +11219,13 @@ fsevents@~2.1.2: languageName: node linkType: hard +"strip-bom@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-bom@npm:3.0.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-bom%2Fdownload%2Fstrip-bom-3.0.0.tgz" + checksum: 361dd1dd08ae626940061570d20bcf73909d0459734b8880eb3d14176aa28f41cf85d13af036c323ce739e04ef3930a71b516950c5985b318bae3757ecb2974c + languageName: node + linkType: hard + "strip-comments@npm:^1.0.2": version: 1.0.2 resolution: "strip-comments@npm:1.0.2::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fstrip-comments%2Fdownload%2Fstrip-comments-1.0.2.tgz" @@ -11014,6 +11308,13 @@ fsevents@~2.1.2: languageName: node linkType: hard +"tapable@npm:^0.1.8": + version: 0.1.10 + resolution: "tapable@npm:0.1.10::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftapable%2Fdownload%2Ftapable-0.1.10.tgz" + checksum: 5604e1127dbfaa9da431121c947be751e0a91fe21f6256da03b61d1c8c5111b6434806ff751758ec07b810ff2c4e538829aad417e55e6b9b4a73544747eca43e + languageName: node + linkType: hard + "tapable@npm:^1.0.0, tapable@npm:^1.1.3": version: 1.1.3 resolution: "tapable@npm:1.1.3::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftapable%2Fdownload%2Ftapable-1.1.3.tgz" @@ -11167,6 +11468,8 @@ fsevents@~2.1.2: css-loader: ^4.2.1 eslint: ^7.7.0 eslint-config-prettier: ^6.11.0 + eslint-import-resolver-webpack: ^0.12.2 + eslint-plugin-import: ^2.22.0 eslint-plugin-prettier: ^3.1.4 eslint-plugin-react: ^7.20.6 eslint-plugin-react-hooks: ^4.1.0 @@ -11341,6 +11644,18 @@ fsevents@~2.1.2: languageName: node linkType: hard +"tsconfig-paths@npm:^3.9.0": + version: 3.9.0 + resolution: "tsconfig-paths@npm:3.9.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftsconfig-paths%2Fdownload%2Ftsconfig-paths-3.9.0.tgz" + dependencies: + "@types/json5": ^0.0.29 + json5: ^1.0.1 + minimist: ^1.2.0 + strip-bom: ^3.0.0 + checksum: 5383ba626b3ac70e08094b9dfd1e30ce82878407b6c8db8cd84279cc7c7340d5f53f67dbeb8174a233c082a068322a6b00ec8514b96d9a80a453e0476dc116d2 + languageName: node + linkType: hard + "tslib@npm:^1.10.0, tslib@npm:^1.13.0, tslib@npm:^1.8.1, tslib@npm:^1.9.0": version: 1.13.0 resolution: "tslib@npm:1.13.0::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.13.0.tgz" @@ -11712,6 +12027,16 @@ typescript@^4.0.2: languageName: node linkType: hard +"validate-npm-package-license@npm:^3.0.1": + version: 3.0.4 + resolution: "validate-npm-package-license@npm:3.0.4::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fvalidate-npm-package-license%2Fdownload%2Fvalidate-npm-package-license-3.0.4.tgz" + dependencies: + spdx-correct: ^3.0.0 + spdx-expression-parse: ^3.0.0 + checksum: 940899bd4eacfa012ceecb10a5814ba0e8103da5243aa74d0d62f1f8a405efcd23e034fb7193e2d05b392870c53aabcb1f66439b062075cdcb28bc5d562a8ff6 + languageName: node + linkType: hard + "value-equal@npm:^1.0.1": version: 1.0.1 resolution: "value-equal@npm:1.0.1::__archiveUrl=https%3A%2F%2Fregistry.npm.taobao.org%2Fvalue-equal%2Fdownload%2Fvalue-equal-1.0.1.tgz" -- cgit v1.2.3