Compare commits
63 Commits
feat/monac
...
feat/md-pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1fab69ef9b | ||
|
|
dbbbfdb2f0 | ||
|
|
052be354d1 | ||
|
|
737523fe8d | ||
|
|
034fc3423b | ||
|
|
b23b0066bb | ||
|
|
380b6b1afd | ||
|
|
c7d77b26b5 | ||
|
|
aa62251780 | ||
|
|
4b2b4b25c0 | ||
|
|
6dd5712573 | ||
|
|
6611a94652 | ||
|
|
2086291d4d | ||
|
|
5505f0ac87 | ||
|
|
2cf92b908d | ||
|
|
70de876f75 | ||
|
|
58cde29fff | ||
|
|
a06fb06610 | ||
|
|
1f5a9731bb | ||
|
|
ef4f95ca3e | ||
|
|
fb9814ec76 | ||
|
|
7f6b989f15 | ||
|
|
d459b2ee92 | ||
|
|
6ee1a09aaa | ||
|
|
dd2228fb35 | ||
|
|
ca52a5e064 | ||
|
|
df0f8abe62 | ||
|
|
a6c4db1951 | ||
|
|
1c91003164 | ||
|
|
66be0efbbd | ||
|
|
9ab64ec062 | ||
|
|
e77a5e234f | ||
|
|
d2f618512a | ||
|
|
f5063de2c9 | ||
|
|
1ee8dcb536 | ||
|
|
7f6f9c11db | ||
|
|
b2b7059774 | ||
|
|
41ba096ef9 | ||
|
|
8b72086c04 | ||
|
|
895b34cc68 | ||
|
|
b9da659f83 | ||
|
|
3897f2d823 | ||
|
|
6a3ff3e1d7 | ||
|
|
bf792f1495 | ||
|
|
df3210a663 | ||
|
|
bad7730c32 | ||
|
|
adb6a78549 | ||
|
|
8cc27f20c3 | ||
|
|
8e49a3f5f1 | ||
|
|
3179757469 | ||
|
|
554cfb3db9 | ||
|
|
637a066f69 | ||
|
|
c9a852e9be | ||
|
|
307a5407eb | ||
|
|
faa28845c8 | ||
|
|
168d11d48e | ||
|
|
60f2bb558c | ||
|
|
fdf33b9f45 | ||
|
|
d05180d148 | ||
|
|
bfaa6be17d | ||
|
|
9e368dec84 | ||
|
|
25eec6980f | ||
|
|
8e2f20c5ac |
@@ -32,6 +32,7 @@ import { SetHookDialog } from "./SetHookDialog";
|
|||||||
import { addFunds } from "../state/actions/addFaucetAccount";
|
import { addFunds } from "../state/actions/addFaucetAccount";
|
||||||
import { deleteHook } from "../state/actions/deployHook";
|
import { deleteHook } from "../state/actions/deployHook";
|
||||||
import { capitalize } from "../utils/helpers";
|
import { capitalize } from "../utils/helpers";
|
||||||
|
import { deleteAccount } from '../state/actions/deleteAccount';
|
||||||
|
|
||||||
export const AccountDialog = ({
|
export const AccountDialog = ({
|
||||||
activeAccountAddress,
|
activeAccountAddress,
|
||||||
@@ -99,10 +100,7 @@ export const AccountDialog = ({
|
|||||||
css={{ ml: "auto", mr: "$9" }}
|
css={{ ml: "auto", mr: "$9" }}
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const index = state.accounts.findIndex(
|
deleteAccount(activeAccount?.address);
|
||||||
acc => acc.address === activeAccount?.address
|
|
||||||
);
|
|
||||||
state.accounts.splice(index, 1);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Delete Account <Trash size="15px" />
|
Delete Account <Trash size="15px" />
|
||||||
|
|||||||
135
components/ContextMenu/index.tsx
Normal file
135
components/ContextMenu/index.tsx
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
import { CaretRight, Check, Circle } from "phosphor-react";
|
||||||
|
import { FC, Fragment, ReactNode } from "react";
|
||||||
|
import { Flex, Text } from "../";
|
||||||
|
import {
|
||||||
|
ContextMenuCheckboxItem,
|
||||||
|
ContextMenuContent,
|
||||||
|
ContextMenuItem,
|
||||||
|
ContextMenuItemIndicator,
|
||||||
|
ContextMenuLabel,
|
||||||
|
ContextMenuRadioGroup,
|
||||||
|
ContextMenuRadioItem,
|
||||||
|
ContextMenuRoot,
|
||||||
|
ContextMenuSeparator,
|
||||||
|
ContextMenuTrigger,
|
||||||
|
ContextMenuTriggerItem,
|
||||||
|
} from "./primitive";
|
||||||
|
|
||||||
|
export type TextOption = {
|
||||||
|
type: "text";
|
||||||
|
label: ReactNode;
|
||||||
|
onSelect?: () => any;
|
||||||
|
children?: ContentMenuOption[];
|
||||||
|
};
|
||||||
|
export type SeparatorOption = { type: "separator" };
|
||||||
|
export type CheckboxOption = {
|
||||||
|
type: "checkbox";
|
||||||
|
label: ReactNode;
|
||||||
|
checked?: boolean;
|
||||||
|
onCheckedChange?: (isChecked: boolean) => any;
|
||||||
|
};
|
||||||
|
export type RadioOption<T extends string = string> = {
|
||||||
|
type: "radio";
|
||||||
|
label: ReactNode;
|
||||||
|
onValueChange?: (value: string) => any;
|
||||||
|
value: T;
|
||||||
|
options?: { value: T; label?: ReactNode }[];
|
||||||
|
};
|
||||||
|
|
||||||
|
type WithCommons = { key: string; disabled?: boolean };
|
||||||
|
|
||||||
|
export type ContentMenuOption = (
|
||||||
|
| TextOption
|
||||||
|
| SeparatorOption
|
||||||
|
| CheckboxOption
|
||||||
|
| RadioOption
|
||||||
|
) &
|
||||||
|
WithCommons;
|
||||||
|
|
||||||
|
export interface IContextMenu {
|
||||||
|
options?: ContentMenuOption[];
|
||||||
|
isNested?: boolean;
|
||||||
|
}
|
||||||
|
export const ContextMenu: FC<IContextMenu> = ({
|
||||||
|
children,
|
||||||
|
options,
|
||||||
|
isNested,
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<ContextMenuRoot>
|
||||||
|
{isNested ? (
|
||||||
|
<ContextMenuTriggerItem>{children}</ContextMenuTriggerItem>
|
||||||
|
) : (
|
||||||
|
<ContextMenuTrigger>{children}</ContextMenuTrigger>
|
||||||
|
)}
|
||||||
|
{options && !!options.length && (
|
||||||
|
<ContextMenuContent sideOffset={isNested ? 2 : 5}>
|
||||||
|
{options.map(({ key, ...option }) => {
|
||||||
|
if (option.type === "text") {
|
||||||
|
const { children, label, onSelect } = option;
|
||||||
|
if (children)
|
||||||
|
return (
|
||||||
|
<ContextMenu isNested key={key} options={children}>
|
||||||
|
<Flex fluid row justify="space-between" align="center">
|
||||||
|
<Text>{label}</Text>
|
||||||
|
<CaretRight />
|
||||||
|
</Flex>
|
||||||
|
</ContextMenu>
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<ContextMenuItem key={key} onSelect={onSelect}>
|
||||||
|
{label}
|
||||||
|
</ContextMenuItem>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (option.type === "checkbox") {
|
||||||
|
const { label, checked, onCheckedChange } = option;
|
||||||
|
return (
|
||||||
|
<ContextMenuCheckboxItem
|
||||||
|
key={key}
|
||||||
|
checked={checked}
|
||||||
|
onCheckedChange={onCheckedChange}
|
||||||
|
>
|
||||||
|
<Flex row align="center">
|
||||||
|
<ContextMenuItemIndicator>
|
||||||
|
<Check />
|
||||||
|
</ContextMenuItemIndicator>
|
||||||
|
<Text css={{ ml: checked ? "$4" : undefined }}>
|
||||||
|
{label}
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
</ContextMenuCheckboxItem>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (option.type === "radio") {
|
||||||
|
const { label, options, onValueChange, value } = option;
|
||||||
|
return (
|
||||||
|
<Fragment key={key}>
|
||||||
|
<ContextMenuLabel>{label}</ContextMenuLabel>
|
||||||
|
<ContextMenuRadioGroup
|
||||||
|
value={value}
|
||||||
|
onValueChange={onValueChange}
|
||||||
|
>
|
||||||
|
{options?.map(({ value: v, label }) => {
|
||||||
|
return (
|
||||||
|
<ContextMenuRadioItem key={v} value={v}>
|
||||||
|
<ContextMenuItemIndicator>
|
||||||
|
<Circle weight="fill" />
|
||||||
|
</ContextMenuItemIndicator>
|
||||||
|
<Text css={{ ml: "$4" }}>{label}</Text>
|
||||||
|
</ContextMenuRadioItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ContextMenuRadioGroup>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return <ContextMenuSeparator key={key} />;
|
||||||
|
})}
|
||||||
|
</ContextMenuContent>
|
||||||
|
)}
|
||||||
|
</ContextMenuRoot>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ContextMenu;
|
||||||
107
components/ContextMenu/primitive.tsx
Normal file
107
components/ContextMenu/primitive.tsx
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
|
||||||
|
import { styled } from "../../stitches.config";
|
||||||
|
import {
|
||||||
|
slideDownAndFade,
|
||||||
|
slideLeftAndFade,
|
||||||
|
slideRightAndFade,
|
||||||
|
slideUpAndFade,
|
||||||
|
} from "../../styles/keyframes";
|
||||||
|
|
||||||
|
const StyledContent = styled(ContextMenuPrimitive.Content, {
|
||||||
|
minWidth: 140,
|
||||||
|
backgroundColor: "$backgroundOverlay",
|
||||||
|
borderRadius: 6,
|
||||||
|
overflow: "hidden",
|
||||||
|
padding: "5px",
|
||||||
|
boxShadow:
|
||||||
|
"0px 10px 38px -10px rgba(22, 23, 24, 0.35), 0px 10px 20px -15px rgba(22, 23, 24, 0.2)",
|
||||||
|
"@media (prefers-reduced-motion: no-preference)": {
|
||||||
|
animationDuration: "400ms",
|
||||||
|
animationTimingFunction: "cubic-bezier(0.16, 1, 0.3, 1)",
|
||||||
|
willChange: "transform, opacity",
|
||||||
|
'&[data-state="open"]': {
|
||||||
|
'&[data-side="top"]': { animationName: slideDownAndFade },
|
||||||
|
'&[data-side="right"]': { animationName: slideLeftAndFade },
|
||||||
|
'&[data-side="bottom"]': { animationName: slideUpAndFade },
|
||||||
|
'&[data-side="left"]': { animationName: slideRightAndFade },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
".dark &": {
|
||||||
|
boxShadow:
|
||||||
|
"0px 10px 38px -10px rgba(22, 23, 24, 0.85), 0px 10px 20px -15px rgba(22, 23, 24, 0.6)",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const itemStyles = {
|
||||||
|
all: "unset",
|
||||||
|
fontSize: 13,
|
||||||
|
lineHeight: 1,
|
||||||
|
color: "$text",
|
||||||
|
borderRadius: 3,
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
height: 28,
|
||||||
|
padding: "0 7px",
|
||||||
|
position: "relative",
|
||||||
|
paddingLeft: 10,
|
||||||
|
userSelect: "none",
|
||||||
|
|
||||||
|
"&[data-disabled]": {
|
||||||
|
color: "$textMuted",
|
||||||
|
pointerEvents: "none",
|
||||||
|
},
|
||||||
|
|
||||||
|
"&:focus": {
|
||||||
|
backgroundColor: "$purple9",
|
||||||
|
color: "$white",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const StyledItem = styled(ContextMenuPrimitive.Item, { ...itemStyles });
|
||||||
|
const StyledCheckboxItem = styled(ContextMenuPrimitive.CheckboxItem, {
|
||||||
|
...itemStyles,
|
||||||
|
});
|
||||||
|
const StyledRadioItem = styled(ContextMenuPrimitive.RadioItem, {
|
||||||
|
...itemStyles,
|
||||||
|
});
|
||||||
|
const StyledTriggerItem = styled(ContextMenuPrimitive.TriggerItem, {
|
||||||
|
'&[data-state="open"]': {
|
||||||
|
backgroundColor: "$purple9",
|
||||||
|
color: "$purple9",
|
||||||
|
},
|
||||||
|
...itemStyles,
|
||||||
|
});
|
||||||
|
|
||||||
|
const StyledLabel = styled(ContextMenuPrimitive.Label, {
|
||||||
|
paddingLeft: 10,
|
||||||
|
fontSize: 12,
|
||||||
|
lineHeight: "25px",
|
||||||
|
color: "$text",
|
||||||
|
});
|
||||||
|
|
||||||
|
const StyledSeparator = styled(ContextMenuPrimitive.Separator, {
|
||||||
|
height: 1,
|
||||||
|
backgroundColor: "$backgroundAlt",
|
||||||
|
margin: 5,
|
||||||
|
});
|
||||||
|
|
||||||
|
const StyledItemIndicator = styled(ContextMenuPrimitive.ItemIndicator, {
|
||||||
|
position: "absolute",
|
||||||
|
left: 0,
|
||||||
|
width: 25,
|
||||||
|
display: "inline-flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ContextMenuRoot = ContextMenuPrimitive.Root;
|
||||||
|
export const ContextMenuTrigger = ContextMenuPrimitive.Trigger;
|
||||||
|
export const ContextMenuContent = StyledContent;
|
||||||
|
export const ContextMenuItem = StyledItem;
|
||||||
|
export const ContextMenuCheckboxItem = StyledCheckboxItem;
|
||||||
|
export const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
|
||||||
|
export const ContextMenuRadioItem = StyledRadioItem;
|
||||||
|
export const ContextMenuItemIndicator = StyledItemIndicator;
|
||||||
|
export const ContextMenuTriggerItem = StyledTriggerItem;
|
||||||
|
export const ContextMenuLabel = StyledLabel;
|
||||||
|
export const ContextMenuSeparator = StyledSeparator;
|
||||||
@@ -13,7 +13,7 @@ import state from "../state";
|
|||||||
import wat from "../utils/wat-highlight";
|
import wat from "../utils/wat-highlight";
|
||||||
|
|
||||||
import EditorNavigation from "./EditorNavigation";
|
import EditorNavigation from "./EditorNavigation";
|
||||||
import { Button, Text, Link, Flex } from ".";
|
import { Button, Text, Link, Flex, Tabs, Tab } from ".";
|
||||||
import Monaco from "./Monaco";
|
import Monaco from "./Monaco";
|
||||||
|
|
||||||
const FILESIZE_BREAKPOINTS: [number, number] = [2 * 1024, 5 * 1024];
|
const FILESIZE_BREAKPOINTS: [number, number] = [2 * 1024, 5 * 1024];
|
||||||
@@ -25,9 +25,20 @@ const DeployEditor = () => {
|
|||||||
|
|
||||||
const [showContent, setShowContent] = useState(false);
|
const [showContent, setShowContent] = useState(false);
|
||||||
|
|
||||||
const activeFile = snap.files[snap.active]?.compiledContent
|
const compiledFiles = snap.files.filter(file => file.compiledContent);
|
||||||
? snap.files[snap.active]
|
const activeFile = compiledFiles[snap.activeWat];
|
||||||
: snap.files.filter(file => file.compiledContent)[0];
|
|
||||||
|
const renderNav = () => (
|
||||||
|
<Tabs
|
||||||
|
activeIndex={snap.activeWat}
|
||||||
|
onChangeActive={idx => (state.activeWat = idx)}
|
||||||
|
>
|
||||||
|
{compiledFiles.map((file, index) => {
|
||||||
|
return <Tab key={file.name} header={`${file.name}.wat`} />;
|
||||||
|
})}
|
||||||
|
</Tabs>
|
||||||
|
);
|
||||||
|
|
||||||
const compiledSize = activeFile?.compiledContent?.byteLength || 0;
|
const compiledSize = activeFile?.compiledContent?.byteLength || 0;
|
||||||
const color =
|
const color =
|
||||||
compiledSize > FILESIZE_BREAKPOINTS[1]
|
compiledSize > FILESIZE_BREAKPOINTS[1]
|
||||||
@@ -38,7 +49,7 @@ const DeployEditor = () => {
|
|||||||
|
|
||||||
const isContentChanged =
|
const isContentChanged =
|
||||||
activeFile && activeFile.compiledValueSnapshot !== activeFile.content;
|
activeFile && activeFile.compiledValueSnapshot !== activeFile.content;
|
||||||
// const hasDeployErros = activeFile && activeFile.containsErrors;
|
// const hasDeployErrors = activeFile && activeFile.containsErrors;
|
||||||
|
|
||||||
const CompiledStatView = activeFile && (
|
const CompiledStatView = activeFile && (
|
||||||
<Flex
|
<Flex
|
||||||
@@ -99,6 +110,7 @@ const DeployEditor = () => {
|
|||||||
</NextLink>
|
</NextLink>
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
|
|
||||||
const isContent =
|
const isContent =
|
||||||
snap.files?.filter(file => file.compiledWatContent).length > 0 &&
|
snap.files?.filter(file => file.compiledWatContent).length > 0 &&
|
||||||
router.isReady;
|
router.isReady;
|
||||||
@@ -113,7 +125,7 @@ const DeployEditor = () => {
|
|||||||
width: "100%",
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<EditorNavigation showWat />
|
<EditorNavigation renderNav={renderNav} />
|
||||||
<Container
|
<Container
|
||||||
css={{
|
css={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const contentShow = keyframes({
|
|||||||
"100%": { opacity: 1 },
|
"100%": { opacity: 1 },
|
||||||
});
|
});
|
||||||
const StyledOverlay = styled(DialogPrimitive.Overlay, {
|
const StyledOverlay = styled(DialogPrimitive.Overlay, {
|
||||||
zIndex: 9999,
|
zIndex: 10000,
|
||||||
backgroundColor: blackA.blackA9,
|
backgroundColor: blackA.blackA9,
|
||||||
position: "fixed",
|
position: "fixed",
|
||||||
inset: 0,
|
inset: 0,
|
||||||
|
|||||||
@@ -1,27 +1,7 @@
|
|||||||
import { keyframes } from "@stitches/react";
|
|
||||||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
||||||
|
|
||||||
import { styled } from "../stitches.config";
|
import { styled } from "../stitches.config";
|
||||||
|
import { slideDownAndFade, slideLeftAndFade, slideRightAndFade, slideUpAndFade } from '../styles/keyframes';
|
||||||
const slideUpAndFade = keyframes({
|
|
||||||
"0%": { opacity: 0, transform: "translateY(2px)" },
|
|
||||||
"100%": { opacity: 1, transform: "translateY(0)" },
|
|
||||||
});
|
|
||||||
|
|
||||||
const slideRightAndFade = keyframes({
|
|
||||||
"0%": { opacity: 0, transform: "translateX(-2px)" },
|
|
||||||
"100%": { opacity: 1, transform: "translateX(0)" },
|
|
||||||
});
|
|
||||||
|
|
||||||
const slideDownAndFade = keyframes({
|
|
||||||
"0%": { opacity: 0, transform: "translateY(-2px)" },
|
|
||||||
"100%": { opacity: 1, transform: "translateY(0)" },
|
|
||||||
});
|
|
||||||
|
|
||||||
const slideLeftAndFade = keyframes({
|
|
||||||
"0%": { opacity: 0, transform: "translateX(2px)" },
|
|
||||||
"100%": { opacity: 1, transform: "translateX(0)" },
|
|
||||||
});
|
|
||||||
|
|
||||||
const StyledContent = styled(DropdownMenuPrimitive.Content, {
|
const StyledContent = styled(DropdownMenuPrimitive.Content, {
|
||||||
minWidth: 220,
|
minWidth: 220,
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import React, { useState, useEffect, useCallback, useRef } from "react";
|
import React, {
|
||||||
|
useState,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
ReactNode,
|
||||||
|
} from "react";
|
||||||
import {
|
import {
|
||||||
Plus,
|
|
||||||
Share,
|
Share,
|
||||||
DownloadSimple,
|
DownloadSimple,
|
||||||
Gear,
|
Gear,
|
||||||
@@ -28,7 +32,6 @@ import { useSnapshot } from "valtio";
|
|||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createNewFile,
|
|
||||||
syncToGist,
|
syncToGist,
|
||||||
updateEditorSettings,
|
updateEditorSettings,
|
||||||
downloadAsZip,
|
downloadAsZip,
|
||||||
@@ -48,36 +51,23 @@ import {
|
|||||||
import Flex from "./Flex";
|
import Flex from "./Flex";
|
||||||
import Stack from "./Stack";
|
import Stack from "./Stack";
|
||||||
import { Input, Label } from "./Input";
|
import { Input, Label } from "./Input";
|
||||||
import Text from "./Text";
|
|
||||||
import Tooltip from "./Tooltip";
|
import Tooltip from "./Tooltip";
|
||||||
import { styled } from "../stitches.config";
|
|
||||||
import { showAlert } from "../state/actions/showAlert";
|
import { showAlert } from "../state/actions/showAlert";
|
||||||
|
|
||||||
const ErrorText = styled(Text, {
|
|
||||||
color: "$error",
|
|
||||||
mt: "$1",
|
|
||||||
display: "block",
|
|
||||||
});
|
|
||||||
|
|
||||||
const EditorNavigation = ({ showWat }: { showWat?: boolean }) => {
|
const EditorNavigation = ({ renderNav }: { renderNav?: () => ReactNode }) => {
|
||||||
const snap = useSnapshot(state);
|
const snap = useSnapshot(state);
|
||||||
const [editorSettingsOpen, setEditorSettingsOpen] = useState(false);
|
const [editorSettingsOpen, setEditorSettingsOpen] = useState(false);
|
||||||
const [isNewfileDialogOpen, setIsNewfileDialogOpen] = useState(false);
|
|
||||||
const [newfileError, setNewfileError] = useState<string | null>(null);
|
|
||||||
const [filename, setFilename] = useState("");
|
|
||||||
const { data: session, status } = useSession();
|
const { data: session, status } = useSession();
|
||||||
const [popup, setPopUp] = useState(false);
|
const [popup, setPopUp] = useState(false);
|
||||||
const [editorSettings, setEditorSettings] = useState(snap.editorSettings);
|
const [editorSettings, setEditorSettings] = useState(snap.editorSettings);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (session && session.user && popup) {
|
if (session && session.user && popup) {
|
||||||
setPopUp(false);
|
setPopUp(false);
|
||||||
}
|
}
|
||||||
}, [session, popup]);
|
}, [session, popup]);
|
||||||
|
|
||||||
// when filename changes, reset error
|
|
||||||
useEffect(() => {
|
|
||||||
setNewfileError(null);
|
|
||||||
}, [filename, setNewfileError]);
|
|
||||||
|
|
||||||
const showNewGistAlert = () => {
|
const showNewGistAlert = () => {
|
||||||
showAlert("Are you sure?", {
|
showAlert("Are you sure?", {
|
||||||
@@ -95,46 +85,8 @@ const EditorNavigation = ({ showWat }: { showWat?: boolean }) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const validateFilename = useCallback(
|
|
||||||
(filename: string): { error: string | null } => {
|
|
||||||
// check if filename already exists
|
|
||||||
if (!filename) {
|
|
||||||
return { error: "You need to add filename" };
|
|
||||||
}
|
|
||||||
if (snap.files.find((file) => file.name === filename)) {
|
|
||||||
return { error: "Filename already exists." };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!filename.includes(".") || filename[filename.length - 1] === ".") {
|
|
||||||
return { error: "Filename should include file extension" };
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for illegal characters
|
|
||||||
const ALPHA_NUMERICAL_REGEX = /^[A-Za-z0-9_-]+[.][A-Za-z0-9]{1,4}$/g;
|
|
||||||
if (!filename.match(ALPHA_NUMERICAL_REGEX)) {
|
|
||||||
return {
|
|
||||||
error: `Filename can contain only characters from a-z, A-Z, 0-9, "_" and "-" and it needs to have file extension (e.g. ".c")`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return { error: null };
|
|
||||||
},
|
|
||||||
[snap.files]
|
|
||||||
);
|
|
||||||
const handleConfirm = useCallback(() => {
|
|
||||||
// add default extension in case omitted
|
|
||||||
const chk = validateFilename(filename);
|
|
||||||
if (chk && chk.error) {
|
|
||||||
setNewfileError(`Error: ${chk.error}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setIsNewfileDialogOpen(false);
|
|
||||||
createNewFile(filename);
|
|
||||||
setFilename("");
|
|
||||||
}, [filename, setIsNewfileDialogOpen, setFilename, validateFilename]);
|
|
||||||
const scrollRef = useRef<HTMLDivElement>(null);
|
const scrollRef = useRef<HTMLDivElement>(null);
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const files = snap.files;
|
|
||||||
return (
|
return (
|
||||||
<Flex css={{ flexShrink: 0, gap: "$0" }}>
|
<Flex css={{ flexShrink: 0, gap: "$0" }}>
|
||||||
<Flex
|
<Flex
|
||||||
@@ -174,131 +126,14 @@ const EditorNavigation = ({ showWat }: { showWat?: boolean }) => {
|
|||||||
scrollbarWidth: "thin",
|
scrollbarWidth: "thin",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
onWheelCapture={(e) => {
|
onWheelCapture={e => {
|
||||||
if (scrollRef.current) {
|
if (scrollRef.current) {
|
||||||
scrollRef.current.scrollLeft += e.deltaY;
|
scrollRef.current.scrollLeft += e.deltaY;
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Container css={{ flex: 1 }} ref={containerRef}>
|
<Container css={{ flex: 1 }} ref={containerRef}>
|
||||||
<Stack
|
{renderNav?.()}
|
||||||
css={{
|
|
||||||
gap: "$3",
|
|
||||||
flex: 1,
|
|
||||||
flexWrap: "nowrap",
|
|
||||||
marginBottom: "-1px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{files &&
|
|
||||||
files.length > 0 &&
|
|
||||||
files.map((file, index) => {
|
|
||||||
if (!file.compiledContent && showWat) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
size="sm"
|
|
||||||
outline={
|
|
||||||
showWat ? snap.activeWat !== index : snap.active !== index
|
|
||||||
}
|
|
||||||
onClick={() => (state.active = index)}
|
|
||||||
key={file.name + index}
|
|
||||||
css={{
|
|
||||||
"&:hover": {
|
|
||||||
span: {
|
|
||||||
visibility: "visible",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{file.name}
|
|
||||||
{showWat && ".wat"}
|
|
||||||
{!showWat && (
|
|
||||||
<Box
|
|
||||||
as="span"
|
|
||||||
css={{
|
|
||||||
display: "flex",
|
|
||||||
p: "2px",
|
|
||||||
borderRadius: "$full",
|
|
||||||
mr: "-4px",
|
|
||||||
"&:hover": {
|
|
||||||
// boxSizing: "0px 0px 1px",
|
|
||||||
backgroundColor: "$mauve2",
|
|
||||||
color: "$mauve12",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
onClick={(ev: React.MouseEvent<HTMLElement>) => {
|
|
||||||
ev.stopPropagation();
|
|
||||||
// Remove file from state
|
|
||||||
state.files.splice(index, 1);
|
|
||||||
// Change active file state
|
|
||||||
// If deleted file is behind active tab
|
|
||||||
// we keep the current state otherwise
|
|
||||||
// select previous file on the list
|
|
||||||
state.active =
|
|
||||||
index > snap.active ? snap.active : snap.active - 1;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<X size="9px" weight="bold" />
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
{!showWat && (
|
|
||||||
<Dialog
|
|
||||||
open={isNewfileDialogOpen}
|
|
||||||
onOpenChange={setIsNewfileDialogOpen}
|
|
||||||
>
|
|
||||||
<DialogTrigger asChild>
|
|
||||||
<Button
|
|
||||||
ghost
|
|
||||||
size="sm"
|
|
||||||
css={{ alignItems: "center", px: "$2", mr: "$3" }}
|
|
||||||
>
|
|
||||||
<Plus size="16px" />{" "}
|
|
||||||
{snap.files.length === 0 && "Add new file"}
|
|
||||||
</Button>
|
|
||||||
</DialogTrigger>
|
|
||||||
<DialogContent>
|
|
||||||
<DialogTitle>Create new file</DialogTitle>
|
|
||||||
<DialogDescription>
|
|
||||||
<Label>Filename</Label>
|
|
||||||
<Input
|
|
||||||
value={filename}
|
|
||||||
onChange={(e) => setFilename(e.target.value)}
|
|
||||||
onKeyPress={(e) => {
|
|
||||||
if (e.key === "Enter") {
|
|
||||||
handleConfirm();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<ErrorText>{newfileError}</ErrorText>
|
|
||||||
</DialogDescription>
|
|
||||||
|
|
||||||
<Flex
|
|
||||||
css={{
|
|
||||||
marginTop: 25,
|
|
||||||
justifyContent: "flex-end",
|
|
||||||
gap: "$3",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DialogClose asChild>
|
|
||||||
<Button outline>Cancel</Button>
|
|
||||||
</DialogClose>
|
|
||||||
<Button variant="primary" onClick={handleConfirm}>
|
|
||||||
Create file
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
|
||||||
<DialogClose asChild>
|
|
||||||
<Box css={{ position: "absolute", top: "$3", right: "$3" }}>
|
|
||||||
<X size="20px" />
|
|
||||||
</Box>
|
|
||||||
</DialogClose>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
)}
|
|
||||||
</Stack>
|
|
||||||
</Container>
|
</Container>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
@@ -542,8 +377,8 @@ const EditorNavigation = ({ showWat }: { showWat?: boolean }) => {
|
|||||||
type="number"
|
type="number"
|
||||||
min="1"
|
min="1"
|
||||||
value={editorSettings.tabSize}
|
value={editorSettings.tabSize}
|
||||||
onChange={(e) =>
|
onChange={e =>
|
||||||
setEditorSettings((curr) => ({
|
setEditorSettings(curr => ({
|
||||||
...curr,
|
...curr,
|
||||||
tabSize: Number(e.target.value),
|
tabSize: Number(e.target.value),
|
||||||
}))
|
}))
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useRef } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { useSnapshot, ref } from "valtio";
|
import { useSnapshot, ref } from "valtio";
|
||||||
import type monaco from "monaco-editor";
|
import type monaco from "monaco-editor";
|
||||||
import { ArrowBendLeftUp } from "phosphor-react";
|
import { ArrowBendLeftUp } from "phosphor-react";
|
||||||
@@ -7,7 +7,7 @@ import { useRouter } from "next/router";
|
|||||||
|
|
||||||
import Box from "./Box";
|
import Box from "./Box";
|
||||||
import Container from "./Container";
|
import Container from "./Container";
|
||||||
import { saveFile } from "../state/actions";
|
import { createNewFile, saveFile } from "../state/actions";
|
||||||
import { apiHeaderFiles } from "../state/constants";
|
import { apiHeaderFiles } from "../state/constants";
|
||||||
import state from "../state";
|
import state from "../state";
|
||||||
|
|
||||||
@@ -20,15 +20,23 @@ import ReconnectingWebSocket from "reconnecting-websocket";
|
|||||||
|
|
||||||
import docs from "../xrpl-hooks-docs/docs";
|
import docs from "../xrpl-hooks-docs/docs";
|
||||||
import Monaco from "./Monaco";
|
import Monaco from "./Monaco";
|
||||||
import { saveAllFiles } from '../state/actions/saveFile';
|
import { saveAllFiles } from "../state/actions/saveFile";
|
||||||
|
import { Tab, Tabs } from "./Tabs";
|
||||||
|
import { renameFile } from "../state/actions/createNewFile";
|
||||||
|
import { Link } from ".";
|
||||||
|
import Markdown from "./Markdown";
|
||||||
|
|
||||||
|
const checkWritable = (filename?: string): boolean => {
|
||||||
|
if (apiHeaderFiles.find(file => file === filename)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
const validateWritability = (editor: monaco.editor.IStandaloneCodeEditor) => {
|
const validateWritability = (editor: monaco.editor.IStandaloneCodeEditor) => {
|
||||||
const currPath = editor.getModel()?.uri.path;
|
const filename = editor.getModel()?.uri.path.split("/").pop();
|
||||||
if (apiHeaderFiles.find(h => currPath?.endsWith(h))) {
|
const isWritable = checkWritable(filename);
|
||||||
editor.updateOptions({ readOnly: true });
|
editor.updateOptions({ readOnly: !isWritable });
|
||||||
} else {
|
|
||||||
editor.updateOptions({ readOnly: false });
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let decorations: { [key: string]: string[] } = {};
|
let decorations: { [key: string]: string[] } = {};
|
||||||
@@ -97,6 +105,7 @@ const HooksEditor = () => {
|
|||||||
const snap = useSnapshot(state);
|
const snap = useSnapshot(state);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
|
const [isMdPreview, setIsMdPreview] = useState(true);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editorRef.current) validateWritability(editorRef.current);
|
if (editorRef.current) validateWritability(editorRef.current);
|
||||||
@@ -119,6 +128,53 @@ const HooksEditor = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const file = snap.files[snap.active];
|
const file = snap.files[snap.active];
|
||||||
|
|
||||||
|
const renderNav = () => (
|
||||||
|
<Tabs
|
||||||
|
label="File"
|
||||||
|
activeIndex={snap.active}
|
||||||
|
onChangeActive={idx => (state.active = idx)}
|
||||||
|
extensionRequired
|
||||||
|
onCreateNewTab={createNewFile}
|
||||||
|
onCloseTab={idx => state.files.splice(idx, 1)}
|
||||||
|
onRenameTab={(idx, nwName, oldName = "") => renameFile(oldName, nwName)}
|
||||||
|
headerExtraValidation={{
|
||||||
|
regex: /^[A-Za-z0-9_-]+[.][A-Za-z0-9]{1,4}$/g,
|
||||||
|
error:
|
||||||
|
'Filename can contain only characters from a-z, A-Z, 0-9, "_" and "-"',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{snap.files.map((file, index) => {
|
||||||
|
return (
|
||||||
|
<Tab
|
||||||
|
key={file.name}
|
||||||
|
header={file.name}
|
||||||
|
renameDisabled={!checkWritable(file.name)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Tabs>
|
||||||
|
);
|
||||||
|
const previewToggle = (
|
||||||
|
<Link
|
||||||
|
onClick={() => {
|
||||||
|
if (!isMdPreview) {
|
||||||
|
saveFile(false);
|
||||||
|
}
|
||||||
|
setIsMdPreview(!isMdPreview);
|
||||||
|
}}
|
||||||
|
css={{
|
||||||
|
position: "absolute",
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
zIndex: 10,
|
||||||
|
m: "$1",
|
||||||
|
fontSize: "$sm",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{isMdPreview ? "Exit Preview" : "View Preview"}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
css={{
|
css={{
|
||||||
@@ -131,112 +187,129 @@ const HooksEditor = () => {
|
|||||||
width: "100%",
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<EditorNavigation />
|
<EditorNavigation renderNav={renderNav} />
|
||||||
|
{file?.language === "markdown" && previewToggle}
|
||||||
{snap.files.length > 0 && router.isReady ? (
|
{snap.files.length > 0 && router.isReady ? (
|
||||||
<Monaco
|
isMdPreview && file?.language === "markdown" ? (
|
||||||
keepCurrentModel
|
<Markdown
|
||||||
defaultLanguage={file?.language}
|
components={{
|
||||||
language={file?.language}
|
a: ({ href, children }) => (
|
||||||
path={`file:///work/c/${file?.name}`}
|
<Link target="_blank" rel="noopener noreferrer" href={href}>
|
||||||
defaultValue={file?.content}
|
{children}
|
||||||
// onChange={val => (state.files[snap.active].content = val)} // Auto save?
|
</Link>
|
||||||
beforeMount={monaco => {
|
),
|
||||||
if (!snap.editorCtx) {
|
}}
|
||||||
snap.files.forEach(file =>
|
>
|
||||||
monaco.editor.createModel(
|
{file.content}
|
||||||
file.content,
|
</Markdown>
|
||||||
file.language,
|
) : (
|
||||||
monaco.Uri.parse(`file:///work/c/${file.name}`)
|
<Monaco
|
||||||
)
|
keepCurrentModel
|
||||||
);
|
defaultLanguage={file?.language}
|
||||||
}
|
language={file?.language}
|
||||||
|
path={`file:///work/c/${file?.name}`}
|
||||||
|
defaultValue={file?.content}
|
||||||
|
// onChange={val => (state.files[snap.active].content = val)} // Auto save?
|
||||||
|
beforeMount={monaco => {
|
||||||
|
if (!snap.editorCtx) {
|
||||||
|
snap.files.forEach(file =>
|
||||||
|
monaco.editor.createModel(
|
||||||
|
file.content,
|
||||||
|
file.language,
|
||||||
|
monaco.Uri.parse(`file:///work/c/${file.name}`)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// create the web socket
|
// create the web socket
|
||||||
if (!subscriptionRef.current) {
|
if (!subscriptionRef.current) {
|
||||||
monaco.languages.register({
|
monaco.languages.register({
|
||||||
id: "c",
|
id: "c",
|
||||||
extensions: [".c", ".h"],
|
extensions: [".c", ".h"],
|
||||||
aliases: ["C", "c", "H", "h"],
|
aliases: ["C", "c", "H", "h"],
|
||||||
mimetypes: ["text/plain"],
|
mimetypes: ["text/plain"],
|
||||||
});
|
});
|
||||||
MonacoServices.install(monaco);
|
MonacoServices.install(monaco);
|
||||||
const webSocket = createWebSocket(
|
const webSocket = createWebSocket(
|
||||||
process.env.NEXT_PUBLIC_LANGUAGE_SERVER_API_ENDPOINT || ""
|
process.env.NEXT_PUBLIC_LANGUAGE_SERVER_API_ENDPOINT || ""
|
||||||
);
|
);
|
||||||
subscriptionRef.current = webSocket;
|
subscriptionRef.current = webSocket;
|
||||||
// listen when the web socket is opened
|
// listen when the web socket is opened
|
||||||
listen({
|
listen({
|
||||||
webSocket: webSocket as WebSocket,
|
webSocket: webSocket as WebSocket,
|
||||||
onConnection: connection => {
|
onConnection: connection => {
|
||||||
// create and start the language client
|
// create and start the language client
|
||||||
const languageClient = createLanguageClient(connection);
|
const languageClient = createLanguageClient(connection);
|
||||||
const disposable = languageClient.start();
|
const disposable = languageClient.start();
|
||||||
|
|
||||||
connection.onClose(() => {
|
connection.onClose(() => {
|
||||||
try {
|
try {
|
||||||
disposable.dispose();
|
disposable.dispose();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("err", err);
|
console.log("err", err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// editor.updateOptions({
|
||||||
|
// minimap: {
|
||||||
|
// enabled: false,
|
||||||
|
// },
|
||||||
|
// ...snap.editorSettings,
|
||||||
|
// });
|
||||||
|
if (!state.editorCtx) {
|
||||||
|
state.editorCtx = ref(monaco.editor);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onMount={(editor, monaco) => {
|
||||||
|
editorRef.current = editor;
|
||||||
|
monacoRef.current = monaco;
|
||||||
|
editor.updateOptions({
|
||||||
|
glyphMargin: true,
|
||||||
|
lightbulb: {
|
||||||
|
enabled: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
editor.addCommand(
|
||||||
|
monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS,
|
||||||
// editor.updateOptions({
|
() => {
|
||||||
// minimap: {
|
saveFile();
|
||||||
// enabled: false,
|
}
|
||||||
// },
|
);
|
||||||
// ...snap.editorSettings,
|
// When the markers (errors/warnings from clangd language server) change
|
||||||
// });
|
// Lets improve the markers by adding extra content to them from related
|
||||||
if (!state.editorCtx) {
|
// md files
|
||||||
state.editorCtx = ref(monaco.editor);
|
monaco.editor.onDidChangeMarkers(() => {
|
||||||
}
|
if (monacoRef.current) {
|
||||||
}}
|
setMarkers(monacoRef.current);
|
||||||
onMount={(editor, monaco) => {
|
|
||||||
editorRef.current = editor;
|
|
||||||
monacoRef.current = monaco;
|
|
||||||
editor.updateOptions({
|
|
||||||
glyphMargin: true,
|
|
||||||
lightbulb: {
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
editor.addCommand(
|
|
||||||
monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS,
|
|
||||||
() => {
|
|
||||||
saveFile();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// When the markers (errors/warnings from clangd language server) change
|
|
||||||
// Lets improve the markers by adding extra content to them from related
|
|
||||||
// md files
|
|
||||||
monaco.editor.onDidChangeMarkers(() => {
|
|
||||||
if (monacoRef.current) {
|
|
||||||
setMarkers(monacoRef.current);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Hacky way to hide Peek menu
|
|
||||||
editor.onContextMenu(e => {
|
|
||||||
const host =
|
|
||||||
document.querySelector<HTMLElement>(".shadow-root-host");
|
|
||||||
|
|
||||||
const contextMenuItems =
|
|
||||||
host?.shadowRoot?.querySelectorAll("li.action-item");
|
|
||||||
contextMenuItems?.forEach(k => {
|
|
||||||
// If menu item contains "Peek" lets hide it
|
|
||||||
if (k.querySelector(".action-label")?.textContent === "Peek") {
|
|
||||||
// @ts-expect-error
|
|
||||||
k["style"].display = "none";
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
validateWritability(editor);
|
// Hacky way to hide Peek menu
|
||||||
}}
|
editor.onContextMenu(e => {
|
||||||
theme={theme === "dark" ? "dark" : "light"}
|
const host =
|
||||||
/>
|
document.querySelector<HTMLElement>(".shadow-root-host");
|
||||||
|
|
||||||
|
const contextMenuItems =
|
||||||
|
host?.shadowRoot?.querySelectorAll("li.action-item");
|
||||||
|
contextMenuItems?.forEach(k => {
|
||||||
|
// If menu item contains "Peek" lets hide it
|
||||||
|
if (
|
||||||
|
k.querySelector(".action-label")?.textContent === "Peek"
|
||||||
|
) {
|
||||||
|
// @ts-expect-error
|
||||||
|
k["style"].display = "none";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
validateWritability(editor);
|
||||||
|
}}
|
||||||
|
theme={theme === "dark" ? "dark" : "light"}
|
||||||
|
/>
|
||||||
|
)
|
||||||
) : (
|
) : (
|
||||||
<Container>
|
<Container>
|
||||||
{!snap.loading && router.isReady && (
|
{!snap.loading && router.isReady && (
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ export const Log: FC<ILog> = ({
|
|||||||
|
|
||||||
const enrichAccounts = useCallback(
|
const enrichAccounts = useCallback(
|
||||||
(str?: string): ReactNode => {
|
(str?: string): ReactNode => {
|
||||||
if (!str || !accounts.length) return null;
|
if (!str || !accounts.length) return str;
|
||||||
|
|
||||||
const pattern = `(${accounts.map(acc => acc.address).join("|")})`;
|
const pattern = `(${accounts.map(acc => acc.address).join("|")})`;
|
||||||
const res = regexifyString({
|
const res = regexifyString({
|
||||||
|
|||||||
14
components/Markdown.tsx
Normal file
14
components/Markdown.tsx
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
|
import { styled } from '../stitches.config';
|
||||||
|
|
||||||
|
const Markdown = styled(ReactMarkdown, {
|
||||||
|
px: "$8",
|
||||||
|
"@md": {
|
||||||
|
px: "$20",
|
||||||
|
},
|
||||||
|
pb: "$5",
|
||||||
|
height: "100%",
|
||||||
|
overflowY: "auto"
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Markdown;
|
||||||
@@ -102,7 +102,7 @@ const Navigation = () => {
|
|||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Heading css={{ lineHeight: 1 }}>
|
<Heading css={{ lineHeight: 1 }}>
|
||||||
{snap.files?.[0]?.name || "XRPL Hooks"}
|
{snap.gistName || "XRPL Hooks"}
|
||||||
</Heading>
|
</Heading>
|
||||||
<Text
|
<Text
|
||||||
css={{ fontSize: "$xs", color: "$mauve10", lineHeight: 1 }}
|
css={{ fontSize: "$xs", color: "$mauve10", lineHeight: 1 }}
|
||||||
|
|||||||
@@ -143,7 +143,6 @@ const RunScript: React.FC<{ file: IFile }> = ({ file: { content, name } }) => {
|
|||||||
setIframeCode(template);
|
setIframeCode(template);
|
||||||
|
|
||||||
state.scriptLogs = [
|
state.scriptLogs = [
|
||||||
...snap.scriptLogs,
|
|
||||||
{ type: "success", message: "Started running..." },
|
{ type: "success", message: "Started running..." },
|
||||||
];
|
];
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ const Select = forwardRef<any, Props>((props, ref) => {
|
|||||||
...provided,
|
...provided,
|
||||||
color: colors.searchText,
|
color: colors.searchText,
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
state.isSelected || state.isFocused
|
state.isFocused
|
||||||
? colors.activeLight
|
? colors.activeLight
|
||||||
: colors.dropDownBg,
|
: colors.dropDownBg,
|
||||||
":hover": {
|
":hover": {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import { Plus, Trash, X } from "phosphor-react";
|
import { Plus, Trash, X } from "phosphor-react";
|
||||||
import Button from "./Button";
|
import { Button, Box, Text } from ".";
|
||||||
import Box from "./Box";
|
|
||||||
import { Stack, Flex, Select } from ".";
|
import { Stack, Flex, Select } from ".";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
@@ -19,48 +18,30 @@ import {
|
|||||||
useForm,
|
useForm,
|
||||||
} from "react-hook-form";
|
} from "react-hook-form";
|
||||||
|
|
||||||
import { TTS, tts } from "../utils/hookOnCalculator";
|
|
||||||
import { deployHook } from "../state/actions";
|
import { deployHook } from "../state/actions";
|
||||||
import { useSnapshot } from "valtio";
|
import { useSnapshot } from "valtio";
|
||||||
import state, { SelectOption } from "../state";
|
import state, { IFile, SelectOption } from "../state";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import { prepareDeployHookTx, sha256 } from "../state/actions/deployHook";
|
import { prepareDeployHookTx, sha256 } from "../state/actions/deployHook";
|
||||||
import estimateFee from "../utils/estimateFee";
|
import estimateFee from "../utils/estimateFee";
|
||||||
|
import {
|
||||||
const transactionOptions = Object.keys(tts).map(key => ({
|
getParameters,
|
||||||
label: key,
|
getInvokeOptions,
|
||||||
value: key as keyof TTS,
|
transactionOptions,
|
||||||
}));
|
SetHookData,
|
||||||
|
} from "../utils/setHook";
|
||||||
export type SetHookData = {
|
import { capitalize } from "../utils/helpers";
|
||||||
Invoke: {
|
|
||||||
value: keyof TTS;
|
|
||||||
label: string;
|
|
||||||
}[];
|
|
||||||
Fee: string;
|
|
||||||
HookNamespace: string;
|
|
||||||
HookParameters: {
|
|
||||||
HookParameter: {
|
|
||||||
HookParameterName: string;
|
|
||||||
HookParameterValue: string;
|
|
||||||
};
|
|
||||||
}[];
|
|
||||||
// HookGrants: {
|
|
||||||
// HookGrant: {
|
|
||||||
// Authorize: string;
|
|
||||||
// HookHash: string;
|
|
||||||
// };
|
|
||||||
// }[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
|
export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
|
||||||
({ accountAddress }) => {
|
({ accountAddress }) => {
|
||||||
const snap = useSnapshot(state);
|
const snap = useSnapshot(state);
|
||||||
const activeFile = snap.files[snap.active]?.compiledContent
|
|
||||||
? snap.files[snap.active]
|
const [estimateLoading, setEstimateLoading] = useState(false);
|
||||||
: snap.files.filter(file => file.compiledContent)[0];
|
|
||||||
const [isSetHookDialogOpen, setIsSetHookDialogOpen] = useState(false);
|
const [isSetHookDialogOpen, setIsSetHookDialogOpen] = useState(false);
|
||||||
|
|
||||||
|
const compiledFiles = snap.files.filter(file => file.compiledContent);
|
||||||
|
const activeFile = compiledFiles[snap.activeWat] as IFile | undefined;
|
||||||
|
|
||||||
const accountOptions: SelectOption[] = snap.accounts.map(acc => ({
|
const accountOptions: SelectOption[] = snap.accounts.map(acc => ({
|
||||||
label: acc.name,
|
label: acc.name,
|
||||||
value: acc.address,
|
value: acc.address,
|
||||||
@@ -72,6 +53,26 @@ export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
|
|||||||
const account = snap.accounts.find(
|
const account = snap.accounts.find(
|
||||||
acc => acc.address === selectedAccount?.value
|
acc => acc.address === selectedAccount?.value
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const getHookNamespace = useCallback(
|
||||||
|
() =>
|
||||||
|
(activeFile && snap.deployValues[activeFile.name]?.HookNamespace) ||
|
||||||
|
activeFile?.name.split(".")[0] ||
|
||||||
|
"",
|
||||||
|
[activeFile, snap.deployValues]
|
||||||
|
);
|
||||||
|
|
||||||
|
const getDefaultValues = useCallback((): Partial<SetHookData> => {
|
||||||
|
const content = activeFile?.compiledValueSnapshot;
|
||||||
|
return (
|
||||||
|
(activeFile && snap.deployValues[activeFile.name]) || {
|
||||||
|
HookNamespace: getHookNamespace(),
|
||||||
|
Invoke: getInvokeOptions(content),
|
||||||
|
HookParameters: getParameters(content),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, [activeFile, getHookNamespace, snap.deployValues]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@@ -79,38 +80,26 @@ export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
|
|||||||
watch,
|
watch,
|
||||||
setValue,
|
setValue,
|
||||||
getValues,
|
getValues,
|
||||||
|
reset,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
} = useForm<SetHookData>({
|
} = useForm<SetHookData>({
|
||||||
defaultValues: snap.deployValues?.[activeFile?.name]
|
defaultValues: getDefaultValues(),
|
||||||
? snap.deployValues[activeFile?.name]
|
|
||||||
: {
|
|
||||||
HookNamespace:
|
|
||||||
snap.files?.[snap.activeWat]?.name?.split(".")?.[0] || "",
|
|
||||||
Invoke: transactionOptions.filter(to => to.label === "ttPAYMENT"),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
const { fields, append, remove } = useFieldArray({
|
const { fields, append, remove } = useFieldArray({
|
||||||
control,
|
control,
|
||||||
name: "HookParameters", // unique name for your Field Array
|
name: "HookParameters", // unique name for your Field Array
|
||||||
});
|
});
|
||||||
const [formInitialized, setFormInitialized] = useState(false);
|
|
||||||
const [estimateLoading, setEstimateLoading] = useState(false);
|
|
||||||
const watchedFee = watch("Fee");
|
const watchedFee = watch("Fee");
|
||||||
|
|
||||||
// Update value if activeWat changes
|
// Reset form if activeFile changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const defaultValue = snap.deployValues?.[activeFile?.name]
|
if (!activeFile) return;
|
||||||
? snap.deployValues?.[activeFile?.name].HookNamespace
|
const defaultValues = getDefaultValues();
|
||||||
: snap.files?.[snap.activeWat]?.name?.split(".")?.[0] || "";
|
|
||||||
setValue("HookNamespace", defaultValue);
|
reset(defaultValues);
|
||||||
setFormInitialized(true);
|
}, [activeFile, getDefaultValues, reset]);
|
||||||
}, [
|
|
||||||
snap.activeWat,
|
|
||||||
snap.files,
|
|
||||||
setValue,
|
|
||||||
activeFile?.name,
|
|
||||||
snap.deployValues,
|
|
||||||
]);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
watchedFee &&
|
watchedFee &&
|
||||||
@@ -128,54 +117,51 @@ export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
|
|||||||
// name: "HookGrants", // unique name for your Field Array
|
// name: "HookGrants", // unique name for your Field Array
|
||||||
// });
|
// });
|
||||||
const [hashedNamespace, setHashedNamespace] = useState("");
|
const [hashedNamespace, setHashedNamespace] = useState("");
|
||||||
const namespace = watch(
|
|
||||||
"HookNamespace",
|
const namespace = watch("HookNamespace", getHookNamespace());
|
||||||
snap.deployValues?.[activeFile?.name]
|
|
||||||
? snap.deployValues?.[activeFile?.name].HookNamespace
|
|
||||||
: snap.files?.[snap.activeWat]?.name?.split(".")?.[0] || ""
|
|
||||||
);
|
|
||||||
const calculateHashedValue = useCallback(async () => {
|
const calculateHashedValue = useCallback(async () => {
|
||||||
const hashedVal = await sha256(namespace);
|
const hashedVal = await sha256(namespace);
|
||||||
setHashedNamespace(hashedVal.toUpperCase());
|
setHashedNamespace(hashedVal.toUpperCase());
|
||||||
}, [namespace]);
|
}, [namespace]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
calculateHashedValue();
|
calculateHashedValue();
|
||||||
}, [namespace, calculateHashedValue]);
|
}, [namespace, calculateHashedValue]);
|
||||||
|
|
||||||
// Calcucate initial fee estimate when modal opens
|
const calculateFee = useCallback(async () => {
|
||||||
useEffect(() => {
|
if (!account) return;
|
||||||
if (formInitialized && account) {
|
|
||||||
(async () => {
|
const formValues = getValues();
|
||||||
const formValues = getValues();
|
const tx = await prepareDeployHookTx(account, formValues);
|
||||||
const tx = await prepareDeployHookTx(account, formValues);
|
if (!tx) {
|
||||||
if (!tx) {
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
const res = await estimateFee(tx, account);
|
|
||||||
if (res && res.base_fee) {
|
|
||||||
setValue("Fee", Math.round(Number(res.base_fee || "")).toString());
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
const res = await estimateFee(tx, account);
|
||||||
}, [formInitialized]);
|
if (res && res.base_fee) {
|
||||||
|
setValue("Fee", Math.round(Number(res.base_fee || "")).toString());
|
||||||
|
}
|
||||||
|
}, [account, getValues, setValue]);
|
||||||
|
|
||||||
const tooLargeFile = () => {
|
const tooLargeFile = () => {
|
||||||
const activeFile = snap.files[snap.active].compiledContent
|
|
||||||
? snap.files[snap.active]
|
|
||||||
: snap.files.filter(file => file.compiledContent)[0];
|
|
||||||
return Boolean(
|
return Boolean(
|
||||||
activeFile?.compiledContent?.byteLength &&
|
activeFile?.compiledContent?.byteLength &&
|
||||||
activeFile?.compiledContent?.byteLength >= 64000
|
activeFile?.compiledContent?.byteLength >= 64000
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit: SubmitHandler<SetHookData> = async (data) => {
|
const onSubmit: SubmitHandler<SetHookData> = async data => {
|
||||||
const currAccount = state.accounts.find(
|
const currAccount = state.accounts.find(
|
||||||
(acc) => acc.address === account?.address
|
acc => acc.address === account?.address
|
||||||
);
|
);
|
||||||
if (!account) return;
|
if (!account) return;
|
||||||
if (currAccount) currAccount.isLoading = true;
|
if (currAccount) currAccount.isLoading = true;
|
||||||
|
|
||||||
|
data.HookParameters.forEach(param => {
|
||||||
|
delete param.$metaData;
|
||||||
|
return param;
|
||||||
|
});
|
||||||
|
|
||||||
const res = await deployHook(account, data);
|
const res = await deployHook(account, data);
|
||||||
if (currAccount) currAccount.isLoading = false;
|
if (currAccount) currAccount.isLoading = false;
|
||||||
|
|
||||||
@@ -185,8 +171,14 @@ export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
|
|||||||
}
|
}
|
||||||
toast.error(`Transaction failed! (${res?.engine_result_message})`);
|
toast.error(`Transaction failed! (${res?.engine_result_message})`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onOpenChange = useCallback((open: boolean) => {
|
||||||
|
setIsSetHookDialogOpen(open);
|
||||||
|
|
||||||
|
if (open) calculateFee();
|
||||||
|
}, [calculateFee]);
|
||||||
return (
|
return (
|
||||||
<Dialog open={isSetHookDialogOpen} onOpenChange={setIsSetHookDialogOpen}>
|
<Dialog open={isSetHookDialogOpen} onOpenChange={onOpenChange}>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
ghost
|
ghost
|
||||||
@@ -194,10 +186,7 @@ export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
|
|||||||
uppercase
|
uppercase
|
||||||
variant={"secondary"}
|
variant={"secondary"}
|
||||||
disabled={
|
disabled={
|
||||||
!account ||
|
!account || account.isLoading || !activeFile || tooLargeFile()
|
||||||
account.isLoading ||
|
|
||||||
!snap.files.filter(file => file.compiledWatContent).length ||
|
|
||||||
tooLargeFile()
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Set Hook
|
Set Hook
|
||||||
@@ -213,7 +202,6 @@ export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
|
|||||||
<Select
|
<Select
|
||||||
instanceId="deploy-account"
|
instanceId="deploy-account"
|
||||||
placeholder="Select account"
|
placeholder="Select account"
|
||||||
hideSelectedOptions
|
|
||||||
options={accountOptions}
|
options={accountOptions}
|
||||||
value={selectedAccount}
|
value={selectedAccount}
|
||||||
onChange={(acc: any) => setSelectedAccount(acc)}
|
onChange={(acc: any) => setSelectedAccount(acc)}
|
||||||
@@ -259,22 +247,39 @@ export const SetHookDialog: React.FC<{ accountAddress: string }> = React.memo(
|
|||||||
<Stack>
|
<Stack>
|
||||||
{fields.map((field, index) => (
|
{fields.map((field, index) => (
|
||||||
<Stack key={field.id}>
|
<Stack key={field.id}>
|
||||||
<Input
|
<Flex column>
|
||||||
// important to include key with field's id
|
<Flex row>
|
||||||
placeholder="Parameter name"
|
<Input
|
||||||
{...register(
|
// important to include key with field's id
|
||||||
`HookParameters.${index}.HookParameter.HookParameterName`
|
placeholder="Parameter name"
|
||||||
|
readOnly={field.$metaData?.required}
|
||||||
|
{...register(
|
||||||
|
`HookParameters.${index}.HookParameter.HookParameterName`
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
css={{ mx: "$2" }}
|
||||||
|
placeholder="Value (hex-quoted)"
|
||||||
|
{...register(
|
||||||
|
`HookParameters.${index}.HookParameter.HookParameterValue`,
|
||||||
|
{ required: field.$metaData?.required }
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
onClick={() => remove(index)}
|
||||||
|
variant="destroy"
|
||||||
|
>
|
||||||
|
<Trash weight="regular" size="16px" />
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
{errors.HookParameters?.[index]?.HookParameter
|
||||||
|
?.HookParameterValue?.type === "required" && (
|
||||||
|
<Text error>This field is required</Text>
|
||||||
)}
|
)}
|
||||||
/>
|
<Label css={{ fontSize: "$sm", mt: "$1" }}>
|
||||||
<Input
|
{capitalize(field.$metaData?.description)}
|
||||||
placeholder="Value (hex-quoted)"
|
</Label>
|
||||||
{...register(
|
</Flex>
|
||||||
`HookParameters.${index}.HookParameter.HookParameterValue`
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Button onClick={() => remove(index)} variant="destroy">
|
|
||||||
<Trash weight="regular" size="16px" />
|
|
||||||
</Button>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
))}
|
))}
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import React, {
|
|||||||
useCallback,
|
useCallback,
|
||||||
} from "react";
|
} from "react";
|
||||||
import type { ReactNode, ReactElement } from "react";
|
import type { ReactNode, ReactElement } from "react";
|
||||||
import { Box, Button, Flex, Input, Label, Stack, Text } from ".";
|
import { Box, Button, Flex, Input, Label, Pre, Stack, Text } from ".";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
@@ -17,6 +17,8 @@ import {
|
|||||||
} from "./Dialog";
|
} from "./Dialog";
|
||||||
import { Plus, X } from "phosphor-react";
|
import { Plus, X } from "phosphor-react";
|
||||||
import { styled } from "../stitches.config";
|
import { styled } from "../stitches.config";
|
||||||
|
import { capitalize } from "../utils/helpers";
|
||||||
|
import ContextMenu, { ContentMenuOption } from "./ContextMenu";
|
||||||
|
|
||||||
const ErrorText = styled(Text, {
|
const ErrorText = styled(Text, {
|
||||||
color: "$error",
|
color: "$error",
|
||||||
@@ -24,12 +26,15 @@ const ErrorText = styled(Text, {
|
|||||||
display: "block",
|
display: "block",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
type Nullable<T> = T | null | undefined | false;
|
||||||
|
|
||||||
interface TabProps {
|
interface TabProps {
|
||||||
header?: string;
|
header: string;
|
||||||
children: ReactNode;
|
children?: ReactNode;
|
||||||
|
renameDisabled?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO customise messages shown
|
// TODO customize messages shown
|
||||||
interface Props {
|
interface Props {
|
||||||
label?: string;
|
label?: string;
|
||||||
activeIndex?: number;
|
activeIndex?: number;
|
||||||
@@ -38,9 +43,14 @@ interface Props {
|
|||||||
children: ReactElement<TabProps>[];
|
children: ReactElement<TabProps>[];
|
||||||
keepAllAlive?: boolean;
|
keepAllAlive?: boolean;
|
||||||
defaultExtension?: string;
|
defaultExtension?: string;
|
||||||
appendDefaultExtension?: boolean;
|
extensionRequired?: boolean;
|
||||||
allowedExtensions?: string[];
|
allowedExtensions?: string[];
|
||||||
|
headerExtraValidation?: {
|
||||||
|
regex: string | RegExp;
|
||||||
|
error: string;
|
||||||
|
};
|
||||||
onCreateNewTab?: (name: string) => any;
|
onCreateNewTab?: (name: string) => any;
|
||||||
|
onRenameTab?: (index: number, nwName: string, oldName?: string) => any;
|
||||||
onCloseTab?: (index: number, header?: string) => any;
|
onCloseTab?: (index: number, header?: string) => any;
|
||||||
onChangeActive?: (index: number, header?: string) => any;
|
onChangeActive?: (index: number, header?: string) => any;
|
||||||
}
|
}
|
||||||
@@ -57,16 +67,19 @@ export const Tabs = ({
|
|||||||
onCreateNewTab,
|
onCreateNewTab,
|
||||||
onCloseTab,
|
onCloseTab,
|
||||||
onChangeActive,
|
onChangeActive,
|
||||||
|
onRenameTab,
|
||||||
|
headerExtraValidation,
|
||||||
|
extensionRequired,
|
||||||
defaultExtension = "",
|
defaultExtension = "",
|
||||||
appendDefaultExtension = false,
|
|
||||||
allowedExtensions,
|
allowedExtensions,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const [active, setActive] = useState(activeIndex || 0);
|
const [active, setActive] = useState(activeIndex || 0);
|
||||||
const tabs: TabProps[] = children.map(elem => elem.props);
|
const tabs: TabProps[] = children.map(elem => elem.props);
|
||||||
|
|
||||||
const [isNewtabDialogOpen, setIsNewtabDialogOpen] = useState(false);
|
const [isNewtabDialogOpen, setIsNewtabDialogOpen] = useState(false);
|
||||||
|
const [renamingTab, setRenamingTab] = useState<number | null>(null);
|
||||||
const [tabname, setTabname] = useState("");
|
const [tabname, setTabname] = useState("");
|
||||||
const [newtabError, setNewtabError] = useState<string | null>(null);
|
const [tabnameError, setTabnameError] = useState<string | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (activeIndex) setActive(activeIndex);
|
if (activeIndex) setActive(activeIndex);
|
||||||
@@ -82,21 +95,45 @@ export const Tabs = ({
|
|||||||
|
|
||||||
// when filename changes, reset error
|
// when filename changes, reset error
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setNewtabError(null);
|
setTabnameError(null);
|
||||||
}, [tabname, setNewtabError]);
|
}, [tabname, setTabnameError]);
|
||||||
|
|
||||||
const validateTabname = useCallback(
|
const validateTabname = useCallback(
|
||||||
(tabname: string): { error: string | null } => {
|
(tabname: string): { error?: string; result?: string } => {
|
||||||
if (tabs.find(tab => tab.header === tabname)) {
|
if (!tabname) {
|
||||||
return { error: "Name already exists." };
|
return { error: `Please enter ${label.toLocaleLowerCase()} name.` };
|
||||||
|
}
|
||||||
|
let ext = (tabname.includes(".") && tabname.split(".").pop()) || "";
|
||||||
|
|
||||||
|
if (!ext && defaultExtension) {
|
||||||
|
ext = defaultExtension;
|
||||||
|
tabname = `${tabname}.${defaultExtension}`;
|
||||||
|
}
|
||||||
|
if (tabs.find(tab => tab.header === tabname)) {
|
||||||
|
return { error: `${capitalize(label)} name already exists.` };
|
||||||
|
}
|
||||||
|
if (extensionRequired && !ext) {
|
||||||
|
return { error: "File extension is required!" };
|
||||||
}
|
}
|
||||||
const ext = tabname.split(".").pop() || "";
|
|
||||||
if (allowedExtensions && !allowedExtensions.includes(ext)) {
|
if (allowedExtensions && !allowedExtensions.includes(ext)) {
|
||||||
return { error: "This file extension is not allowed!" };
|
return { error: "This file extension is not allowed!" };
|
||||||
}
|
}
|
||||||
return { error: null };
|
if (
|
||||||
|
headerExtraValidation &&
|
||||||
|
!tabname.match(headerExtraValidation.regex)
|
||||||
|
) {
|
||||||
|
return { error: headerExtraValidation.error };
|
||||||
|
}
|
||||||
|
return { result: tabname };
|
||||||
},
|
},
|
||||||
[allowedExtensions, tabs]
|
[
|
||||||
|
allowedExtensions,
|
||||||
|
defaultExtension,
|
||||||
|
extensionRequired,
|
||||||
|
headerExtraValidation,
|
||||||
|
label,
|
||||||
|
tabs,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleActiveChange = useCallback(
|
const handleActiveChange = useCallback(
|
||||||
@@ -107,33 +144,50 @@ export const Tabs = ({
|
|||||||
[onChangeActive]
|
[onChangeActive]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleCreateTab = useCallback(() => {
|
const handleRenameTab = useCallback(() => {
|
||||||
// add default extension in case omitted
|
if (renamingTab === null) return;
|
||||||
let _tabname = tabname.includes(".")
|
|
||||||
? tabname
|
|
||||||
: `${tabname}.${defaultExtension}`;
|
|
||||||
if (appendDefaultExtension && !_tabname.endsWith(defaultExtension)) {
|
|
||||||
_tabname = `${_tabname}.${defaultExtension}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const chk = validateTabname(_tabname);
|
const res = validateTabname(tabname);
|
||||||
if (chk.error) {
|
if (res.error) {
|
||||||
setNewtabError(`Error: ${chk.error}`);
|
setTabnameError(`Error: ${res.error}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { result: nwName = tabname } = res;
|
||||||
|
|
||||||
|
setRenamingTab(null);
|
||||||
|
setTabname("");
|
||||||
|
|
||||||
|
const oldName = tabs[renamingTab]?.header;
|
||||||
|
onRenameTab?.(renamingTab, nwName, oldName);
|
||||||
|
|
||||||
|
handleActiveChange(renamingTab, nwName);
|
||||||
|
}, [
|
||||||
|
handleActiveChange,
|
||||||
|
onRenameTab,
|
||||||
|
renamingTab,
|
||||||
|
tabname,
|
||||||
|
tabs,
|
||||||
|
validateTabname,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const handleCreateTab = useCallback(() => {
|
||||||
|
const res = validateTabname(tabname);
|
||||||
|
if (res.error) {
|
||||||
|
setTabnameError(`Error: ${res.error}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { result: _tabname = tabname } = res;
|
||||||
|
|
||||||
setIsNewtabDialogOpen(false);
|
setIsNewtabDialogOpen(false);
|
||||||
setTabname("");
|
setTabname("");
|
||||||
|
|
||||||
onCreateNewTab?.(_tabname);
|
onCreateNewTab?.(_tabname);
|
||||||
|
|
||||||
// switch to new tab?
|
|
||||||
handleActiveChange(tabs.length, _tabname);
|
handleActiveChange(tabs.length, _tabname);
|
||||||
}, [
|
}, [
|
||||||
tabname,
|
|
||||||
defaultExtension,
|
|
||||||
appendDefaultExtension,
|
|
||||||
validateTabname,
|
validateTabname,
|
||||||
|
tabname,
|
||||||
onCreateNewTab,
|
onCreateNewTab,
|
||||||
handleActiveChange,
|
handleActiveChange,
|
||||||
tabs.length,
|
tabs.length,
|
||||||
@@ -141,15 +195,34 @@ export const Tabs = ({
|
|||||||
|
|
||||||
const handleCloseTab = useCallback(
|
const handleCloseTab = useCallback(
|
||||||
(idx: number) => {
|
(idx: number) => {
|
||||||
if (idx <= active && active !== 0) {
|
|
||||||
setActive(active - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
onCloseTab?.(idx, tabs[idx].header);
|
onCloseTab?.(idx, tabs[idx].header);
|
||||||
|
|
||||||
|
if (idx <= active && active !== 0) {
|
||||||
|
const nwActive = active - 1
|
||||||
|
handleActiveChange(nwActive, tabs[nwActive].header);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[active, onCloseTab, tabs]
|
[active, handleActiveChange, onCloseTab, tabs]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const closeOption = (idx: number): Nullable<ContentMenuOption> =>
|
||||||
|
onCloseTab && {
|
||||||
|
type: "text",
|
||||||
|
label: "Close",
|
||||||
|
key: "close",
|
||||||
|
onSelect: () => handleCloseTab(idx),
|
||||||
|
};
|
||||||
|
const renameOption = (idx: number, tab: TabProps): Nullable<ContentMenuOption> => {
|
||||||
|
return (
|
||||||
|
onRenameTab && !tab.renameDisabled && {
|
||||||
|
type: "text",
|
||||||
|
label: "Rename",
|
||||||
|
key: "rename",
|
||||||
|
onSelect: () => setRenamingTab(idx),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!headless && (
|
{!headless && (
|
||||||
@@ -164,46 +237,54 @@ export const Tabs = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{tabs.map((tab, idx) => (
|
{tabs.map((tab, idx) => (
|
||||||
<Button
|
<ContextMenu
|
||||||
key={tab.header}
|
key={tab.header}
|
||||||
role="tab"
|
options={
|
||||||
tabIndex={idx}
|
[closeOption(idx), renameOption(idx, tab)].filter(
|
||||||
onClick={() => handleActiveChange(idx, tab.header)}
|
Boolean
|
||||||
onKeyPress={() => handleActiveChange(idx, tab.header)}
|
) as ContentMenuOption[]
|
||||||
outline={active !== idx}
|
}
|
||||||
size="sm"
|
|
||||||
css={{
|
|
||||||
"&:hover": {
|
|
||||||
span: {
|
|
||||||
visibility: "visible",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{tab.header || idx}
|
<Button
|
||||||
{onCloseTab && (
|
role="tab"
|
||||||
<Box
|
tabIndex={idx}
|
||||||
as="span"
|
onClick={() => handleActiveChange(idx, tab.header)}
|
||||||
css={{
|
onKeyPress={() => handleActiveChange(idx, tab.header)}
|
||||||
display: "flex",
|
outline={active !== idx}
|
||||||
p: "2px",
|
size="sm"
|
||||||
borderRadius: "$full",
|
css={{
|
||||||
mr: "-4px",
|
"&:hover": {
|
||||||
"&:hover": {
|
span: {
|
||||||
// boxSizing: "0px 0px 1px",
|
visibility: "visible",
|
||||||
backgroundColor: "$mauve2",
|
|
||||||
color: "$mauve12",
|
|
||||||
},
|
},
|
||||||
}}
|
},
|
||||||
onClick={(ev: React.MouseEvent<HTMLElement>) => {
|
}}
|
||||||
ev.stopPropagation();
|
>
|
||||||
handleCloseTab(idx);
|
{tab.header || idx}
|
||||||
}}
|
{onCloseTab && (
|
||||||
>
|
<Box
|
||||||
<X size="9px" weight="bold" />
|
as="span"
|
||||||
</Box>
|
css={{
|
||||||
)}
|
display: "flex",
|
||||||
</Button>
|
p: "2px",
|
||||||
|
borderRadius: "$full",
|
||||||
|
mr: "-4px",
|
||||||
|
"&:hover": {
|
||||||
|
// boxSizing: "0px 0px 1px",
|
||||||
|
backgroundColor: "$mauve2",
|
||||||
|
color: "$mauve12",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
onClick={(ev: React.MouseEvent<HTMLElement>) => {
|
||||||
|
ev.stopPropagation();
|
||||||
|
handleCloseTab(idx);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<X size="9px" weight="bold" />
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
</ContextMenu>
|
||||||
))}
|
))}
|
||||||
{onCreateNewTab && (
|
{onCreateNewTab && (
|
||||||
<Dialog
|
<Dialog
|
||||||
@@ -216,11 +297,14 @@ export const Tabs = ({
|
|||||||
size="sm"
|
size="sm"
|
||||||
css={{ alignItems: "center", px: "$2", mr: "$3" }}
|
css={{ alignItems: "center", px: "$2", mr: "$3" }}
|
||||||
>
|
>
|
||||||
<Plus size="16px" /> {tabs.length === 0 && `Add new ${label.toLocaleLowerCase()}`}
|
<Plus size="16px" />{" "}
|
||||||
|
{tabs.length === 0 && `Add new ${label.toLocaleLowerCase()}`}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogTitle>Create new {label.toLocaleLowerCase()}</DialogTitle>
|
<DialogTitle>
|
||||||
|
Create new {label.toLocaleLowerCase()}
|
||||||
|
</DialogTitle>
|
||||||
<DialogDescription>
|
<DialogDescription>
|
||||||
<Label>{label} name</Label>
|
<Label>{label} name</Label>
|
||||||
<Input
|
<Input
|
||||||
@@ -232,7 +316,7 @@ export const Tabs = ({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<ErrorText>{newtabError}</ErrorText>
|
<ErrorText>{tabnameError}</ErrorText>
|
||||||
</DialogDescription>
|
</DialogDescription>
|
||||||
|
|
||||||
<Flex
|
<Flex
|
||||||
@@ -257,31 +341,79 @@ export const Tabs = ({
|
|||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)}
|
)}
|
||||||
|
{onRenameTab && (
|
||||||
|
<Dialog
|
||||||
|
open={renamingTab !== null}
|
||||||
|
onOpenChange={() => setRenamingTab(null)}
|
||||||
|
>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogTitle>
|
||||||
|
Rename <Pre>{tabs[renamingTab || 0]?.header}</Pre>
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
<Label>Enter new name</Label>
|
||||||
|
<Input
|
||||||
|
value={tabname}
|
||||||
|
onChange={e => setTabname(e.target.value)}
|
||||||
|
onKeyPress={e => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
handleRenameTab();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ErrorText>{tabnameError}</ErrorText>
|
||||||
|
</DialogDescription>
|
||||||
|
|
||||||
|
<Flex
|
||||||
|
css={{
|
||||||
|
marginTop: 25,
|
||||||
|
justifyContent: "flex-end",
|
||||||
|
gap: "$3",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DialogClose asChild>
|
||||||
|
<Button outline>Cancel</Button>
|
||||||
|
</DialogClose>
|
||||||
|
<Button variant="primary" onClick={handleRenameTab}>
|
||||||
|
Confirm
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
<DialogClose asChild>
|
||||||
|
<Box css={{ position: "absolute", top: "$3", right: "$3" }}>
|
||||||
|
<X size="20px" />
|
||||||
|
</Box>
|
||||||
|
</DialogClose>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
{keepAllAlive ? (
|
{keepAllAlive
|
||||||
tabs.map((tab, idx) => {
|
? tabs.map((tab, idx) => {
|
||||||
// TODO Maybe rule out fragments as children
|
// TODO Maybe rule out fragments as children
|
||||||
if (!isValidElement(tab.children)) {
|
if (!isValidElement(tab.children)) {
|
||||||
if (active !== idx) return null;
|
if (active !== idx) return null;
|
||||||
return tab.children;
|
return tab.children;
|
||||||
}
|
}
|
||||||
let key = tab.children.key || tab.header || idx;
|
let key = tab.children.key || tab.header || idx;
|
||||||
let { children } = tab;
|
let { children } = tab;
|
||||||
let { style, ...props } = children.props;
|
let { style, ...props } = children.props;
|
||||||
return (
|
return (
|
||||||
<children.type
|
<children.type
|
||||||
key={key}
|
key={key}
|
||||||
{...props}
|
{...props}
|
||||||
style={{ ...style, display: active !== idx ? "none" : undefined }}
|
style={{
|
||||||
/>
|
...style,
|
||||||
);
|
display: active !== idx ? "none" : undefined,
|
||||||
})
|
}}
|
||||||
) : (
|
/>
|
||||||
<Fragment key={tabs[active].header || active}>
|
);
|
||||||
{tabs[active].children}
|
})
|
||||||
</Fragment>
|
: tabs[active] && (
|
||||||
)}
|
<Fragment key={tabs[active].header || active}>
|
||||||
|
{tabs[active].children}
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import { Play } from "phosphor-react";
|
import { Play } from "phosphor-react";
|
||||||
import { FC, useCallback, useEffect, useMemo } from "react";
|
import { FC, useCallback, useEffect } from "react";
|
||||||
import { useSnapshot } from "valtio";
|
import { useSnapshot } from "valtio";
|
||||||
import state from "../../state";
|
import state from "../../state";
|
||||||
import {
|
import {
|
||||||
modifyTransaction,
|
defaultTransactionType,
|
||||||
|
getTxFields,
|
||||||
|
modifyTxState,
|
||||||
prepareState,
|
prepareState,
|
||||||
prepareTransaction,
|
prepareTransaction,
|
||||||
|
SelectOption,
|
||||||
TransactionState,
|
TransactionState,
|
||||||
} from "../../state/transactions";
|
} from "../../state/transactions";
|
||||||
import { sendTransaction } from "../../state/actions";
|
import { sendTransaction } from "../../state/actions";
|
||||||
@@ -15,7 +18,7 @@ import Flex from "../Flex";
|
|||||||
import { TxJson } from "./json";
|
import { TxJson } from "./json";
|
||||||
import { TxUI } from "./ui";
|
import { TxUI } from "./ui";
|
||||||
import { default as _estimateFee } from "../../utils/estimateFee";
|
import { default as _estimateFee } from "../../utils/estimateFee";
|
||||||
import toast from 'react-hot-toast';
|
import toast from "react-hot-toast";
|
||||||
|
|
||||||
export interface TransactionProps {
|
export interface TransactionProps {
|
||||||
header: string;
|
header: string;
|
||||||
@@ -34,19 +37,18 @@ const Transaction: FC<TransactionProps> = ({
|
|||||||
txIsDisabled,
|
txIsDisabled,
|
||||||
txIsLoading,
|
txIsLoading,
|
||||||
viewType,
|
viewType,
|
||||||
editorSavedValue,
|
|
||||||
editorValue,
|
editorValue,
|
||||||
} = txState;
|
} = txState;
|
||||||
|
|
||||||
const setState = useCallback(
|
const setState = useCallback(
|
||||||
(pTx?: Partial<TransactionState>) => {
|
(pTx?: Partial<TransactionState>) => {
|
||||||
return modifyTransaction(header, pTx);
|
return modifyTxState(header, pTx);
|
||||||
},
|
},
|
||||||
[header]
|
[header]
|
||||||
);
|
);
|
||||||
|
|
||||||
const prepareOptions = useCallback(
|
const prepareOptions = useCallback(
|
||||||
(state: TransactionState = txState) => {
|
(state: Partial<TransactionState> = txState) => {
|
||||||
const {
|
const {
|
||||||
selectedTransaction,
|
selectedTransaction,
|
||||||
selectedDestAccount,
|
selectedDestAccount,
|
||||||
@@ -55,9 +57,7 @@ const Transaction: FC<TransactionProps> = ({
|
|||||||
} = state;
|
} = state;
|
||||||
|
|
||||||
const TransactionType = selectedTransaction?.value || null;
|
const TransactionType = selectedTransaction?.value || null;
|
||||||
const Destination =
|
const Destination = selectedDestAccount?.value || txFields?.Destination;
|
||||||
selectedDestAccount?.value ||
|
|
||||||
("Destination" in txFields ? null : undefined);
|
|
||||||
const Account = selectedAccount?.value || null;
|
const Account = selectedAccount?.value || null;
|
||||||
|
|
||||||
return prepareTransaction({
|
return prepareTransaction({
|
||||||
@@ -109,8 +109,9 @@ const Transaction: FC<TransactionProps> = ({
|
|||||||
}
|
}
|
||||||
const options = prepareOptions(st);
|
const options = prepareOptions(st);
|
||||||
|
|
||||||
if (options.Destination === null) {
|
const fields = getTxFields(options.TransactionType);
|
||||||
throw Error("Destination account cannot be null");
|
if (fields.Destination && !options.Destination) {
|
||||||
|
throw Error("Destination account is required!");
|
||||||
}
|
}
|
||||||
|
|
||||||
await sendTransaction(account, options, { logPrefix });
|
await sendTransaction(account, options, { logPrefix });
|
||||||
@@ -136,15 +137,38 @@ const Transaction: FC<TransactionProps> = ({
|
|||||||
prepareOptions,
|
prepareOptions,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const resetState = useCallback(() => {
|
const getJsonString = useCallback(
|
||||||
modifyTransaction(header, { viewType }, { replaceState: true });
|
(state?: Partial<TransactionState>) =>
|
||||||
}, [header, viewType]);
|
JSON.stringify(
|
||||||
|
prepareOptions?.(state) || {},
|
||||||
|
null,
|
||||||
|
editorSettings.tabSize
|
||||||
|
),
|
||||||
|
[editorSettings.tabSize, prepareOptions]
|
||||||
|
);
|
||||||
|
|
||||||
const jsonValue = useMemo(
|
const resetState = useCallback(
|
||||||
() =>
|
(transactionType: SelectOption | undefined = defaultTransactionType) => {
|
||||||
editorSavedValue ||
|
const fields = getTxFields(transactionType?.value);
|
||||||
JSON.stringify(prepareOptions?.() || {}, null, editorSettings.tabSize),
|
|
||||||
[editorSavedValue, editorSettings.tabSize, prepareOptions]
|
const nwState: Partial<TransactionState> = {
|
||||||
|
viewType,
|
||||||
|
selectedTransaction: transactionType,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (fields.Destination !== undefined) {
|
||||||
|
nwState.selectedDestAccount = null;
|
||||||
|
fields.Destination = "";
|
||||||
|
} else {
|
||||||
|
fields.Destination = undefined;
|
||||||
|
}
|
||||||
|
nwState.txFields = fields;
|
||||||
|
|
||||||
|
const state = modifyTxState(header, nwState, { replaceState: true });
|
||||||
|
const editorValue = getJsonString(state);
|
||||||
|
return setState({ editorValue });
|
||||||
|
},
|
||||||
|
[getJsonString, header, setState, viewType]
|
||||||
);
|
);
|
||||||
|
|
||||||
const estimateFee = useCallback(
|
const estimateFee = useCallback(
|
||||||
@@ -156,10 +180,10 @@ const Transaction: FC<TransactionProps> = ({
|
|||||||
);
|
);
|
||||||
if (!account) {
|
if (!account) {
|
||||||
if (!opts?.silent) {
|
if (!opts?.silent) {
|
||||||
toast.error("Please select account from the list.")
|
toast.error("Please select account from the list.");
|
||||||
}
|
}
|
||||||
return
|
return;
|
||||||
};
|
}
|
||||||
|
|
||||||
ptx.Account = account.address;
|
ptx.Account = account.address;
|
||||||
ptx.Sequence = account.sequence;
|
ptx.Sequence = account.sequence;
|
||||||
@@ -176,7 +200,7 @@ const Transaction: FC<TransactionProps> = ({
|
|||||||
<Box css={{ position: "relative", height: "calc(100% - 28px)" }} {...props}>
|
<Box css={{ position: "relative", height: "calc(100% - 28px)" }} {...props}>
|
||||||
{viewType === "json" ? (
|
{viewType === "json" ? (
|
||||||
<TxJson
|
<TxJson
|
||||||
value={jsonValue}
|
getJsonString={getJsonString}
|
||||||
header={header}
|
header={header}
|
||||||
state={txState}
|
state={txState}
|
||||||
setState={setState}
|
setState={setState}
|
||||||
@@ -199,7 +223,7 @@ const Transaction: FC<TransactionProps> = ({
|
|||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (viewType === "ui") {
|
if (viewType === "ui") {
|
||||||
setState({ editorSavedValue: null, viewType: "json" });
|
setState({ viewType: "json" });
|
||||||
} else setState({ viewType: "ui" });
|
} else setState({ viewType: "ui" });
|
||||||
}}
|
}}
|
||||||
outline
|
outline
|
||||||
@@ -207,7 +231,7 @@ const Transaction: FC<TransactionProps> = ({
|
|||||||
{viewType === "ui" ? "EDIT AS JSON" : "EXIT JSON MODE"}
|
{viewType === "ui" ? "EDIT AS JSON" : "EXIT JSON MODE"}
|
||||||
</Button>
|
</Button>
|
||||||
<Flex row>
|
<Flex row>
|
||||||
<Button onClick={resetState} outline css={{ mr: "$3" }}>
|
<Button onClick={() => resetState()} outline css={{ mr: "$3" }}>
|
||||||
RESET
|
RESET
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { FC, useCallback, useEffect, useState } from "react";
|
import { FC, useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { useSnapshot } from "valtio";
|
import { useSnapshot } from "valtio";
|
||||||
import state, {
|
import state, {
|
||||||
prepareState,
|
prepareState,
|
||||||
@@ -15,7 +15,7 @@ import Monaco from "../Monaco";
|
|||||||
import type monaco from "monaco-editor";
|
import type monaco from "monaco-editor";
|
||||||
|
|
||||||
interface JsonProps {
|
interface JsonProps {
|
||||||
value?: string;
|
getJsonString?: (state?: Partial<TransactionState>) => string;
|
||||||
header?: string;
|
header?: string;
|
||||||
setState: (pTx?: Partial<TransactionState> | undefined) => void;
|
setState: (pTx?: Partial<TransactionState> | undefined) => void;
|
||||||
state: TransactionState;
|
state: TransactionState;
|
||||||
@@ -23,22 +23,23 @@ interface JsonProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const TxJson: FC<JsonProps> = ({
|
export const TxJson: FC<JsonProps> = ({
|
||||||
value = "",
|
getJsonString,
|
||||||
state: txState,
|
state: txState,
|
||||||
header,
|
header,
|
||||||
setState,
|
setState,
|
||||||
}) => {
|
}) => {
|
||||||
const { editorSettings, accounts } = useSnapshot(state);
|
const { editorSettings, accounts } = useSnapshot(state);
|
||||||
const { editorValue = value, estimatedFee } = txState;
|
const { editorValue, estimatedFee } = txState;
|
||||||
const [hasUnsaved, setHasUnsaved] = useState(false);
|
|
||||||
const [currTxType, setCurrTxType] = useState<string | undefined>(
|
const [currTxType, setCurrTxType] = useState<string | undefined>(
|
||||||
txState.selectedTransaction?.value
|
txState.selectedTransaction?.value
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setState({ editorValue: value });
|
setState({
|
||||||
|
editorValue: getJsonString?.(),
|
||||||
|
});
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [value]);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const parsed = parseJSON(editorValue);
|
const parsed = parseJSON(editorValue);
|
||||||
@@ -52,21 +53,22 @@ export const TxJson: FC<JsonProps> = ({
|
|||||||
}
|
}
|
||||||
}, [editorValue]);
|
}, [editorValue]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (editorValue === value) setHasUnsaved(false);
|
|
||||||
else setHasUnsaved(true);
|
|
||||||
}, [editorValue, value]);
|
|
||||||
|
|
||||||
const saveState = (value: string, transactionType?: string) => {
|
const saveState = (value: string, transactionType?: string) => {
|
||||||
const tx = prepareState(value, transactionType);
|
const tx = prepareState(value, transactionType);
|
||||||
if (tx) setState(tx);
|
if (tx) {
|
||||||
|
setState(tx);
|
||||||
|
setState({
|
||||||
|
editorValue: getJsonString?.(tx),
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const discardChanges = () => {
|
const discardChanges = () => {
|
||||||
showAlert("Confirm", {
|
showAlert("Confirm", {
|
||||||
body: "Are you sure to discard these changes?",
|
body: "Are you sure to discard these changes?",
|
||||||
confirmText: "Yes",
|
confirmText: "Yes",
|
||||||
onConfirm: () => setState({ editorValue: value }),
|
onCancel: () => {},
|
||||||
|
onConfirm: () => setState({ editorValue: getJsonString?.() }),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -79,8 +81,8 @@ export const TxJson: FC<JsonProps> = ({
|
|||||||
showAlert("Error!", {
|
showAlert("Error!", {
|
||||||
body: `Malformed Transaction in ${header}, would you like to discard these changes?`,
|
body: `Malformed Transaction in ${header}, would you like to discard these changes?`,
|
||||||
confirmText: "Discard",
|
confirmText: "Discard",
|
||||||
onConfirm: () => setState({ editorValue: value }),
|
onConfirm: () => setState({ editorValue: getJsonString?.() }),
|
||||||
onCancel: () => setState({ viewType: "json", editorSavedValue: value }),
|
onCancel: () => setState({ viewType: "json" }),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -174,6 +176,11 @@ export const TxJson: FC<JsonProps> = ({
|
|||||||
});
|
});
|
||||||
}, [getSchemas, monacoInst]);
|
}, [getSchemas, monacoInst]);
|
||||||
|
|
||||||
|
const hasUnsaved = useMemo(
|
||||||
|
() => editorValue !== getJsonString?.(),
|
||||||
|
[editorValue, getJsonString]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Monaco
|
<Monaco
|
||||||
rootProps={{
|
rootProps={{
|
||||||
@@ -203,14 +210,14 @@ export const TxJson: FC<JsonProps> = ({
|
|||||||
<Flex
|
<Flex
|
||||||
row
|
row
|
||||||
align="center"
|
align="center"
|
||||||
css={{ fontSize: "$xs", color: "$textMuted", ml: 'auto' }}
|
css={{ fontSize: "$xs", color: "$textMuted", ml: "auto" }}
|
||||||
>
|
>
|
||||||
<Text muted small>
|
<Text muted small>
|
||||||
This file has unsaved changes.
|
This file has unsaved changes.
|
||||||
</Text>
|
</Text>
|
||||||
<Link
|
<Link
|
||||||
css={{ ml: "$1" }}
|
css={{ ml: "$1" }}
|
||||||
onClick={() => saveState(editorValue, currTxType)}
|
onClick={() => saveState(editorValue || "", currTxType)}
|
||||||
>
|
>
|
||||||
save
|
save
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { FC, useCallback, useEffect, useState } from "react";
|
import { FC, useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import Container from "../Container";
|
import Container from "../Container";
|
||||||
import Flex from "../Flex";
|
import Flex from "../Flex";
|
||||||
import Input from "../Input";
|
import Input from "../Input";
|
||||||
@@ -7,9 +7,10 @@ import Text from "../Text";
|
|||||||
import {
|
import {
|
||||||
SelectOption,
|
SelectOption,
|
||||||
TransactionState,
|
TransactionState,
|
||||||
transactionsData,
|
transactionsOptions,
|
||||||
TxFields,
|
TxFields,
|
||||||
getTxFields,
|
getTxFields,
|
||||||
|
defaultTransactionType,
|
||||||
} from "../../state/transactions";
|
} from "../../state/transactions";
|
||||||
import { useSnapshot } from "valtio";
|
import { useSnapshot } from "valtio";
|
||||||
import state from "../../state";
|
import state from "../../state";
|
||||||
@@ -38,12 +39,6 @@ export const TxUI: FC<UIProps> = ({
|
|||||||
txFields,
|
txFields,
|
||||||
} = txState;
|
} = txState;
|
||||||
|
|
||||||
|
|
||||||
const transactionsOptions = transactionsData.map(tx => ({
|
|
||||||
value: tx.TransactionType,
|
|
||||||
label: tx.TransactionType,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const accountOptions: SelectOption[] = accounts.map(acc => ({
|
const accountOptions: SelectOption[] = accounts.map(acc => ({
|
||||||
label: acc.name,
|
label: acc.name,
|
||||||
value: acc.address,
|
value: acc.address,
|
||||||
@@ -58,10 +53,16 @@ export const TxUI: FC<UIProps> = ({
|
|||||||
|
|
||||||
const [feeLoading, setFeeLoading] = useState(false);
|
const [feeLoading, setFeeLoading] = useState(false);
|
||||||
|
|
||||||
const resetOptions = useCallback(
|
const resetFields = useCallback(
|
||||||
(tt: string) => {
|
(tt: string) => {
|
||||||
const fields = getTxFields(tt);
|
const fields = getTxFields(tt);
|
||||||
if (!fields.Destination) setState({ selectedDestAccount: null });
|
|
||||||
|
if (fields.Destination !== undefined) {
|
||||||
|
setState({ selectedDestAccount: null });
|
||||||
|
fields.Destination = "";
|
||||||
|
} else {
|
||||||
|
fields.Destination = undefined;
|
||||||
|
}
|
||||||
return setState({ txFields: fields });
|
return setState({ txFields: fields });
|
||||||
},
|
},
|
||||||
[setState]
|
[setState]
|
||||||
@@ -102,33 +103,37 @@ export const TxUI: FC<UIProps> = ({
|
|||||||
(tt: SelectOption) => {
|
(tt: SelectOption) => {
|
||||||
setState({ selectedTransaction: tt });
|
setState({ selectedTransaction: tt });
|
||||||
|
|
||||||
const newState = resetOptions(tt.value);
|
const newState = resetFields(tt.value);
|
||||||
|
|
||||||
handleEstimateFee(newState, true);
|
handleEstimateFee(newState, true);
|
||||||
},
|
},
|
||||||
[handleEstimateFee, resetOptions, setState]
|
[handleEstimateFee, resetFields, setState]
|
||||||
);
|
);
|
||||||
|
|
||||||
const specialFields = ["TransactionType", "Account", "Destination"];
|
const switchToJson = () => setState({ viewType: "json" });
|
||||||
|
|
||||||
const otherFields = Object.keys(txFields).filter(
|
|
||||||
k => !specialFields.includes(k)
|
|
||||||
) as [keyof TxFields];
|
|
||||||
|
|
||||||
const switchToJson = () =>
|
|
||||||
setState({ editorSavedValue: null, viewType: "json" });
|
|
||||||
|
|
||||||
// default tx
|
// default tx
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedTransaction?.value) return;
|
if (selectedTransaction?.value) return;
|
||||||
|
|
||||||
const defaultOption = transactionsOptions.find(
|
if (defaultTransactionType) {
|
||||||
tt => tt.value === "Payment"
|
handleChangeTxType(defaultTransactionType);
|
||||||
);
|
|
||||||
if (defaultOption) {
|
|
||||||
handleChangeTxType(defaultOption);
|
|
||||||
}
|
}
|
||||||
}, [handleChangeTxType, selectedTransaction?.value, transactionsOptions]);
|
}, [handleChangeTxType, selectedTransaction?.value]);
|
||||||
|
|
||||||
|
const fields = useMemo(
|
||||||
|
() => getTxFields(selectedTransaction?.value),
|
||||||
|
[selectedTransaction?.value]
|
||||||
|
);
|
||||||
|
|
||||||
|
const specialFields = ["TransactionType", "Account"];
|
||||||
|
if (fields.Destination !== undefined) {
|
||||||
|
specialFields.push("Destination");
|
||||||
|
}
|
||||||
|
|
||||||
|
const otherFields = Object.keys(txFields).filter(
|
||||||
|
k => !specialFields.includes(k)
|
||||||
|
) as [keyof TxFields];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container
|
||||||
@@ -185,7 +190,7 @@ export const TxUI: FC<UIProps> = ({
|
|||||||
onChange={(acc: any) => handleSetAccount(acc)} // TODO make react-select have correct types for acc
|
onChange={(acc: any) => handleSetAccount(acc)} // TODO make react-select have correct types for acc
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
{txFields.Destination !== undefined && (
|
{fields.Destination !== undefined && (
|
||||||
<Flex
|
<Flex
|
||||||
row
|
row
|
||||||
fluid
|
fluid
|
||||||
|
|||||||
@@ -40,9 +40,9 @@
|
|||||||
{
|
{
|
||||||
"label": "Token",
|
"label": "Token",
|
||||||
"body": {
|
"body": {
|
||||||
"currency": "${1:13.1}",
|
"currency": "${1:USD}",
|
||||||
"value": "${2:FOO}",
|
"value": "${2:100}",
|
||||||
"description": "${3:rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpns}"
|
"issuer": "${3:rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpns}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -55,7 +55,8 @@
|
|||||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||||
"TransactionType": "EscrowCancel",
|
"TransactionType": "EscrowCancel",
|
||||||
"Owner": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
"Owner": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||||
"OfferSequence": 7
|
"OfferSequence": 7,
|
||||||
|
"Fee": "10"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||||
@@ -69,7 +70,8 @@
|
|||||||
"FinishAfter": 533171558,
|
"FinishAfter": 533171558,
|
||||||
"Condition": "A0258020E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855810100",
|
"Condition": "A0258020E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855810100",
|
||||||
"DestinationTag": 23480,
|
"DestinationTag": 23480,
|
||||||
"SourceTag": 11747
|
"SourceTag": 11747,
|
||||||
|
"Fee": "10"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||||
@@ -77,32 +79,50 @@
|
|||||||
"Owner": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
"Owner": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||||
"OfferSequence": 7,
|
"OfferSequence": 7,
|
||||||
"Condition": "A0258020E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855810100",
|
"Condition": "A0258020E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855810100",
|
||||||
"Fulfillment": "A0028000"
|
"Fulfillment": "A0028000",
|
||||||
|
"Fee": "10"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"TransactionType": "NFTokenMint",
|
||||||
|
"Account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
||||||
|
"Fee": "10",
|
||||||
|
"NFTokenTaxon": 0,
|
||||||
|
"URI": "697066733A2F2F516D614374444B5A4656767666756676626479346573745A626851483744586831364354707631686F776D424779"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"TransactionType": "NFTokenBurn",
|
"TransactionType": "NFTokenBurn",
|
||||||
"Account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
"Account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
||||||
"Fee": "10",
|
"Fee": "10",
|
||||||
"TokenID": "000B013A95F14B0044F78A264E41713C64B5F89242540EE208C3098E00000D65"
|
"NFTokenID": "000B013A95F14B0044F78A264E41713C64B5F89242540EE208C3098E00000D65"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"TransactionType": "NFTokenAcceptOffer",
|
"TransactionType": "NFTokenAcceptOffer",
|
||||||
"Fee": "10"
|
"Account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
||||||
|
"Fee": "10",
|
||||||
|
"NFTokenSellOffer": "A2FA1A9911FE2AEF83DAB05F437768E26A301EF899BD31EB85E704B3D528FF18",
|
||||||
|
"NFTokenBuyOffer": "4AAAEEA76E3C8148473CB3840CE637676E561FB02BD4CA22CA59729EA815B862",
|
||||||
|
"NFTokenBrokerFee": "10"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"TransactionType": "NFTokenCancelOffer",
|
"TransactionType": "NFTokenCancelOffer",
|
||||||
"Account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
|
"Account": "ra5nK24KXen9AHvsdFTKHSANinZseWnPcX",
|
||||||
"TokenIDs": "000100001E962F495F07A990F4ED55ACCFEEF365DBAA76B6A048C0A200000007"
|
"Fee": "10",
|
||||||
|
"NFTokenOffers": {
|
||||||
|
"$type": "json",
|
||||||
|
"$value": ["4AAAEEA76E3C8148473CB3840CE637676E561FB02BD4CA22CA59729EA815B862"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"TransactionType": "NFTokenCreateOffer",
|
"TransactionType": "NFTokenCreateOffer",
|
||||||
"Account": "rs8jBmmfpwgmrSPgwMsh7CvKRmRt1JTVSX",
|
"Account": "rs8jBmmfpwgmrSPgwMsh7CvKRmRt1JTVSX",
|
||||||
"TokenID": "000100001E962F495F07A990F4ED55ACCFEEF365DBAA76B6A048C0A200000007",
|
"NFTokenID": "000100001E962F495F07A990F4ED55ACCFEEF365DBAA76B6A048C0A200000007",
|
||||||
"Amount": {
|
"Amount": {
|
||||||
"$value": "100",
|
"$value": "100",
|
||||||
"$type": "xrp"
|
"$type": "xrp"
|
||||||
},
|
},
|
||||||
"Flags": 1
|
"Flags": 1,
|
||||||
|
"Destination": "",
|
||||||
|
"Fee": "10"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"TransactionType": "OfferCancel",
|
"TransactionType": "OfferCancel",
|
||||||
@@ -150,7 +170,8 @@
|
|||||||
"PublicKey": "32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A",
|
"PublicKey": "32D2471DB72B27E3310F355BB33E339BF26F8392D5A93D3BC0FC3B566612DA0F0A",
|
||||||
"CancelAfter": 533171558,
|
"CancelAfter": 533171558,
|
||||||
"DestinationTag": 23480,
|
"DestinationTag": 23480,
|
||||||
"SourceTag": 11747
|
"SourceTag": 11747,
|
||||||
|
"Fee": "10"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
|
||||||
@@ -160,7 +181,8 @@
|
|||||||
"$value": "200",
|
"$value": "200",
|
||||||
"$type": "xrp"
|
"$type": "xrp"
|
||||||
},
|
},
|
||||||
"Expiration": 543171558
|
"Expiration": 543171558,
|
||||||
|
"Fee": "10"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Flags": 0,
|
"Flags": 0,
|
||||||
@@ -212,9 +234,13 @@
|
|||||||
"Fee": "12",
|
"Fee": "12",
|
||||||
"Flags": 262144,
|
"Flags": 262144,
|
||||||
"LastLedgerSequence": 8007750,
|
"LastLedgerSequence": 8007750,
|
||||||
"Amount": {
|
"LimitAmount": {
|
||||||
"$value": "100",
|
"$type": "json",
|
||||||
"$type": "xrp"
|
"$value": {
|
||||||
|
"currency": "USD",
|
||||||
|
"issuer": "rsP3mgGb2tcYUrxiLFiHJiQXhsziegtwBc",
|
||||||
|
"value": "100"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Sequence": 12
|
"Sequence": 12
|
||||||
}
|
}
|
||||||
|
|||||||
11
package.json
11
package.json
@@ -16,8 +16,9 @@
|
|||||||
"@octokit/core": "^3.5.1",
|
"@octokit/core": "^3.5.1",
|
||||||
"@radix-ui/colors": "^0.1.7",
|
"@radix-ui/colors": "^0.1.7",
|
||||||
"@radix-ui/react-alert-dialog": "^0.1.1",
|
"@radix-ui/react-alert-dialog": "^0.1.1",
|
||||||
|
"@radix-ui/react-context-menu": "^0.1.6",
|
||||||
"@radix-ui/react-dialog": "^0.1.1",
|
"@radix-ui/react-dialog": "^0.1.1",
|
||||||
"@radix-ui/react-dropdown-menu": "^0.1.1",
|
"@radix-ui/react-dropdown-menu": "^0.1.6",
|
||||||
"@radix-ui/react-id": "^0.1.1",
|
"@radix-ui/react-id": "^0.1.1",
|
||||||
"@radix-ui/react-label": "^0.1.5",
|
"@radix-ui/react-label": "^0.1.5",
|
||||||
"@radix-ui/react-popover": "^0.1.6",
|
"@radix-ui/react-popover": "^0.1.6",
|
||||||
@@ -35,7 +36,7 @@
|
|||||||
"lodash.xor": "^4.5.0",
|
"lodash.xor": "^4.5.0",
|
||||||
"monaco-editor": "^0.33.0",
|
"monaco-editor": "^0.33.0",
|
||||||
"next": "^12.0.4",
|
"next": "^12.0.4",
|
||||||
"next-auth": "^4.0.0-beta.5",
|
"next-auth": "^4.10.3",
|
||||||
"next-plausible": "^3.2.0",
|
"next-plausible": "^3.2.0",
|
||||||
"next-themes": "^0.1.1",
|
"next-themes": "^0.1.1",
|
||||||
"normalize-url": "^7.0.2",
|
"normalize-url": "^7.0.2",
|
||||||
@@ -50,6 +51,7 @@
|
|||||||
"react-hook-form": "^7.28.0",
|
"react-hook-form": "^7.28.0",
|
||||||
"react-hot-keys": "^2.7.1",
|
"react-hot-keys": "^2.7.1",
|
||||||
"react-hot-toast": "^2.1.1",
|
"react-hot-toast": "^2.1.1",
|
||||||
|
"react-markdown": "^8.0.3",
|
||||||
"react-new-window": "^0.2.1",
|
"react-new-window": "^0.2.1",
|
||||||
"react-select": "^5.2.1",
|
"react-select": "^5.2.1",
|
||||||
"react-split": "^2.0.14",
|
"react-split": "^2.0.14",
|
||||||
@@ -61,7 +63,7 @@
|
|||||||
"vscode-languageserver": "^7.0.0",
|
"vscode-languageserver": "^7.0.0",
|
||||||
"vscode-uri": "^3.0.2",
|
"vscode-uri": "^3.0.2",
|
||||||
"wabt": "1.0.16",
|
"wabt": "1.0.16",
|
||||||
"xrpl-accountlib": "^1.3.2",
|
"xrpl-accountlib": "^1.5.2",
|
||||||
"xrpl-client": "^1.9.4"
|
"xrpl-client": "^1.9.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -75,5 +77,8 @@
|
|||||||
"eslint-config-next": "11.1.2",
|
"eslint-config-next": "11.1.2",
|
||||||
"raw-loader": "^4.0.2",
|
"raw-loader": "^4.0.2",
|
||||||
"typescript": "4.4.4"
|
"typescript": "4.4.4"
|
||||||
|
},
|
||||||
|
"resolutions": {
|
||||||
|
"ripple-binary-codec": "=1.4.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import Split from "react-split";
|
|||||||
import { useSnapshot } from "valtio";
|
import { useSnapshot } from "valtio";
|
||||||
import { Box, Container, Flex, Tab, Tabs } from "../../components";
|
import { Box, Container, Flex, Tab, Tabs } from "../../components";
|
||||||
import Transaction from "../../components/Transaction";
|
import Transaction from "../../components/Transaction";
|
||||||
import state from "../../state";
|
import state, { renameTxState } from "../../state";
|
||||||
import { getSplit, saveSplit } from "../../state/actions/persistSplits";
|
import { getSplit, saveSplit } from "../../state/actions/persistSplits";
|
||||||
import { transactionsState, modifyTransaction } from "../../state";
|
import { transactionsState, modifyTxState } from "../../state";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { FileJs } from "phosphor-react";
|
import { FileJs } from "phosphor-react";
|
||||||
import RunScript from '../../components/RunScript';
|
import RunScript from "../../components/RunScript";
|
||||||
|
|
||||||
const DebugStream = dynamic(() => import("../../components/DebugStream"), {
|
const DebugStream = dynamic(() => import("../../components/DebugStream"), {
|
||||||
ssr: false,
|
ssr: false,
|
||||||
@@ -96,9 +96,12 @@ const Test = () => {
|
|||||||
keepAllAlive
|
keepAllAlive
|
||||||
defaultExtension="json"
|
defaultExtension="json"
|
||||||
allowedExtensions={["json"]}
|
allowedExtensions={["json"]}
|
||||||
onCreateNewTab={header => modifyTransaction(header, {})}
|
onCreateNewTab={header => modifyTxState(header, {})}
|
||||||
|
onRenameTab={(idx, nwName, oldName = "") =>
|
||||||
|
renameTxState(oldName, nwName)
|
||||||
|
}
|
||||||
onCloseTab={(idx, header) =>
|
onCloseTab={(idx, header) =>
|
||||||
header && modifyTransaction(header, undefined)
|
header && modifyTxState(header, undefined)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{transactions.map(({ header, state }) => (
|
{transactions.map(({ header, state }) => (
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -28,40 +28,34 @@ export const names = [
|
|||||||
* is protected with CORS so that's why we did our own endpoint
|
* is protected with CORS so that's why we did our own endpoint
|
||||||
*/
|
*/
|
||||||
export const addFaucetAccount = async (name?: string, showToast: boolean = false) => {
|
export const addFaucetAccount = async (name?: string, showToast: boolean = false) => {
|
||||||
// Lets limit the number of faucet accounts to 5 for now
|
if (typeof window === undefined) return
|
||||||
if (state.accounts.length > 5) {
|
|
||||||
return toast.error("You can only have maximum 6 accounts");
|
|
||||||
}
|
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
|
|
||||||
|
const toastId = showToast ? toast.loading("Creating account") : "";
|
||||||
const toastId = showToast ? toast.loading("Creating account") : "";
|
const res = await fetch(`${window.location.origin}/api/faucet`, {
|
||||||
const res = await fetch(`${window.location.origin}/api/faucet`, {
|
method: "POST",
|
||||||
method: "POST",
|
});
|
||||||
});
|
const json: FaucetAccountRes | { error: string } = await res.json();
|
||||||
const json: FaucetAccountRes | { error: string } = await res.json();
|
if ("error" in json) {
|
||||||
if ("error" in json) {
|
if (showToast) {
|
||||||
if (showToast) {
|
return toast.error(json.error, { id: toastId });
|
||||||
return toast.error(json.error, { id: toastId });
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (showToast) {
|
return;
|
||||||
toast.success("New account created", { id: toastId });
|
|
||||||
}
|
|
||||||
const currNames = state.accounts.map(acc => acc.name);
|
|
||||||
state.accounts.push({
|
|
||||||
name: name || names.filter(name => !currNames.includes(name))[0],
|
|
||||||
xrp: (json.xrp || 0 * 1000000).toString(),
|
|
||||||
address: json.address,
|
|
||||||
secret: json.secret,
|
|
||||||
sequence: 1,
|
|
||||||
hooks: [],
|
|
||||||
isLoading: false,
|
|
||||||
version: '2'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (showToast) {
|
||||||
|
toast.success("New account created", { id: toastId });
|
||||||
|
}
|
||||||
|
const currNames = state.accounts.map(acc => acc.name);
|
||||||
|
state.accounts.push({
|
||||||
|
name: name || names.filter(name => !currNames.includes(name))[0],
|
||||||
|
xrp: (json.xrp || 0 * 1000000).toString(),
|
||||||
|
address: json.address,
|
||||||
|
secret: json.secret,
|
||||||
|
sequence: 1,
|
||||||
|
hooks: [],
|
||||||
|
isLoading: false,
|
||||||
|
version: '2'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -29,25 +29,30 @@ export const compileCode = async (activeId: number) => {
|
|||||||
const file = state.files[activeId]
|
const file = state.files[activeId]
|
||||||
try {
|
try {
|
||||||
file.containsErrors = false
|
file.containsErrors = false
|
||||||
const res = await fetch(process.env.NEXT_PUBLIC_COMPILE_API_ENDPOINT, {
|
let res: Response
|
||||||
method: "POST",
|
try {
|
||||||
headers: {
|
res = await fetch(process.env.NEXT_PUBLIC_COMPILE_API_ENDPOINT, {
|
||||||
"Content-Type": "application/json",
|
method: "POST",
|
||||||
},
|
headers: {
|
||||||
body: JSON.stringify({
|
"Content-Type": "application/json",
|
||||||
output: "wasm",
|
},
|
||||||
compress: true,
|
body: JSON.stringify({
|
||||||
strip: state.compileOptions.strip,
|
output: "wasm",
|
||||||
files: [
|
compress: true,
|
||||||
{
|
strip: state.compileOptions.strip,
|
||||||
type: "c",
|
files: [
|
||||||
options: state.compileOptions.optimizationLevel || '-O2',
|
{
|
||||||
name: file.name,
|
type: "c",
|
||||||
src: file.content,
|
options: state.compileOptions.optimizationLevel || '-O2',
|
||||||
},
|
name: file.name,
|
||||||
],
|
src: file.content,
|
||||||
}),
|
},
|
||||||
});
|
],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
throw Error("Something went wrong, check your network connection and try again!")
|
||||||
|
}
|
||||||
const json = await res.json();
|
const json = await res.json();
|
||||||
state.compiling = false;
|
state.compiling = false;
|
||||||
if (!json.success) {
|
if (!json.success) {
|
||||||
@@ -61,29 +66,34 @@ export const compileCode = async (activeId: number) => {
|
|||||||
}
|
}
|
||||||
throw errors
|
throw errors
|
||||||
}
|
}
|
||||||
state.logs.push({
|
try {
|
||||||
type: "success",
|
// Decode base64 encoded wasm that is coming back from the endpoint
|
||||||
message: `File ${state.files?.[activeId]?.name} compiled successfully. Ready to deploy.`,
|
const bufferData = await decodeBinary(json.output);
|
||||||
link: Router.asPath.replace("develop", "deploy"),
|
|
||||||
linkText: "Go to deploy",
|
// Import wabt from and create human readable version of wasm file and
|
||||||
});
|
// put it into state
|
||||||
// Decode base64 encoded wasm that is coming back from the endpoint
|
const ww = (await import('wabt')).default()
|
||||||
const bufferData = await decodeBinary(json.output);
|
|
||||||
file.compiledContent = ref(bufferData);
|
|
||||||
file.lastCompiled = new Date();
|
|
||||||
file.compiledValueSnapshot = file.content
|
|
||||||
// Import wabt from and create human readable version of wasm file and
|
|
||||||
// put it into state
|
|
||||||
import("wabt").then((wabt) => {
|
|
||||||
const ww = wabt.default();
|
|
||||||
const myModule = ww.readWasm(new Uint8Array(bufferData), {
|
const myModule = ww.readWasm(new Uint8Array(bufferData), {
|
||||||
readDebugNames: true,
|
readDebugNames: true,
|
||||||
});
|
});
|
||||||
myModule.applyNames();
|
myModule.applyNames();
|
||||||
|
|
||||||
const wast = myModule.toText({ foldExprs: false, inlineExport: false });
|
const wast = myModule.toText({ foldExprs: false, inlineExport: false });
|
||||||
state.files[state.active].compiledWatContent = wast;
|
|
||||||
toast.success("Compiled successfully!", { position: "bottom-center" });
|
file.compiledContent = ref(bufferData);
|
||||||
|
file.lastCompiled = new Date();
|
||||||
|
file.compiledValueSnapshot = file.content
|
||||||
|
file.compiledWatContent = wast;
|
||||||
|
} catch (error) {
|
||||||
|
throw Error("Invalid compilation result produced, check your code for errors and try again!")
|
||||||
|
}
|
||||||
|
|
||||||
|
toast.success("Compiled successfully!", { position: "bottom-center" });
|
||||||
|
state.logs.push({
|
||||||
|
type: "success",
|
||||||
|
message: `File ${state.files?.[activeId]?.name} compiled successfully. Ready to deploy.`,
|
||||||
|
link: Router.asPath.replace("develop", "deploy"),
|
||||||
|
linkText: "Go to deploy",
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -96,12 +106,19 @@ export const compileCode = async (activeId: number) => {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
else if (err instanceof Error) {
|
||||||
|
state.logs.push({
|
||||||
|
type: "error",
|
||||||
|
message: err.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
state.logs.push({
|
state.logs.push({
|
||||||
type: "error",
|
type: "error",
|
||||||
message: "Something went wrong, check your connection try again later!",
|
message: "Something went wrong, come back later!",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
state.compiling = false;
|
state.compiling = false;
|
||||||
toast.error(`Error occurred while compiling!`, { position: "bottom-center" });
|
toast.error(`Error occurred while compiling!`, { position: "bottom-center" });
|
||||||
file.containsErrors = true
|
file.containsErrors = true
|
||||||
|
|||||||
@@ -14,4 +14,11 @@ export const createNewFile = (name: string) => {
|
|||||||
const emptyFile: IFile = { name, language: languageMapping[fileExt as 'ts' | 'js' | 'md' | 'c' | 'h' | 'other'], content: "" };
|
const emptyFile: IFile = { name, language: languageMapping[fileExt as 'ts' | 'js' | 'md' | 'c' | 'h' | 'other'], content: "" };
|
||||||
state.files.push(emptyFile);
|
state.files.push(emptyFile);
|
||||||
state.active = state.files.length - 1;
|
state.active = state.files.length - 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const renameFile = (oldName: string, nwName: string) => {
|
||||||
|
const file = state.files.find(file => file.name === oldName)
|
||||||
|
if (!file) throw Error(`No file exists with name ${oldName}`)
|
||||||
|
|
||||||
|
file.name = nwName
|
||||||
};
|
};
|
||||||
24
state/actions/deleteAccount.ts
Normal file
24
state/actions/deleteAccount.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import state, { transactionsState } from '..';
|
||||||
|
|
||||||
|
export const deleteAccount = (addr?: string) => {
|
||||||
|
if (!addr) return;
|
||||||
|
const index = state.accounts.findIndex(acc => acc.address === addr);
|
||||||
|
if (index === -1) return;
|
||||||
|
state.accounts.splice(index, 1);
|
||||||
|
|
||||||
|
// update selected accounts
|
||||||
|
transactionsState.transactions
|
||||||
|
.filter(t => t.state.selectedAccount?.value === addr)
|
||||||
|
.forEach(t => {
|
||||||
|
const acc = t.state.selectedAccount;
|
||||||
|
if (!acc) return;
|
||||||
|
acc.label = acc.value;
|
||||||
|
});
|
||||||
|
transactionsState.transactions
|
||||||
|
.filter(t => t.state.selectedDestAccount?.value === addr)
|
||||||
|
.forEach(t => {
|
||||||
|
const acc = t.state.selectedDestAccount;
|
||||||
|
if (!acc) return;
|
||||||
|
acc.label = acc.value;
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -3,10 +3,10 @@ import toast from "react-hot-toast";
|
|||||||
|
|
||||||
import state, { IAccount } from "../index";
|
import state, { IAccount } from "../index";
|
||||||
import calculateHookOn, { TTS } from "../../utils/hookOnCalculator";
|
import calculateHookOn, { TTS } from "../../utils/hookOnCalculator";
|
||||||
import { SetHookData } from "../../components/SetHookDialog";
|
|
||||||
import { Link } from "../../components";
|
import { Link } from "../../components";
|
||||||
import { ref } from "valtio";
|
import { ref } from "valtio";
|
||||||
import estimateFee from "../../utils/estimateFee";
|
import estimateFee from "../../utils/estimateFee";
|
||||||
|
import { SetHookData } from '../../utils/setHook';
|
||||||
|
|
||||||
export const sha256 = async (string: string) => {
|
export const sha256 = async (string: string) => {
|
||||||
const utf8 = new TextEncoder().encode(string);
|
const utf8 = new TextEncoder().encode(string);
|
||||||
|
|||||||
@@ -1,117 +1,92 @@
|
|||||||
import { Octokit } from "@octokit/core";
|
import { Octokit } from "@octokit/core";
|
||||||
import Router from "next/router";
|
import state, { IFile } from '../index';
|
||||||
import state from '../index';
|
|
||||||
import { templateFileIds } from '../constants';
|
import { templateFileIds } from '../constants';
|
||||||
|
|
||||||
const octokit = new Octokit();
|
const octokit = new Octokit();
|
||||||
|
|
||||||
/* Fetches Gist files from Githug Gists based on
|
/**
|
||||||
* gistId and stores the content in global state
|
* Fetches files from Github Gists based on gistId and stores them in global state
|
||||||
*/
|
*/
|
||||||
export const fetchFiles = (gistId: string) => {
|
export const fetchFiles = async (gistId: string) => {
|
||||||
|
if (!gistId || state.files.length) return
|
||||||
|
|
||||||
state.loading = true;
|
state.loading = true;
|
||||||
if (gistId && !state.files.length) {
|
state.logs.push({
|
||||||
state.logs.push({
|
type: "log",
|
||||||
type: "log",
|
message: `Fetching Gist with id: ${gistId}`,
|
||||||
message: `Fetching Gist with id: ${gistId}`,
|
});
|
||||||
});
|
try {
|
||||||
|
const res = await octokit
|
||||||
octokit
|
|
||||||
.request("GET /gists/{gist_id}", { gist_id: gistId })
|
.request("GET /gists/{gist_id}", { gist_id: gistId })
|
||||||
.then(async res => {
|
|
||||||
if (!Object.values(templateFileIds).map(v => v.id).includes(gistId)) {
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
// in case of templates, fetch header file(s) and append to res
|
|
||||||
try {
|
|
||||||
const resHeader = await fetch(`${process.env.NEXT_PUBLIC_COMPILE_API_BASE_URL}/api/header-files`);
|
|
||||||
if (resHeader.ok) {
|
|
||||||
const resHeaderJson = await resHeader.json()
|
|
||||||
const headerFiles: Record<string, { filename: string; content: string; language: string }> = {};
|
|
||||||
Object.entries(resHeaderJson).forEach(([key, value]) => {
|
|
||||||
const fname = `${key}.h`;
|
|
||||||
headerFiles[fname] = { filename: fname, content: value as string, language: 'C' }
|
|
||||||
})
|
|
||||||
const files = {
|
|
||||||
...res.data.files,
|
|
||||||
...headerFiles
|
|
||||||
};
|
|
||||||
res.data.files = files;
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
const isTemplate = (id: string) => Object.values(templateFileIds).map(v => v.id).includes(id)
|
||||||
|
|
||||||
|
if (isTemplate(gistId)) {
|
||||||
|
// fetch headers
|
||||||
|
const headerRes = await fetch(`${process.env.NEXT_PUBLIC_COMPILE_API_BASE_URL}/api/header-files`);
|
||||||
|
if (!headerRes.ok) throw Error("Failed to fetch headers");;
|
||||||
|
|
||||||
return res;
|
const headerJson = await headerRes.json()
|
||||||
// If you want to load templates from GIST instad, uncomment the code below and comment the code above.
|
const headerFiles: Record<string, { filename: string; content: string; language: string }> = {};
|
||||||
// return octokit.request("GET /gists/{gist_id}", { gist_id: templateFileIds.headers }).then(({ data: { files: headerFiles } }) => {
|
Object.entries(headerJson).forEach(([key, value]) => {
|
||||||
// const files = { ...res.data.files, ...headerFiles }
|
const fname = `${key}.h`;
|
||||||
// console.log(headerFiles)
|
headerFiles[fname] = { filename: fname, content: value as string, language: 'C' }
|
||||||
// res.data.files = files
|
|
||||||
// return res
|
|
||||||
// })
|
|
||||||
})
|
})
|
||||||
.then((res) => {
|
const files = {
|
||||||
if (res.data.files && Object.keys(res.data.files).length > 0) {
|
...res.data.files,
|
||||||
const files = Object.keys(res.data.files).map((filename) => ({
|
...headerFiles
|
||||||
name: res.data.files?.[filename]?.filename || "untitled.c",
|
};
|
||||||
language: res.data.files?.[filename]?.language?.toLowerCase() || "",
|
res.data.files = files;
|
||||||
content: res.data.files?.[filename]?.content || "",
|
}
|
||||||
}));
|
|
||||||
// Sort files so that the source files are first
|
if (!res.data.files) throw Error("No files could be fetched from given gist id!")
|
||||||
// In case of other files leave the order as it its
|
|
||||||
files.sort((a, b) => {
|
const files: IFile[] = Object.keys(res.data.files).map((filename) => ({
|
||||||
const aBasename = a.name.split('.')?.[0];
|
name: res.data.files?.[filename]?.filename || "untitled.c",
|
||||||
const aCext = a.name?.toLowerCase().endsWith('.c');
|
language: res.data.files?.[filename]?.language?.toLowerCase() || "",
|
||||||
const bBasename = b.name.split('.')?.[0];
|
content: res.data.files?.[filename]?.content || "",
|
||||||
const bCext = b.name?.toLowerCase().endsWith('.c');
|
}));
|
||||||
// If a has c extension and b doesn't move a up
|
|
||||||
if (aCext && !bCext) {
|
files.sort((a, b) => {
|
||||||
return -1;
|
const aBasename = a.name.split('.')?.[0];
|
||||||
}
|
const aExt = a.name.split('.').pop() || '';
|
||||||
if (!aCext && bCext) {
|
const bBasename = b.name.split('.')?.[0];
|
||||||
return 1
|
const bExt = b.name.split('.').pop() || '';
|
||||||
}
|
|
||||||
// Otherwise fallback to default sorting based on basename
|
// default priority is undefined == 0
|
||||||
if (aBasename > bBasename) {
|
const extPriority: Record<string, number> = {
|
||||||
return 1;
|
c: 3,
|
||||||
}
|
md: 2,
|
||||||
if (bBasename > aBasename) {
|
h: -1
|
||||||
return -1;
|
}
|
||||||
}
|
|
||||||
return 0;
|
// Sort based on extention priorities
|
||||||
})
|
const comp = (extPriority[bExt] || 0) - (extPriority[aExt] || 0)
|
||||||
state.loading = false;
|
if (comp !== 0) return comp
|
||||||
if (files.length > 0) {
|
|
||||||
state.logs.push({
|
// Otherwise fallback to alphabetical sorting
|
||||||
type: "success",
|
return aBasename.localeCompare(bBasename)
|
||||||
message: "Fetched successfully ✅",
|
})
|
||||||
});
|
|
||||||
state.files = files;
|
state.logs.push({
|
||||||
state.gistId = gistId;
|
type: "success",
|
||||||
state.gistName = Object.keys(res.data.files)?.[0] || "untitled";
|
message: "Fetched successfully ✅",
|
||||||
state.gistOwner = res.data.owner?.login;
|
});
|
||||||
return;
|
state.files = files;
|
||||||
} else {
|
state.gistId = gistId;
|
||||||
// Open main modal if now files
|
state.gistOwner = res.data.owner?.login;
|
||||||
state.mainModalOpen = true;
|
|
||||||
}
|
const gistName = files.find(file => file.language === 'c' || file.language === 'javascript')?.name || "untitled";
|
||||||
return Router.push({ pathname: "/develop" });
|
state.gistName = gistName
|
||||||
}
|
} catch (err) {
|
||||||
state.loading = false;
|
console.error(err)
|
||||||
})
|
let message: string
|
||||||
.catch((err) => {
|
if (err instanceof Error) message = err.message
|
||||||
// console.error(err)
|
else message = `Something went wrong, try again later!`
|
||||||
state.loading = false;
|
state.logs.push({
|
||||||
state.logs.push({
|
type: "error",
|
||||||
type: "error",
|
message: `Error: ${message}`,
|
||||||
message: `Couldn't find Gist with id: ${gistId}`,
|
});
|
||||||
});
|
|
||||||
return;
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
state.loading = false;
|
state.loading = false;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export const sendTransaction = async (account: IAccount, txOptions: TransactionO
|
|||||||
Fee, // TODO auto-fillable default
|
Fee, // TODO auto-fillable default
|
||||||
...opts
|
...opts
|
||||||
};
|
};
|
||||||
|
|
||||||
const { logPrefix = '' } = options || {}
|
const { logPrefix = '' } = options || {}
|
||||||
try {
|
try {
|
||||||
const signedAccount = derive.familySeed(account.secret);
|
const signedAccount = derive.familySeed(account.secret);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import Starter from "../../components/icons/Starter";
|
|||||||
|
|
||||||
export const templateFileIds = {
|
export const templateFileIds = {
|
||||||
'starter': {
|
'starter': {
|
||||||
id: '9106f1fe60482d90475bfe8f1315affe',
|
id: '1f8109c80f504e6326db2735df2f0ad6', // Forked
|
||||||
name: 'Starter',
|
name: 'Starter',
|
||||||
description: 'Just a basic starter with essential imports, just accepts any transaction coming through',
|
description: 'Just a basic starter with essential imports, just accepts any transaction coming through',
|
||||||
icon: Starter
|
icon: Starter
|
||||||
@@ -25,7 +25,7 @@ export const templateFileIds = {
|
|||||||
icon: Notary
|
icon: Notary
|
||||||
},
|
},
|
||||||
'carbon': {
|
'carbon': {
|
||||||
id: '5941c19dce3e147948f564e224553c02',
|
id: '953662b22d065449f8ab6f69bc2afe41', // Forked
|
||||||
name: 'Carbon',
|
name: 'Carbon',
|
||||||
description: 'Send a percentage of sum to an address',
|
description: 'Send a percentage of sum to an address',
|
||||||
icon: Carbon
|
icon: Carbon
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type monaco from "monaco-editor";
|
import type monaco from "monaco-editor";
|
||||||
import { proxy, ref, subscribe } from "valtio";
|
import { proxy, ref, subscribe } from "valtio";
|
||||||
import { devtools } from 'valtio/utils';
|
import { devtools, subscribeKey } from 'valtio/utils';
|
||||||
import { XrplClient } from "xrpl-client";
|
import { XrplClient } from "xrpl-client";
|
||||||
import { SplitSize } from "./actions/persistSplits";
|
import { SplitSize } from "./actions/persistSplits";
|
||||||
|
|
||||||
@@ -168,16 +168,23 @@ if (process.env.NODE_ENV !== "production") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
subscribe(state, () => {
|
subscribe(state.accounts, () => {
|
||||||
const { accounts, active } = state;
|
const { accounts } = state;
|
||||||
const accountsNoLoading = accounts.map(acc => ({ ...acc, isLoading: false }))
|
const accountsNoLoading = accounts.map(acc => ({ ...acc, isLoading: false }))
|
||||||
localStorage.setItem("hooksIdeAccounts", JSON.stringify(accountsNoLoading));
|
localStorage.setItem("hooksIdeAccounts", JSON.stringify(accountsNoLoading));
|
||||||
if (!state.files[active]?.compiledWatContent) {
|
|
||||||
state.activeWat = 0;
|
|
||||||
} else {
|
|
||||||
state.activeWat = active;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const updateActiveWat = () => {
|
||||||
|
const filename = state.files[state.active]?.name
|
||||||
|
|
||||||
|
const compiledFiles = state.files.filter(
|
||||||
|
file => file.compiledContent)
|
||||||
|
const idx = compiledFiles.findIndex(file => file.name === filename)
|
||||||
|
|
||||||
|
if (idx !== -1) state.activeWat = idx
|
||||||
|
}
|
||||||
|
subscribeKey(state, 'active', updateActiveWat)
|
||||||
|
subscribeKey(state, 'files', updateActiveWat)
|
||||||
}
|
}
|
||||||
export default state
|
export default state
|
||||||
|
|
||||||
|
|||||||
@@ -18,14 +18,13 @@ export interface TransactionState {
|
|||||||
txIsDisabled: boolean;
|
txIsDisabled: boolean;
|
||||||
txFields: TxFields;
|
txFields: TxFields;
|
||||||
viewType: 'json' | 'ui',
|
viewType: 'json' | 'ui',
|
||||||
editorSavedValue: null | string,
|
|
||||||
editorValue?: string,
|
editorValue?: string,
|
||||||
estimatedFee?: string
|
estimatedFee?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export type TxFields = Omit<
|
export type TxFields = Omit<
|
||||||
typeof transactionsData[0],
|
Partial<typeof transactionsData[0]>,
|
||||||
"Account" | "Sequence" | "TransactionType"
|
"Account" | "Sequence" | "TransactionType"
|
||||||
>;
|
>;
|
||||||
|
|
||||||
@@ -36,27 +35,34 @@ export const defaultTransaction: TransactionState = {
|
|||||||
txIsLoading: false,
|
txIsLoading: false,
|
||||||
txIsDisabled: false,
|
txIsDisabled: false,
|
||||||
txFields: {},
|
txFields: {},
|
||||||
viewType: 'ui',
|
viewType: 'ui'
|
||||||
editorSavedValue: null
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const transactionsState = proxy({
|
export const transactionsState = proxy({
|
||||||
transactions: [
|
transactions: [
|
||||||
{
|
{
|
||||||
header: "test1.json",
|
header: "test1.json",
|
||||||
state: defaultTransaction,
|
state: { ...defaultTransaction },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
activeHeader: "test1.json"
|
activeHeader: "test1.json"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const renameTxState = (oldName: string, nwName: string) => {
|
||||||
|
const tx = transactionsState.transactions.find(tx => tx.header === oldName);
|
||||||
|
|
||||||
|
if (!tx) throw Error(`No transaction state exists with given header name ${oldName}`);
|
||||||
|
|
||||||
|
tx.header = nwName
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple transaction state changer
|
* Simple transaction state changer
|
||||||
* @param header Unique key and tab name for the transaction tab
|
* @param header Unique key and tab name for the transaction tab
|
||||||
* @param partialTx partial transaction state, `undefined` deletes the transaction
|
* @param partialTx partial transaction state, `undefined` deletes the transaction
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export const modifyTransaction = (
|
export const modifyTxState = (
|
||||||
header: string,
|
header: string,
|
||||||
partialTx?: Partial<TransactionState>,
|
partialTx?: Partial<TransactionState>,
|
||||||
opts: { replaceState?: boolean } = {}
|
opts: { replaceState?: boolean } = {}
|
||||||
@@ -92,7 +98,7 @@ export const modifyTransaction = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(partialTx).forEach(k => {
|
Object.keys(partialTx).forEach(k => {
|
||||||
// Typescript mess here, but is definetly safe!
|
// Typescript mess here, but is definitely safe!
|
||||||
const s = tx.state as any;
|
const s = tx.state as any;
|
||||||
const p = partialTx as any; // ? Make copy
|
const p = partialTx as any; // ? Make copy
|
||||||
if (!deepEqual(s[k], p[k])) s[k] = p[k];
|
if (!deepEqual(s[k], p[k])) s[k] = p[k];
|
||||||
@@ -118,7 +124,7 @@ export const prepareTransaction = (data: any) => {
|
|||||||
// handle type: `json`
|
// handle type: `json`
|
||||||
if (_value && typeof _value === "object" && _value.$type === "json") {
|
if (_value && typeof _value === "object" && _value.$type === "json") {
|
||||||
if (typeof _value.$value === "object") {
|
if (typeof _value.$value === "object") {
|
||||||
options[field] = _value.$value as any;
|
options[field] = _value.$value;
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
options[field] = JSON.parse(_value.$value);
|
options[field] = JSON.parse(_value.$value);
|
||||||
@@ -131,8 +137,8 @@ export const prepareTransaction = (data: any) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete unneccesary fields
|
// delete unnecessary fields
|
||||||
if (options[field] === undefined) {
|
if (!options[field]) {
|
||||||
delete options[field];
|
delete options[field];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -152,7 +158,7 @@ export const prepareState = (value: string, transactionType?: string) => {
|
|||||||
|
|
||||||
const { Account, TransactionType, Destination, ...rest } = options;
|
const { Account, TransactionType, Destination, ...rest } = options;
|
||||||
let tx: Partial<TransactionState> = {};
|
let tx: Partial<TransactionState> = {};
|
||||||
const txFields = getTxFields(transactionType)
|
const schema = getTxFields(transactionType)
|
||||||
|
|
||||||
if (Account) {
|
if (Account) {
|
||||||
const acc = state.accounts.find(acc => acc.address === Account);
|
const acc = state.accounts.find(acc => acc.address === Account);
|
||||||
@@ -180,9 +186,8 @@ export const prepareState = (value: string, transactionType?: string) => {
|
|||||||
tx.selectedTransaction = null;
|
tx.selectedTransaction = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (txFields.Destination !== undefined) {
|
if (schema.Destination !== undefined) {
|
||||||
const dest = state.accounts.find(acc => acc.address === Destination);
|
const dest = state.accounts.find(acc => acc.address === Destination);
|
||||||
rest.Destination = null
|
|
||||||
if (dest) {
|
if (dest) {
|
||||||
tx.selectedDestAccount = {
|
tx.selectedDestAccount = {
|
||||||
label: dest.name,
|
label: dest.name,
|
||||||
@@ -199,11 +204,14 @@ export const prepareState = (value: string, transactionType?: string) => {
|
|||||||
tx.selectedDestAccount = null
|
tx.selectedDestAccount = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (Destination) {
|
||||||
|
rest.Destination = Destination
|
||||||
|
}
|
||||||
|
|
||||||
Object.keys(rest).forEach(field => {
|
Object.keys(rest).forEach(field => {
|
||||||
const value = rest[field];
|
const value = rest[field];
|
||||||
const origValue = txFields[field as keyof TxFields]
|
const schemaVal = schema[field as keyof TxFields]
|
||||||
const isXrp = typeof value !== 'object' && origValue && typeof origValue === 'object' && origValue.$type === 'xrp'
|
const isXrp = typeof value !== 'object' && schemaVal && typeof schemaVal === 'object' && schemaVal.$type === 'xrp'
|
||||||
if (isXrp) {
|
if (isXrp) {
|
||||||
rest[field] = {
|
rest[field] = {
|
||||||
$type: "xrp",
|
$type: "xrp",
|
||||||
@@ -218,7 +226,6 @@ export const prepareState = (value: string, transactionType?: string) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
tx.txFields = rest;
|
tx.txFields = rest;
|
||||||
tx.editorSavedValue = null;
|
|
||||||
|
|
||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
@@ -244,3 +251,10 @@ export const getTxFields = (tt?: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export { transactionsData }
|
export { transactionsData }
|
||||||
|
|
||||||
|
export const transactionsOptions = transactionsData.map(tx => ({
|
||||||
|
value: tx.TransactionType,
|
||||||
|
label: tx.TransactionType,
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const defaultTransactionType = transactionsOptions.find(tt => tt.value === 'Payment')
|
||||||
@@ -53,6 +53,7 @@ export const {
|
|||||||
accent: "#9D2DFF",
|
accent: "#9D2DFF",
|
||||||
background: "$gray1",
|
background: "$gray1",
|
||||||
backgroundAlt: "$gray4",
|
backgroundAlt: "$gray4",
|
||||||
|
backgroundOverlay: "$mauve2",
|
||||||
text: "$gray12",
|
text: "$gray12",
|
||||||
textMuted: "$gray10",
|
textMuted: "$gray10",
|
||||||
primary: "$plum",
|
primary: "$plum",
|
||||||
@@ -365,6 +366,7 @@ export const darkTheme = createTheme("dark", {
|
|||||||
...greenDark,
|
...greenDark,
|
||||||
...redDark,
|
...redDark,
|
||||||
deep: "rgb(10, 10, 10)",
|
deep: "rgb(10, 10, 10)",
|
||||||
|
backgroundOverlay: "$mauve5"
|
||||||
// backgroundA: transparentize(0.1, grayDark.gray1),
|
// backgroundA: transparentize(0.1, grayDark.gray1),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
21
styles/keyframes.ts
Normal file
21
styles/keyframes.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { keyframes } from '../stitches.config';
|
||||||
|
|
||||||
|
export const slideUpAndFade = keyframes({
|
||||||
|
"0%": { opacity: 0, transform: "translateY(2px)" },
|
||||||
|
"100%": { opacity: 1, transform: "translateY(0)" },
|
||||||
|
});
|
||||||
|
|
||||||
|
export const slideRightAndFade = keyframes({
|
||||||
|
"0%": { opacity: 0, transform: "translateX(-2px)" },
|
||||||
|
"100%": { opacity: 1, transform: "translateX(0)" },
|
||||||
|
});
|
||||||
|
|
||||||
|
export const slideDownAndFade = keyframes({
|
||||||
|
"0%": { opacity: 0, transform: "translateY(-2px)" },
|
||||||
|
"100%": { opacity: 1, transform: "translateY(0)" },
|
||||||
|
});
|
||||||
|
|
||||||
|
export const slideLeftAndFade = keyframes({
|
||||||
|
"0%": { opacity: 0, transform: "translateX(2px)" },
|
||||||
|
"100%": { opacity: 1, transform: "translateX(0)" },
|
||||||
|
});
|
||||||
@@ -18,13 +18,18 @@ export const tts = {
|
|||||||
ttDEPOSIT_PREAUTH: 19,
|
ttDEPOSIT_PREAUTH: 19,
|
||||||
ttTRUST_SET: 20,
|
ttTRUST_SET: 20,
|
||||||
ttACCOUNT_DELETE: 21,
|
ttACCOUNT_DELETE: 21,
|
||||||
ttHOOK_SET: 22
|
ttHOOK_SET: 22,
|
||||||
|
ttNFTOKEN_MINT: 25,
|
||||||
|
ttNFTOKEN_BURN: 26,
|
||||||
|
ttNFTOKEN_CREATE_OFFER: 27,
|
||||||
|
ttNFTOKEN_CANCEL_OFFER: 28,
|
||||||
|
ttNFTOKEN_ACCEPT_OFFER: 29
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TTS = typeof tts;
|
export type TTS = typeof tts;
|
||||||
|
|
||||||
const calculateHookOn = (arr: (keyof TTS)[]) => {
|
const calculateHookOn = (arr: (keyof TTS)[]) => {
|
||||||
let start = '0x00000000003ff5bf';
|
let start = '0x000000003e3ff5bf';
|
||||||
arr.forEach(n => {
|
arr.forEach(n => {
|
||||||
let v = BigInt(start);
|
let v = BigInt(start);
|
||||||
v ^= (BigInt(1) << BigInt(tts[n as keyof TTS]));
|
v ^= (BigInt(1) << BigInt(tts[n as keyof TTS]));
|
||||||
|
|||||||
78
utils/setHook.ts
Normal file
78
utils/setHook.ts
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import { getTags } from './comment-parser';
|
||||||
|
import { tts, TTS } from './hookOnCalculator';
|
||||||
|
|
||||||
|
export const transactionOptions = Object.keys(tts).map(key => ({
|
||||||
|
label: key,
|
||||||
|
value: key as keyof TTS,
|
||||||
|
}));
|
||||||
|
|
||||||
|
export type SetHookData = {
|
||||||
|
Invoke: {
|
||||||
|
value: keyof TTS;
|
||||||
|
label: string;
|
||||||
|
}[];
|
||||||
|
Fee: string;
|
||||||
|
HookNamespace: string;
|
||||||
|
HookParameters: {
|
||||||
|
HookParameter: {
|
||||||
|
HookParameterName: string;
|
||||||
|
HookParameterValue: string;
|
||||||
|
};
|
||||||
|
$metaData?: any;
|
||||||
|
}[];
|
||||||
|
// HookGrants: {
|
||||||
|
// HookGrant: {
|
||||||
|
// Authorize: string;
|
||||||
|
// HookHash: string;
|
||||||
|
// };
|
||||||
|
// }[];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const getParameters = (content?: string) => {
|
||||||
|
const fieldTags = ["field", "param", "arg", "argument"];
|
||||||
|
const tags = getTags(content)
|
||||||
|
.filter(tag => fieldTags.includes(tag.tag))
|
||||||
|
.filter(tag => !!tag.name);
|
||||||
|
|
||||||
|
const paramters: SetHookData["HookParameters"] = tags.map(tag => ({
|
||||||
|
HookParameter: {
|
||||||
|
HookParameterName: tag.name,
|
||||||
|
HookParameterValue: tag.default || "",
|
||||||
|
},
|
||||||
|
$metaData: {
|
||||||
|
description: tag.description,
|
||||||
|
required: !tag.optional
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
return paramters;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getInvokeOptions = (content?: string) => {
|
||||||
|
const invokeTags = ["invoke", "invoke-on"];
|
||||||
|
|
||||||
|
const options = getTags(content)
|
||||||
|
.filter(tag => invokeTags.includes(tag.tag))
|
||||||
|
.reduce((cumm, curr) => {
|
||||||
|
const combined = curr.type || `${curr.name} ${curr.description}`
|
||||||
|
const opts = combined.split(' ')
|
||||||
|
|
||||||
|
return cumm.concat(opts as any)
|
||||||
|
}, [] as (keyof TTS)[])
|
||||||
|
.filter(opt => Object.keys(tts).includes(opt))
|
||||||
|
|
||||||
|
|
||||||
|
const invokeOptions: SetHookData['Invoke'] = options.map(opt => ({
|
||||||
|
label: opt,
|
||||||
|
value: opt
|
||||||
|
}))
|
||||||
|
|
||||||
|
// default
|
||||||
|
if (!invokeOptions.length) {
|
||||||
|
const payment = transactionOptions.find(tx => tx.value === "ttPAYMENT")
|
||||||
|
if (payment) return [payment]
|
||||||
|
}
|
||||||
|
|
||||||
|
return invokeOptions;
|
||||||
|
};
|
||||||
623
yarn.lock
623
yarn.lock
@@ -594,6 +594,18 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-context-menu@^0.1.6":
|
||||||
|
version "0.1.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-context-menu/-/react-context-menu-0.1.6.tgz#0c75f2faffec6c8697247a4b685a432b3c4d07f0"
|
||||||
|
integrity sha512-0qa6ABaeqD+WYI+8iT0jH0QLLcV8Kv0xI+mZL4FFnG4ec9H0v+yngb5cfBBfs9e/KM8mDzFFpaeegqsQlLNqyQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/primitive" "0.1.0"
|
||||||
|
"@radix-ui/react-context" "0.1.1"
|
||||||
|
"@radix-ui/react-menu" "0.1.6"
|
||||||
|
"@radix-ui/react-primitive" "0.1.4"
|
||||||
|
"@radix-ui/react-use-callback-ref" "0.1.0"
|
||||||
|
|
||||||
"@radix-ui/react-context@0.1.1":
|
"@radix-ui/react-context@0.1.1":
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-0.1.1.tgz"
|
resolved "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-0.1.1.tgz"
|
||||||
@@ -635,9 +647,9 @@
|
|||||||
"@radix-ui/react-use-callback-ref" "0.1.0"
|
"@radix-ui/react-use-callback-ref" "0.1.0"
|
||||||
"@radix-ui/react-use-escape-keydown" "0.1.0"
|
"@radix-ui/react-use-escape-keydown" "0.1.0"
|
||||||
|
|
||||||
"@radix-ui/react-dropdown-menu@^0.1.1":
|
"@radix-ui/react-dropdown-menu@^0.1.6":
|
||||||
version "0.1.6"
|
version "0.1.6"
|
||||||
resolved "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-0.1.6.tgz"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-0.1.6.tgz#3203229788cd57e552c9f19dcc7008e2b545919c"
|
||||||
integrity sha512-RZhtzjWwJ4ZBN7D8ek4Zn+ilHzYuYta9yIxFnbC0pfqMnSi67IQNONo1tuuNqtFh9SRHacPKc65zo+kBBlxtdg==
|
integrity sha512-RZhtzjWwJ4ZBN7D8ek4Zn+ilHzYuYta9yIxFnbC0pfqMnSi67IQNONo1tuuNqtFh9SRHacPKc65zo+kBBlxtdg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
@@ -939,6 +951,13 @@
|
|||||||
resolved "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.0.tgz"
|
resolved "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.0.tgz"
|
||||||
integrity sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg==
|
integrity sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg==
|
||||||
|
|
||||||
|
"@types/debug@^4.0.0":
|
||||||
|
version "4.1.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82"
|
||||||
|
integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==
|
||||||
|
dependencies:
|
||||||
|
"@types/ms" "*"
|
||||||
|
|
||||||
"@types/dinero.js@^1.9.0":
|
"@types/dinero.js@^1.9.0":
|
||||||
version "1.9.0"
|
version "1.9.0"
|
||||||
resolved "https://registry.npmjs.org/@types/dinero.js/-/dinero.js-1.9.0.tgz"
|
resolved "https://registry.npmjs.org/@types/dinero.js/-/dinero.js-1.9.0.tgz"
|
||||||
@@ -949,6 +968,13 @@
|
|||||||
resolved "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.5.tgz"
|
resolved "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.5.tgz"
|
||||||
integrity sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==
|
integrity sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==
|
||||||
|
|
||||||
|
"@types/hast@^2.0.0":
|
||||||
|
version "2.3.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc"
|
||||||
|
integrity sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==
|
||||||
|
dependencies:
|
||||||
|
"@types/unist" "*"
|
||||||
|
|
||||||
"@types/json-schema@^7.0.8":
|
"@types/json-schema@^7.0.8":
|
||||||
version "7.0.9"
|
version "7.0.9"
|
||||||
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz"
|
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz"
|
||||||
@@ -990,6 +1016,23 @@
|
|||||||
resolved "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz"
|
resolved "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz"
|
||||||
integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==
|
integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==
|
||||||
|
|
||||||
|
"@types/mdast@^3.0.0":
|
||||||
|
version "3.0.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af"
|
||||||
|
integrity sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==
|
||||||
|
dependencies:
|
||||||
|
"@types/unist" "*"
|
||||||
|
|
||||||
|
"@types/mdurl@^1.0.0":
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9"
|
||||||
|
integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==
|
||||||
|
|
||||||
|
"@types/ms@*":
|
||||||
|
version "0.7.31"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197"
|
||||||
|
integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==
|
||||||
|
|
||||||
"@types/node@*":
|
"@types/node@*":
|
||||||
version "17.0.21"
|
version "17.0.21"
|
||||||
resolved "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz"
|
resolved "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz"
|
||||||
@@ -1020,6 +1063,11 @@
|
|||||||
resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz"
|
resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz"
|
||||||
integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
|
integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
|
||||||
|
|
||||||
|
"@types/prop-types@^15.0.0":
|
||||||
|
version "15.7.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
|
||||||
|
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
|
||||||
|
|
||||||
"@types/react-transition-group@^4.4.0":
|
"@types/react-transition-group@^4.4.0":
|
||||||
version "4.4.4"
|
version "4.4.4"
|
||||||
resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.4.tgz"
|
resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.4.tgz"
|
||||||
@@ -1050,6 +1098,11 @@
|
|||||||
resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz"
|
resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz"
|
||||||
integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
|
integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
|
||||||
|
|
||||||
|
"@types/unist@*", "@types/unist@^2.0.0":
|
||||||
|
version "2.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
|
||||||
|
integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
|
||||||
|
|
||||||
"@types/ws@^7.2.0":
|
"@types/ws@^7.2.0":
|
||||||
version "7.4.7"
|
version "7.4.7"
|
||||||
resolved "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz"
|
resolved "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz"
|
||||||
@@ -1280,13 +1333,10 @@ babel-plugin-macros@^2.6.1:
|
|||||||
cosmiconfig "^6.0.0"
|
cosmiconfig "^6.0.0"
|
||||||
resolve "^1.12.0"
|
resolve "^1.12.0"
|
||||||
|
|
||||||
babel-runtime@^6.26.0:
|
bail@^2.0.0:
|
||||||
version "6.26.0"
|
version "2.0.2"
|
||||||
resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz"
|
resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d"
|
||||||
integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4=
|
integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==
|
||||||
dependencies:
|
|
||||||
core-js "^2.4.0"
|
|
||||||
regenerator-runtime "^0.11.0"
|
|
||||||
|
|
||||||
balanced-match@^1.0.0:
|
balanced-match@^1.0.0:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
@@ -1483,6 +1533,11 @@ chalk@^4.0.0:
|
|||||||
ansi-styles "^4.1.0"
|
ansi-styles "^4.1.0"
|
||||||
supports-color "^7.1.0"
|
supports-color "^7.1.0"
|
||||||
|
|
||||||
|
character-entities@^2.0.0:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22"
|
||||||
|
integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==
|
||||||
|
|
||||||
ci-info@^2.0.0:
|
ci-info@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz"
|
resolved "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz"
|
||||||
@@ -1525,6 +1580,11 @@ color-name@~1.1.4:
|
|||||||
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
|
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
|
||||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||||
|
|
||||||
|
comma-separated-tokens@^2.0.0:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz#d4c25abb679b7751c880be623c1179780fe1dd98"
|
||||||
|
integrity sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg==
|
||||||
|
|
||||||
comment-parser@^1.3.1:
|
comment-parser@^1.3.1:
|
||||||
version "1.3.1"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.3.1.tgz#3d7ea3adaf9345594aedee6563f422348f165c1b"
|
resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.3.1.tgz#3d7ea3adaf9345594aedee6563f422348f165c1b"
|
||||||
@@ -1552,11 +1612,6 @@ core-js-pure@^3.20.2:
|
|||||||
resolved "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.21.1.tgz"
|
resolved "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.21.1.tgz"
|
||||||
integrity sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==
|
integrity sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==
|
||||||
|
|
||||||
core-js@^2.4.0:
|
|
||||||
version "2.6.12"
|
|
||||||
resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz"
|
|
||||||
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
|
||||||
|
|
||||||
core-util-is@~1.0.0:
|
core-util-is@~1.0.0:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz"
|
resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz"
|
||||||
@@ -1655,11 +1710,25 @@ debug@^3.2.7:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms "^2.1.1"
|
ms "^2.1.1"
|
||||||
|
|
||||||
|
debug@^4.0.0:
|
||||||
|
version "4.3.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
||||||
|
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
|
||||||
|
dependencies:
|
||||||
|
ms "2.1.2"
|
||||||
|
|
||||||
decimal.js@^10.2.0:
|
decimal.js@^10.2.0:
|
||||||
version "10.3.1"
|
version "10.3.1"
|
||||||
resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz"
|
resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz"
|
||||||
integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==
|
integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==
|
||||||
|
|
||||||
|
decode-named-character-reference@^1.0.0:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e"
|
||||||
|
integrity sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==
|
||||||
|
dependencies:
|
||||||
|
character-entities "^2.0.0"
|
||||||
|
|
||||||
deep-is@^0.1.3:
|
deep-is@^0.1.3:
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz"
|
resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz"
|
||||||
@@ -1677,11 +1746,21 @@ deprecation@^2.0.0, deprecation@^2.3.1:
|
|||||||
resolved "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz"
|
resolved "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz"
|
||||||
integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==
|
integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==
|
||||||
|
|
||||||
|
dequal@^2.0.0:
|
||||||
|
version "2.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be"
|
||||||
|
integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
|
||||||
|
|
||||||
detect-node-es@^1.1.0:
|
detect-node-es@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz"
|
resolved "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz"
|
||||||
integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==
|
integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==
|
||||||
|
|
||||||
|
diff@^5.0.0:
|
||||||
|
version "5.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40"
|
||||||
|
integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==
|
||||||
|
|
||||||
dinero.js@^1.9.1:
|
dinero.js@^1.9.1:
|
||||||
version "1.9.1"
|
version "1.9.1"
|
||||||
resolved "https://registry.npmjs.org/dinero.js/-/dinero.js-1.9.1.tgz"
|
resolved "https://registry.npmjs.org/dinero.js/-/dinero.js-1.9.1.tgz"
|
||||||
@@ -2066,6 +2145,11 @@ ext@^1.1.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
type "^2.5.0"
|
type "^2.5.0"
|
||||||
|
|
||||||
|
extend@^3.0.0:
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||||
|
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||||
|
|
||||||
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||||
version "3.1.3"
|
version "3.1.3"
|
||||||
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
||||||
@@ -2337,6 +2421,11 @@ hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7:
|
|||||||
inherits "^2.0.3"
|
inherits "^2.0.3"
|
||||||
minimalistic-assert "^1.0.1"
|
minimalistic-assert "^1.0.1"
|
||||||
|
|
||||||
|
hast-util-whitespace@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-2.0.0.tgz#4fc1086467cc1ef5ba20673cb6b03cec3a970f1c"
|
||||||
|
integrity sha512-Pkw+xBHuV6xFeJprJe2BBEoDV+AvQySaz3pPDRUs5PNZEMQjpXJJueqrpcHIXxnWTcAGi/UOCgVShlkY6kLoqg==
|
||||||
|
|
||||||
hmac-drbg@^1.0.1:
|
hmac-drbg@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz"
|
resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz"
|
||||||
@@ -2417,6 +2506,11 @@ inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3:
|
|||||||
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
|
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
|
||||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||||
|
|
||||||
|
inline-style-parser@0.1.1:
|
||||||
|
version "0.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1"
|
||||||
|
integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==
|
||||||
|
|
||||||
internal-slot@^1.0.3:
|
internal-slot@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz"
|
resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz"
|
||||||
@@ -2461,6 +2555,11 @@ is-boolean-object@^1.1.0:
|
|||||||
call-bind "^1.0.2"
|
call-bind "^1.0.2"
|
||||||
has-tostringtag "^1.0.0"
|
has-tostringtag "^1.0.0"
|
||||||
|
|
||||||
|
is-buffer@^2.0.0:
|
||||||
|
version "2.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191"
|
||||||
|
integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
|
||||||
|
|
||||||
is-callable@^1.1.4, is-callable@^1.2.4:
|
is-callable@^1.1.4, is-callable@^1.2.4:
|
||||||
version "1.2.4"
|
version "1.2.4"
|
||||||
resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz"
|
resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz"
|
||||||
@@ -2541,6 +2640,11 @@ is-number@^7.0.0:
|
|||||||
resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
|
resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
|
||||||
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
|
||||||
|
|
||||||
|
is-plain-obj@^4.0.0:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0"
|
||||||
|
integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==
|
||||||
|
|
||||||
is-plain-object@^5.0.0:
|
is-plain-object@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz"
|
resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz"
|
||||||
@@ -2742,6 +2846,11 @@ klaw-sync@^6.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
graceful-fs "^4.1.11"
|
graceful-fs "^4.1.11"
|
||||||
|
|
||||||
|
kleur@^4.0.3:
|
||||||
|
version "4.1.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780"
|
||||||
|
integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==
|
||||||
|
|
||||||
language-subtag-registry@~0.3.2:
|
language-subtag-registry@~0.3.2:
|
||||||
version "0.3.21"
|
version "0.3.21"
|
||||||
resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz"
|
resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz"
|
||||||
@@ -2874,6 +2983,60 @@ md5.js@^1.3.4:
|
|||||||
inherits "^2.0.1"
|
inherits "^2.0.1"
|
||||||
safe-buffer "^5.1.2"
|
safe-buffer "^5.1.2"
|
||||||
|
|
||||||
|
mdast-util-definitions@^5.0.0:
|
||||||
|
version "5.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-5.1.1.tgz#2c1d684b28e53f84938bb06317944bee8efa79db"
|
||||||
|
integrity sha512-rQ+Gv7mHttxHOBx2dkF4HWTg+EE+UR78ptQWDylzPKaQuVGdG4HIoY3SrS/pCp80nZ04greFvXbVFHT+uf0JVQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/mdast" "^3.0.0"
|
||||||
|
"@types/unist" "^2.0.0"
|
||||||
|
unist-util-visit "^4.0.0"
|
||||||
|
|
||||||
|
mdast-util-from-markdown@^1.0.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-1.2.0.tgz#84df2924ccc6c995dec1e2368b2b208ad0a76268"
|
||||||
|
integrity sha512-iZJyyvKD1+K7QX1b5jXdE7Sc5dtoTry1vzV28UZZe8Z1xVnB/czKntJ7ZAkG0tANqRnBF6p3p7GpU1y19DTf2Q==
|
||||||
|
dependencies:
|
||||||
|
"@types/mdast" "^3.0.0"
|
||||||
|
"@types/unist" "^2.0.0"
|
||||||
|
decode-named-character-reference "^1.0.0"
|
||||||
|
mdast-util-to-string "^3.1.0"
|
||||||
|
micromark "^3.0.0"
|
||||||
|
micromark-util-decode-numeric-character-reference "^1.0.0"
|
||||||
|
micromark-util-decode-string "^1.0.0"
|
||||||
|
micromark-util-normalize-identifier "^1.0.0"
|
||||||
|
micromark-util-symbol "^1.0.0"
|
||||||
|
micromark-util-types "^1.0.0"
|
||||||
|
unist-util-stringify-position "^3.0.0"
|
||||||
|
uvu "^0.5.0"
|
||||||
|
|
||||||
|
mdast-util-to-hast@^12.1.0:
|
||||||
|
version "12.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-12.2.0.tgz#4dbff7ab2b20b8d12fc8fe98bf804d97e7358cbf"
|
||||||
|
integrity sha512-YDwT5KhGzLgPpSnQhAlK1+WpCW4gsPmNNAxUNMkMTDhxQyPp2eX86WOelnKnLKEvSpfxqJbPbInHFkefXZBhEA==
|
||||||
|
dependencies:
|
||||||
|
"@types/hast" "^2.0.0"
|
||||||
|
"@types/mdast" "^3.0.0"
|
||||||
|
"@types/mdurl" "^1.0.0"
|
||||||
|
mdast-util-definitions "^5.0.0"
|
||||||
|
mdurl "^1.0.0"
|
||||||
|
micromark-util-sanitize-uri "^1.0.0"
|
||||||
|
trim-lines "^3.0.0"
|
||||||
|
unist-builder "^3.0.0"
|
||||||
|
unist-util-generated "^2.0.0"
|
||||||
|
unist-util-position "^4.0.0"
|
||||||
|
unist-util-visit "^4.0.0"
|
||||||
|
|
||||||
|
mdast-util-to-string@^3.1.0:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz#56c506d065fbf769515235e577b5a261552d56e9"
|
||||||
|
integrity sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==
|
||||||
|
|
||||||
|
mdurl@^1.0.0:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
|
||||||
|
integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==
|
||||||
|
|
||||||
memoize-one@^5.0.0:
|
memoize-one@^5.0.0:
|
||||||
version "5.2.1"
|
version "5.2.1"
|
||||||
resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz"
|
resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz"
|
||||||
@@ -2889,6 +3052,201 @@ merge2@^1.3.0, merge2@^1.4.1:
|
|||||||
resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
|
resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
|
||||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||||
|
|
||||||
|
micromark-core-commonmark@^1.0.1:
|
||||||
|
version "1.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz#edff4c72e5993d93724a3c206970f5a15b0585ad"
|
||||||
|
integrity sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA==
|
||||||
|
dependencies:
|
||||||
|
decode-named-character-reference "^1.0.0"
|
||||||
|
micromark-factory-destination "^1.0.0"
|
||||||
|
micromark-factory-label "^1.0.0"
|
||||||
|
micromark-factory-space "^1.0.0"
|
||||||
|
micromark-factory-title "^1.0.0"
|
||||||
|
micromark-factory-whitespace "^1.0.0"
|
||||||
|
micromark-util-character "^1.0.0"
|
||||||
|
micromark-util-chunked "^1.0.0"
|
||||||
|
micromark-util-classify-character "^1.0.0"
|
||||||
|
micromark-util-html-tag-name "^1.0.0"
|
||||||
|
micromark-util-normalize-identifier "^1.0.0"
|
||||||
|
micromark-util-resolve-all "^1.0.0"
|
||||||
|
micromark-util-subtokenize "^1.0.0"
|
||||||
|
micromark-util-symbol "^1.0.0"
|
||||||
|
micromark-util-types "^1.0.1"
|
||||||
|
uvu "^0.5.0"
|
||||||
|
|
||||||
|
micromark-factory-destination@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz#fef1cb59ad4997c496f887b6977aa3034a5a277e"
|
||||||
|
integrity sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==
|
||||||
|
dependencies:
|
||||||
|
micromark-util-character "^1.0.0"
|
||||||
|
micromark-util-symbol "^1.0.0"
|
||||||
|
micromark-util-types "^1.0.0"
|
||||||
|
|
||||||
|
micromark-factory-label@^1.0.0:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-1.0.2.tgz#6be2551fa8d13542fcbbac478258fb7a20047137"
|
||||||
|
integrity sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg==
|
||||||
|
dependencies:
|
||||||
|
micromark-util-character "^1.0.0"
|
||||||
|
micromark-util-symbol "^1.0.0"
|
||||||
|
micromark-util-types "^1.0.0"
|
||||||
|
uvu "^0.5.0"
|
||||||
|
|
||||||
|
micromark-factory-space@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz#cebff49968f2b9616c0fcb239e96685cb9497633"
|
||||||
|
integrity sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==
|
||||||
|
dependencies:
|
||||||
|
micromark-util-character "^1.0.0"
|
||||||
|
micromark-util-types "^1.0.0"
|
||||||
|
|
||||||
|
micromark-factory-title@^1.0.0:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-1.0.2.tgz#7e09287c3748ff1693930f176e1c4a328382494f"
|
||||||
|
integrity sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A==
|
||||||
|
dependencies:
|
||||||
|
micromark-factory-space "^1.0.0"
|
||||||
|
micromark-util-character "^1.0.0"
|
||||||
|
micromark-util-symbol "^1.0.0"
|
||||||
|
micromark-util-types "^1.0.0"
|
||||||
|
uvu "^0.5.0"
|
||||||
|
|
||||||
|
micromark-factory-whitespace@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz#e991e043ad376c1ba52f4e49858ce0794678621c"
|
||||||
|
integrity sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==
|
||||||
|
dependencies:
|
||||||
|
micromark-factory-space "^1.0.0"
|
||||||
|
micromark-util-character "^1.0.0"
|
||||||
|
micromark-util-symbol "^1.0.0"
|
||||||
|
micromark-util-types "^1.0.0"
|
||||||
|
|
||||||
|
micromark-util-character@^1.0.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.1.0.tgz#d97c54d5742a0d9611a68ca0cd4124331f264d86"
|
||||||
|
integrity sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==
|
||||||
|
dependencies:
|
||||||
|
micromark-util-symbol "^1.0.0"
|
||||||
|
micromark-util-types "^1.0.0"
|
||||||
|
|
||||||
|
micromark-util-chunked@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz#5b40d83f3d53b84c4c6bce30ed4257e9a4c79d06"
|
||||||
|
integrity sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==
|
||||||
|
dependencies:
|
||||||
|
micromark-util-symbol "^1.0.0"
|
||||||
|
|
||||||
|
micromark-util-classify-character@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz#cbd7b447cb79ee6997dd274a46fc4eb806460a20"
|
||||||
|
integrity sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==
|
||||||
|
dependencies:
|
||||||
|
micromark-util-character "^1.0.0"
|
||||||
|
micromark-util-symbol "^1.0.0"
|
||||||
|
micromark-util-types "^1.0.0"
|
||||||
|
|
||||||
|
micromark-util-combine-extensions@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz#91418e1e74fb893e3628b8d496085639124ff3d5"
|
||||||
|
integrity sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==
|
||||||
|
dependencies:
|
||||||
|
micromark-util-chunked "^1.0.0"
|
||||||
|
micromark-util-types "^1.0.0"
|
||||||
|
|
||||||
|
micromark-util-decode-numeric-character-reference@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz#dcc85f13b5bd93ff8d2868c3dba28039d490b946"
|
||||||
|
integrity sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==
|
||||||
|
dependencies:
|
||||||
|
micromark-util-symbol "^1.0.0"
|
||||||
|
|
||||||
|
micromark-util-decode-string@^1.0.0:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-1.0.2.tgz#942252ab7a76dec2dbf089cc32505ee2bc3acf02"
|
||||||
|
integrity sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q==
|
||||||
|
dependencies:
|
||||||
|
decode-named-character-reference "^1.0.0"
|
||||||
|
micromark-util-character "^1.0.0"
|
||||||
|
micromark-util-decode-numeric-character-reference "^1.0.0"
|
||||||
|
micromark-util-symbol "^1.0.0"
|
||||||
|
|
||||||
|
micromark-util-encode@^1.0.0:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-1.0.1.tgz#2c1c22d3800870ad770ece5686ebca5920353383"
|
||||||
|
integrity sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA==
|
||||||
|
|
||||||
|
micromark-util-html-tag-name@^1.0.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.1.0.tgz#eb227118befd51f48858e879b7a419fc0df20497"
|
||||||
|
integrity sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA==
|
||||||
|
|
||||||
|
micromark-util-normalize-identifier@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz#4a3539cb8db954bbec5203952bfe8cedadae7828"
|
||||||
|
integrity sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==
|
||||||
|
dependencies:
|
||||||
|
micromark-util-symbol "^1.0.0"
|
||||||
|
|
||||||
|
micromark-util-resolve-all@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz#a7c363f49a0162e931960c44f3127ab58f031d88"
|
||||||
|
integrity sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==
|
||||||
|
dependencies:
|
||||||
|
micromark-util-types "^1.0.0"
|
||||||
|
|
||||||
|
micromark-util-sanitize-uri@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.0.0.tgz#27dc875397cd15102274c6c6da5585d34d4f12b2"
|
||||||
|
integrity sha512-cCxvBKlmac4rxCGx6ejlIviRaMKZc0fWm5HdCHEeDWRSkn44l6NdYVRyU+0nT1XC72EQJMZV8IPHF+jTr56lAg==
|
||||||
|
dependencies:
|
||||||
|
micromark-util-character "^1.0.0"
|
||||||
|
micromark-util-encode "^1.0.0"
|
||||||
|
micromark-util-symbol "^1.0.0"
|
||||||
|
|
||||||
|
micromark-util-subtokenize@^1.0.0:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.2.tgz#ff6f1af6ac836f8bfdbf9b02f40431760ad89105"
|
||||||
|
integrity sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA==
|
||||||
|
dependencies:
|
||||||
|
micromark-util-chunked "^1.0.0"
|
||||||
|
micromark-util-symbol "^1.0.0"
|
||||||
|
micromark-util-types "^1.0.0"
|
||||||
|
uvu "^0.5.0"
|
||||||
|
|
||||||
|
micromark-util-symbol@^1.0.0:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.0.1.tgz#b90344db62042ce454f351cf0bebcc0a6da4920e"
|
||||||
|
integrity sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ==
|
||||||
|
|
||||||
|
micromark-util-types@^1.0.0, micromark-util-types@^1.0.1:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.0.2.tgz#f4220fdb319205812f99c40f8c87a9be83eded20"
|
||||||
|
integrity sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w==
|
||||||
|
|
||||||
|
micromark@^3.0.0:
|
||||||
|
version "3.0.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/micromark/-/micromark-3.0.10.tgz#1eac156f0399d42736458a14b0ca2d86190b457c"
|
||||||
|
integrity sha512-ryTDy6UUunOXy2HPjelppgJ2sNfcPz1pLlMdA6Rz9jPzhLikWXv/irpWV/I2jd68Uhmny7hHxAlAhk4+vWggpg==
|
||||||
|
dependencies:
|
||||||
|
"@types/debug" "^4.0.0"
|
||||||
|
debug "^4.0.0"
|
||||||
|
decode-named-character-reference "^1.0.0"
|
||||||
|
micromark-core-commonmark "^1.0.1"
|
||||||
|
micromark-factory-space "^1.0.0"
|
||||||
|
micromark-util-character "^1.0.0"
|
||||||
|
micromark-util-chunked "^1.0.0"
|
||||||
|
micromark-util-combine-extensions "^1.0.0"
|
||||||
|
micromark-util-decode-numeric-character-reference "^1.0.0"
|
||||||
|
micromark-util-encode "^1.0.0"
|
||||||
|
micromark-util-normalize-identifier "^1.0.0"
|
||||||
|
micromark-util-resolve-all "^1.0.0"
|
||||||
|
micromark-util-sanitize-uri "^1.0.0"
|
||||||
|
micromark-util-subtokenize "^1.0.0"
|
||||||
|
micromark-util-symbol "^1.0.0"
|
||||||
|
micromark-util-types "^1.0.1"
|
||||||
|
uvu "^0.5.0"
|
||||||
|
|
||||||
micromatch@^4.0.2, micromatch@^4.0.4:
|
micromatch@^4.0.2, micromatch@^4.0.4:
|
||||||
version "4.0.4"
|
version "4.0.4"
|
||||||
resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz"
|
resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz"
|
||||||
@@ -2924,6 +3282,11 @@ monaco-editor@^0.33.0:
|
|||||||
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.33.0.tgz#842e244f3750a2482f8a29c676b5684e75ff34af"
|
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.33.0.tgz#842e244f3750a2482f8a29c676b5684e75ff34af"
|
||||||
integrity sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw==
|
integrity sha512-VcRWPSLIUEgQJQIE0pVT8FcGBIgFoxz7jtqctE+IiCxWugD0DwgyQBcZBhdSrdMC84eumoqMZsGl2GTreOzwqw==
|
||||||
|
|
||||||
|
mri@^1.1.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
|
||||||
|
integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==
|
||||||
|
|
||||||
ms@2.0.0:
|
ms@2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
|
resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
|
||||||
@@ -2954,10 +3317,10 @@ natural-compare@^1.4.0:
|
|||||||
resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
|
resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
|
||||||
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
||||||
|
|
||||||
next-auth@^4.0.0-beta.5:
|
next-auth@^4.10.3:
|
||||||
version "4.2.1"
|
version "4.10.3"
|
||||||
resolved "https://registry.npmjs.org/next-auth/-/next-auth-4.2.1.tgz"
|
resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.10.3.tgz#0a952dd5004fd2ac2ba414c990922cf9b33951a3"
|
||||||
integrity sha512-XDtt7nqevkNf4EJ2zKAKkI+MFsURf11kx11vPwxrBYA1MHeqWwaWbGOUOI2ekNTvfAg4nTEJJUH3LV2cLrH3Tg==
|
integrity sha512-7zc4aXYc/EEln7Pkcsn21V1IevaTZsMLJwapfbnKA4+JY0+jFzWbt5p/ljugesGIrN4VOZhpZIw50EaFZyghJQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.16.3"
|
"@babel/runtime" "^7.16.3"
|
||||||
"@panva/hkdf" "^1.0.1"
|
"@panva/hkdf" "^1.0.1"
|
||||||
@@ -3340,7 +3703,7 @@ progress@^2.0.0:
|
|||||||
resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz"
|
resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz"
|
||||||
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
||||||
|
|
||||||
prop-types@^15.5.7, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
prop-types@^15.0.0, prop-types@^15.5.7, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||||
version "15.8.1"
|
version "15.8.1"
|
||||||
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
|
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
|
||||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||||
@@ -3349,6 +3712,11 @@ prop-types@^15.5.7, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2,
|
|||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
react-is "^16.13.1"
|
react-is "^16.13.1"
|
||||||
|
|
||||||
|
property-information@^6.0.0:
|
||||||
|
version "6.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.1.1.tgz#5ca85510a3019726cb9afed4197b7b8ac5926a22"
|
||||||
|
integrity sha512-hrzC564QIl0r0vy4l6MvRLhafmUowhO/O3KgVSoXIbbA2Sz4j8HGpJc6T2cubRVwMwpdiG/vKGfhT4IixmKN9w==
|
||||||
|
|
||||||
proxy-compare@2.0.3:
|
proxy-compare@2.0.3:
|
||||||
version "2.0.3"
|
version "2.0.3"
|
||||||
resolved "https://registry.npmjs.org/proxy-compare/-/proxy-compare-2.0.3.tgz"
|
resolved "https://registry.npmjs.org/proxy-compare/-/proxy-compare-2.0.3.tgz"
|
||||||
@@ -3427,6 +3795,32 @@ react-is@^16.13.1, react-is@^16.7.0:
|
|||||||
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
||||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||||
|
|
||||||
|
react-is@^18.0.0:
|
||||||
|
version "18.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
|
||||||
|
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
|
||||||
|
|
||||||
|
react-markdown@^8.0.3:
|
||||||
|
version "8.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-8.0.3.tgz#e8aba0d2f5a1b2124d476ee1fff9448a2f57e4b3"
|
||||||
|
integrity sha512-We36SfqaKoVNpN1QqsZwWSv/OZt5J15LNgTLWynwAN5b265hrQrsjMtlRNwUvS+YyR3yDM8HpTNc4pK9H/Gc0A==
|
||||||
|
dependencies:
|
||||||
|
"@types/hast" "^2.0.0"
|
||||||
|
"@types/prop-types" "^15.0.0"
|
||||||
|
"@types/unist" "^2.0.0"
|
||||||
|
comma-separated-tokens "^2.0.0"
|
||||||
|
hast-util-whitespace "^2.0.0"
|
||||||
|
prop-types "^15.0.0"
|
||||||
|
property-information "^6.0.0"
|
||||||
|
react-is "^18.0.0"
|
||||||
|
remark-parse "^10.0.0"
|
||||||
|
remark-rehype "^10.0.0"
|
||||||
|
space-separated-tokens "^2.0.0"
|
||||||
|
style-to-object "^0.3.0"
|
||||||
|
unified "^10.0.0"
|
||||||
|
unist-util-visit "^4.0.0"
|
||||||
|
vfile "^5.0.0"
|
||||||
|
|
||||||
react-new-window@^0.2.1:
|
react-new-window@^0.2.1:
|
||||||
version "0.2.1"
|
version "0.2.1"
|
||||||
resolved "https://registry.npmjs.org/react-new-window/-/react-new-window-0.2.1.tgz"
|
resolved "https://registry.npmjs.org/react-new-window/-/react-new-window-0.2.1.tgz"
|
||||||
@@ -3545,11 +3939,6 @@ reconnecting-websocket@^4.4.0:
|
|||||||
resolved "https://registry.npmjs.org/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz"
|
resolved "https://registry.npmjs.org/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz"
|
||||||
integrity sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng==
|
integrity sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng==
|
||||||
|
|
||||||
regenerator-runtime@^0.11.0:
|
|
||||||
version "0.11.1"
|
|
||||||
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz"
|
|
||||||
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
|
|
||||||
|
|
||||||
regenerator-runtime@^0.13.4:
|
regenerator-runtime@^0.13.4:
|
||||||
version "0.13.9"
|
version "0.13.9"
|
||||||
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz"
|
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz"
|
||||||
@@ -3578,6 +3967,25 @@ relative-time-format@^1.0.7:
|
|||||||
resolved "https://registry.npmjs.org/relative-time-format/-/relative-time-format-1.0.7.tgz"
|
resolved "https://registry.npmjs.org/relative-time-format/-/relative-time-format-1.0.7.tgz"
|
||||||
integrity sha512-BoLPaoL5y94ngPI4iJ9mNHqRS8NA+Hjs6oYHL5UYkbnA7/iTlvJiMoQQt8txhHhc+Y3e6yXWhwTAKvsQhnx2yg==
|
integrity sha512-BoLPaoL5y94ngPI4iJ9mNHqRS8NA+Hjs6oYHL5UYkbnA7/iTlvJiMoQQt8txhHhc+Y3e6yXWhwTAKvsQhnx2yg==
|
||||||
|
|
||||||
|
remark-parse@^10.0.0:
|
||||||
|
version "10.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-10.0.1.tgz#6f60ae53edbf0cf38ea223fe643db64d112e0775"
|
||||||
|
integrity sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==
|
||||||
|
dependencies:
|
||||||
|
"@types/mdast" "^3.0.0"
|
||||||
|
mdast-util-from-markdown "^1.0.0"
|
||||||
|
unified "^10.0.0"
|
||||||
|
|
||||||
|
remark-rehype@^10.0.0:
|
||||||
|
version "10.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-10.1.0.tgz#32dc99d2034c27ecaf2e0150d22a6dcccd9a6279"
|
||||||
|
integrity sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==
|
||||||
|
dependencies:
|
||||||
|
"@types/hast" "^2.0.0"
|
||||||
|
"@types/mdast" "^3.0.0"
|
||||||
|
mdast-util-to-hast "^12.1.0"
|
||||||
|
unified "^10.0.0"
|
||||||
|
|
||||||
require-from-string@^2.0.2:
|
require-from-string@^2.0.2:
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
|
resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
|
||||||
@@ -3648,30 +4056,25 @@ ripple-address-codec@^4.1.0, ripple-address-codec@^4.1.1, ripple-address-codec@^
|
|||||||
base-x "3.0.9"
|
base-x "3.0.9"
|
||||||
create-hash "^1.1.2"
|
create-hash "^1.1.2"
|
||||||
|
|
||||||
ripple-binary-codec@^0.2.4:
|
ripple-address-codec@^4.2.4:
|
||||||
version "0.2.7"
|
version "4.2.4"
|
||||||
resolved "https://registry.npmjs.org/ripple-binary-codec/-/ripple-binary-codec-0.2.7.tgz"
|
resolved "https://registry.yarnpkg.com/ripple-address-codec/-/ripple-address-codec-4.2.4.tgz#a56c2168c8bb81269ea4d15ed96d6824c5a866f8"
|
||||||
integrity sha512-VD+sHgZK76q3kmO765klFHPDCEveS5SUeg/bUNVpNrj7w2alyDNkbF17XNbAjFv+kSYhfsUudQanoaSs2Y6uzw==
|
integrity sha512-roAOjKz94+FboTItey1XRh5qynwt4xvfBLvbbcx+FiR94Yw2x3LrKLF2GVCMCSAh5I6PkcpADg6AbYsUbGN3nA==
|
||||||
dependencies:
|
dependencies:
|
||||||
babel-runtime "^6.26.0"
|
base-x "3.0.9"
|
||||||
bn.js "^5.1.1"
|
create-hash "^1.1.2"
|
||||||
create-hash "^1.2.0"
|
|
||||||
decimal.js "^10.2.0"
|
|
||||||
inherits "^2.0.4"
|
|
||||||
lodash "^4.17.15"
|
|
||||||
ripple-address-codec "^4.1.0"
|
|
||||||
|
|
||||||
ripple-binary-codec@^1.1.3, ripple-binary-codec@^1.3.0:
|
ripple-binary-codec@=1.4.2, ripple-binary-codec@^0.2.4, ripple-binary-codec@^1.1.3, ripple-binary-codec@^1.4.2:
|
||||||
version "1.3.2"
|
version "1.4.2"
|
||||||
resolved "https://registry.npmjs.org/ripple-binary-codec/-/ripple-binary-codec-1.3.2.tgz"
|
resolved "https://registry.yarnpkg.com/ripple-binary-codec/-/ripple-binary-codec-1.4.2.tgz#cdc35353e4bc7c3a704719247c82b4c4d0b57dd3"
|
||||||
integrity sha512-8VG1vfb3EM1J7ZdPXo9E57Zv2hF4cxT64gP6rGSQzODVgMjiBCWozhN3729qNTGtHItz0e82Oix8v95vWYBQ3A==
|
integrity sha512-EDKIyZMa/6Ay/oNgCwjD9b9CJv0zmBreeHVQeG4BYwy+9GPnIQjNeT5e/aB6OjAnhcmpgbPeBmzwmNVwzxlt0w==
|
||||||
dependencies:
|
dependencies:
|
||||||
assert "^2.0.0"
|
assert "^2.0.0"
|
||||||
big-integer "^1.6.48"
|
big-integer "^1.6.48"
|
||||||
buffer "5.6.0"
|
buffer "5.6.0"
|
||||||
create-hash "^1.2.0"
|
create-hash "^1.2.0"
|
||||||
decimal.js "^10.2.0"
|
decimal.js "^10.2.0"
|
||||||
ripple-address-codec "^4.2.3"
|
ripple-address-codec "^4.2.4"
|
||||||
|
|
||||||
ripple-bs58@^4.0.0:
|
ripple-bs58@^4.0.0:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
@@ -3749,6 +4152,13 @@ run-parallel@^1.1.9:
|
|||||||
dependencies:
|
dependencies:
|
||||||
queue-microtask "^1.2.2"
|
queue-microtask "^1.2.2"
|
||||||
|
|
||||||
|
sade@^1.7.3:
|
||||||
|
version "1.8.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701"
|
||||||
|
integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==
|
||||||
|
dependencies:
|
||||||
|
mri "^1.1.0"
|
||||||
|
|
||||||
safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0:
|
safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0:
|
||||||
version "5.2.1"
|
version "5.2.1"
|
||||||
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
|
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
|
||||||
@@ -3868,6 +4278,11 @@ source-map@^0.5.7:
|
|||||||
resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz"
|
resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz"
|
||||||
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
||||||
|
|
||||||
|
space-separated-tokens@^2.0.0:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz#43193cec4fb858a2ce934b7f98b7f2c18107098b"
|
||||||
|
integrity sha512-ekwEbFp5aqSPKaqeY1PGrlGQxPNaq+Cnx4+bE2D8sciBQrHpbwoBbawqTN2+6jPs9IdWxxiUcN0K2pkczD3zmw==
|
||||||
|
|
||||||
split.js@^1.6.0:
|
split.js@^1.6.0:
|
||||||
version "1.6.5"
|
version "1.6.5"
|
||||||
resolved "https://registry.npmjs.org/split.js/-/split.js-1.6.5.tgz"
|
resolved "https://registry.npmjs.org/split.js/-/split.js-1.6.5.tgz"
|
||||||
@@ -3953,6 +4368,13 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
|
|||||||
resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz"
|
resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz"
|
||||||
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
|
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
|
||||||
|
|
||||||
|
style-to-object@^0.3.0:
|
||||||
|
version "0.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46"
|
||||||
|
integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==
|
||||||
|
dependencies:
|
||||||
|
inline-style-parser "0.1.1"
|
||||||
|
|
||||||
styled-jsx@5.0.0:
|
styled-jsx@5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.0.tgz"
|
resolved "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.0.tgz"
|
||||||
@@ -4038,6 +4460,16 @@ tr46@~0.0.3:
|
|||||||
resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz"
|
resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz"
|
||||||
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
|
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
|
||||||
|
|
||||||
|
trim-lines@^3.0.0:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338"
|
||||||
|
integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==
|
||||||
|
|
||||||
|
trough@^2.0.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/trough/-/trough-2.1.0.tgz#0f7b511a4fde65a46f18477ab38849b22c554876"
|
||||||
|
integrity sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==
|
||||||
|
|
||||||
tsconfig-paths@^3.12.0, tsconfig-paths@^3.9.0:
|
tsconfig-paths@^3.12.0, tsconfig-paths@^3.9.0:
|
||||||
version "3.13.0"
|
version "3.13.0"
|
||||||
resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.13.0.tgz"
|
resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.13.0.tgz"
|
||||||
@@ -4109,6 +4541,67 @@ unbox-primitive@^1.0.1:
|
|||||||
has-symbols "^1.0.2"
|
has-symbols "^1.0.2"
|
||||||
which-boxed-primitive "^1.0.2"
|
which-boxed-primitive "^1.0.2"
|
||||||
|
|
||||||
|
unified@^10.0.0:
|
||||||
|
version "10.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/unified/-/unified-10.1.2.tgz#b1d64e55dafe1f0b98bb6c719881103ecf6c86df"
|
||||||
|
integrity sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==
|
||||||
|
dependencies:
|
||||||
|
"@types/unist" "^2.0.0"
|
||||||
|
bail "^2.0.0"
|
||||||
|
extend "^3.0.0"
|
||||||
|
is-buffer "^2.0.0"
|
||||||
|
is-plain-obj "^4.0.0"
|
||||||
|
trough "^2.0.0"
|
||||||
|
vfile "^5.0.0"
|
||||||
|
|
||||||
|
unist-builder@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-3.0.0.tgz#728baca4767c0e784e1e64bb44b5a5a753021a04"
|
||||||
|
integrity sha512-GFxmfEAa0vi9i5sd0R2kcrI9ks0r82NasRq5QHh2ysGngrc6GiqD5CDf1FjPenY4vApmFASBIIlk/jj5J5YbmQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/unist" "^2.0.0"
|
||||||
|
|
||||||
|
unist-util-generated@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-2.0.0.tgz#86fafb77eb6ce9bfa6b663c3f5ad4f8e56a60113"
|
||||||
|
integrity sha512-TiWE6DVtVe7Ye2QxOVW9kqybs6cZexNwTwSMVgkfjEReqy/xwGpAXb99OxktoWwmL+Z+Epb0Dn8/GNDYP1wnUw==
|
||||||
|
|
||||||
|
unist-util-is@^5.0.0:
|
||||||
|
version "5.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.1.1.tgz#e8aece0b102fa9bc097b0fef8f870c496d4a6236"
|
||||||
|
integrity sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==
|
||||||
|
|
||||||
|
unist-util-position@^4.0.0:
|
||||||
|
version "4.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-4.0.3.tgz#5290547b014f6222dff95c48d5c3c13a88fadd07"
|
||||||
|
integrity sha512-p/5EMGIa1qwbXjA+QgcBXaPWjSnZfQ2Sc3yBEEfgPwsEmJd8Qh+DSk3LGnmOM4S1bY2C0AjmMnB8RuEYxpPwXQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/unist" "^2.0.0"
|
||||||
|
|
||||||
|
unist-util-stringify-position@^3.0.0:
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.2.tgz#5c6aa07c90b1deffd9153be170dce628a869a447"
|
||||||
|
integrity sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==
|
||||||
|
dependencies:
|
||||||
|
"@types/unist" "^2.0.0"
|
||||||
|
|
||||||
|
unist-util-visit-parents@^5.0.0:
|
||||||
|
version "5.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.0.tgz#44bbc5d25f2411e7dfc5cecff12de43296aa8521"
|
||||||
|
integrity sha512-y+QVLcY5eR/YVpqDsLf/xh9R3Q2Y4HxkZTp7ViLDU6WtJCEcPmRzW1gpdWDCDIqIlhuPDXOgttqPlykrHYDekg==
|
||||||
|
dependencies:
|
||||||
|
"@types/unist" "^2.0.0"
|
||||||
|
unist-util-is "^5.0.0"
|
||||||
|
|
||||||
|
unist-util-visit@^4.0.0:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-4.1.0.tgz#f41e407a9e94da31594e6b1c9811c51ab0b3d8f5"
|
||||||
|
integrity sha512-n7lyhFKJfVZ9MnKtqbsqkQEk5P1KShj0+//V7mAcoI6bpbUjh3C/OG8HVD+pBihfh6Ovl01m8dkcv9HNqYajmQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/unist" "^2.0.0"
|
||||||
|
unist-util-is "^5.0.0"
|
||||||
|
unist-util-visit-parents "^5.0.0"
|
||||||
|
|
||||||
universal-github-app-jwt@^1.0.1:
|
universal-github-app-jwt@^1.0.1:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-1.1.0.tgz"
|
resolved "https://registry.npmjs.org/universal-github-app-jwt/-/universal-github-app-jwt-1.1.0.tgz"
|
||||||
@@ -4183,6 +4676,16 @@ uuid@^8.3.2:
|
|||||||
resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz"
|
resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz"
|
||||||
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
||||||
|
|
||||||
|
uvu@^0.5.0:
|
||||||
|
version "0.5.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.6.tgz#2754ca20bcb0bb59b64e9985e84d2e81058502df"
|
||||||
|
integrity sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==
|
||||||
|
dependencies:
|
||||||
|
dequal "^2.0.0"
|
||||||
|
diff "^5.0.0"
|
||||||
|
kleur "^4.0.3"
|
||||||
|
sade "^1.7.3"
|
||||||
|
|
||||||
v8-compile-cache@^2.0.3:
|
v8-compile-cache@^2.0.3:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz"
|
resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz"
|
||||||
@@ -4195,6 +4698,24 @@ valtio@^1.2.5:
|
|||||||
dependencies:
|
dependencies:
|
||||||
proxy-compare "2.0.3"
|
proxy-compare "2.0.3"
|
||||||
|
|
||||||
|
vfile-message@^3.0.0:
|
||||||
|
version "3.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.1.2.tgz#a2908f64d9e557315ec9d7ea3a910f658ac05f7d"
|
||||||
|
integrity sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA==
|
||||||
|
dependencies:
|
||||||
|
"@types/unist" "^2.0.0"
|
||||||
|
unist-util-stringify-position "^3.0.0"
|
||||||
|
|
||||||
|
vfile@^5.0.0:
|
||||||
|
version "5.3.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/vfile/-/vfile-5.3.4.tgz#bbb8c96b956693bbf70b2c67fdb5781dff769b93"
|
||||||
|
integrity sha512-KI+7cnst03KbEyN1+JE504zF5bJBZa+J+CrevLeyIMq0aPU681I2rQ5p4PlnQ6exFtWiUrg26QUdFMnAKR6PIw==
|
||||||
|
dependencies:
|
||||||
|
"@types/unist" "^2.0.0"
|
||||||
|
is-buffer "^2.0.0"
|
||||||
|
unist-util-stringify-position "^3.0.0"
|
||||||
|
vfile-message "^3.0.0"
|
||||||
|
|
||||||
vscode-jsonrpc@6.0.0, vscode-jsonrpc@^6.0.0:
|
vscode-jsonrpc@6.0.0, vscode-jsonrpc@^6.0.0:
|
||||||
version "6.0.0"
|
version "6.0.0"
|
||||||
resolved "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz"
|
resolved "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz"
|
||||||
@@ -4328,10 +4849,10 @@ ws@^7.2.0:
|
|||||||
resolved "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz"
|
resolved "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz"
|
||||||
integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==
|
integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==
|
||||||
|
|
||||||
xrpl-accountlib@^1.3.2:
|
xrpl-accountlib@^1.5.2:
|
||||||
version "1.3.2"
|
version "1.5.2"
|
||||||
resolved "https://registry.npmjs.org/xrpl-accountlib/-/xrpl-accountlib-1.3.2.tgz"
|
resolved "https://registry.yarnpkg.com/xrpl-accountlib/-/xrpl-accountlib-1.5.2.tgz#8f16abe449fd60ba9ed75597f6ce3f0c45dfff43"
|
||||||
integrity sha512-mXwoumGp0xUiZ7Ty/1o4FHVRK4uLnqngxdYmikZs50drMjlgCUP6GXun2Vf4Uus1fnVnxhXIw+E7peH5OjiOJA==
|
integrity sha512-lieY2/5G9DySqdtgQ0AD/aMMG5Sy/MLAmbIsmsCaF06scM5DpR8s4SsEzgHni7dOG68Wjnb2Uz6tf5aV+l4/Kg==
|
||||||
dependencies:
|
dependencies:
|
||||||
assert "^2.0.0"
|
assert "^2.0.0"
|
||||||
bip32 "^2.0.5"
|
bip32 "^2.0.5"
|
||||||
@@ -4340,13 +4861,13 @@ xrpl-accountlib@^1.3.2:
|
|||||||
elliptic "6.5.4"
|
elliptic "6.5.4"
|
||||||
hash.js "^1.1.7"
|
hash.js "^1.1.7"
|
||||||
ripple-address-codec "^4.1.0"
|
ripple-address-codec "^4.1.0"
|
||||||
ripple-binary-codec "^1.3.0"
|
ripple-binary-codec "^1.4.2"
|
||||||
ripple-hashes "^0.3.4"
|
ripple-hashes "^0.3.4"
|
||||||
ripple-keypairs "^1.0.3"
|
ripple-keypairs "^1.0.3"
|
||||||
ripple-lib "^1.6.4"
|
ripple-lib "^1.6.4"
|
||||||
ripple-secret-codec "^1.0.2"
|
ripple-secret-codec "^1.0.2"
|
||||||
xrpl-secret-numbers "^0.3.3"
|
xrpl-secret-numbers "^0.3.3"
|
||||||
xrpl-sign-keypairs "^2.0.1"
|
xrpl-sign-keypairs "^2.1.1"
|
||||||
|
|
||||||
xrpl-client@^1.9.4:
|
xrpl-client@^1.9.4:
|
||||||
version "1.9.4"
|
version "1.9.4"
|
||||||
@@ -4365,13 +4886,13 @@ xrpl-secret-numbers@^0.3.3:
|
|||||||
brorand "^1.1.0"
|
brorand "^1.1.0"
|
||||||
ripple-keypairs "^1.0.3"
|
ripple-keypairs "^1.0.3"
|
||||||
|
|
||||||
xrpl-sign-keypairs@^2.0.1:
|
xrpl-sign-keypairs@^2.1.1:
|
||||||
version "2.0.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.npmjs.org/xrpl-sign-keypairs/-/xrpl-sign-keypairs-2.0.1.tgz"
|
resolved "https://registry.yarnpkg.com/xrpl-sign-keypairs/-/xrpl-sign-keypairs-2.1.1.tgz#2f7f2855799c5d4ba091007963825eef1db21a4e"
|
||||||
integrity sha512-84QbE3trxetaw0hqDADCWMx0HH1VAWnTJp0TGoKTGRf1jzTqjI7eNNNw5lmcay2MH8bW/waNzJIF8vSAJSkVrQ==
|
integrity sha512-rKQmUCx+x7gjjJ5zv/Z7bOYR+8I36JwUCFlpuD9UzYD4w2msGQDG0rmxVENyZSfThDBVQ1kEArVn6SMDMe9LUQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
big-integer latest
|
big-integer latest
|
||||||
ripple-binary-codec "^1.3.0"
|
ripple-binary-codec "^1.4.2"
|
||||||
ripple-bs58check latest
|
ripple-bs58check latest
|
||||||
ripple-hashes latest
|
ripple-hashes latest
|
||||||
ripple-keypairs latest
|
ripple-keypairs latest
|
||||||
|
|||||||
Reference in New Issue
Block a user