mirror of
https://github.com/Unkn0wnCat/matrix-veles.git
synced 2025-04-28 09:46:51 +02:00
webui: Add hashing implementation
This commit is contained in:
parent
04a4584f74
commit
c0b44b5a89
6 changed files with 294 additions and 15 deletions
|
@ -17,12 +17,14 @@
|
|||
"@types/react-relay": "^13.0.1",
|
||||
"@types/react-table": "^7.7.12",
|
||||
"@types/relay-runtime": "^13.0.2",
|
||||
"animejs": "^3.2.1",
|
||||
"axios": "^0.27.2",
|
||||
"hamburger-react": "^2.5.0",
|
||||
"i18next": "^21.9.1",
|
||||
"i18next-browser-languagedetector": "^6.1.5",
|
||||
"i18next-http-backend": "^1.4.1",
|
||||
"i18next-parser": "^6.5.0",
|
||||
"js-sha512": "^0.8.0",
|
||||
"lucide-react": "^0.88.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
@ -60,6 +62,7 @@
|
|||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/animejs": "^3.1.5",
|
||||
"babel-plugin-relay": "^14.1.0",
|
||||
"graphql": "^16.3.0",
|
||||
"relay-compiler": "^13.2.0"
|
||||
|
|
|
@ -2,6 +2,98 @@
|
|||
|
||||
$slideOverBreakpoint: 1000px;
|
||||
|
||||
.modalOuter {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background-color: var(--veles-color-background-transparent);
|
||||
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
|
||||
transition: opacity .25s;
|
||||
|
||||
&.active {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.modalTitle {
|
||||
font-size: 1.5em;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.uploader {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 800px;
|
||||
max-height: 700px;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: var(--veles-color-background);
|
||||
padding: var(--veles-layout-padding);
|
||||
border: thin solid var(--veles-color-border);
|
||||
border-radius: var(--veles-layout-border-radius);
|
||||
overflow: hidden;
|
||||
|
||||
.dropArea {
|
||||
height: 200px;
|
||||
border: 5px dashed var(--veles-color-border);
|
||||
position: relative;
|
||||
|
||||
.dropAreaContent {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.fileList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: var(--veles-layout-padding);
|
||||
|
||||
> span {
|
||||
text-align: center;
|
||||
opacity: .75;
|
||||
padding: var(--veles-layout-padding-slim) var(--veles-layout-padding);
|
||||
}
|
||||
|
||||
.file {
|
||||
display: flex;
|
||||
padding: var(--veles-layout-padding-slim) var(--veles-layout-padding);
|
||||
border-bottom: thin solid var(--veles-color-border);
|
||||
|
||||
.fileName {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.fileHash {
|
||||
width: 200px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.roomsContainer {
|
||||
display: flex;
|
||||
height: calc(100% + 2*var(--veles-layout-padding));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, {useState} from "react";
|
||||
import React, {useCallback, useEffect, useRef, useState} from "react";
|
||||
import {useNavigate, useOutlet} from "react-router-dom";
|
||||
|
||||
import styles from "./Entries.module.scss";
|
||||
|
@ -9,11 +9,19 @@ import {graphql} from "babel-plugin-relay/macro";
|
|||
import {EntriesQuery} from "./__generated__/EntriesQuery.graphql";
|
||||
import {X} from "lucide-react";
|
||||
import {LoaderSuspense} from "../../../common/Loader";
|
||||
import {sha512} from "js-sha512";
|
||||
import {ReactComponent as Logo} from "../../../../logo.svg";
|
||||
import anime, {AnimeInstance} from "animejs";
|
||||
|
||||
type Props = {
|
||||
initialQueryRef: PreloadedQuery<EntriesQuery>,
|
||||
}
|
||||
|
||||
type UploadQueueEntry = {
|
||||
fileName: string
|
||||
fileHash: string
|
||||
}
|
||||
|
||||
const Entries = ({initialQueryRef}: Props) => {
|
||||
const outlet = useOutlet()
|
||||
const navigate = useNavigate()
|
||||
|
@ -32,14 +40,173 @@ const Entries = ({initialQueryRef}: Props) => {
|
|||
|
||||
const [title, setTitle] = useState(defaultTitle)
|
||||
|
||||
const [showUploader, setShowUploader] = useState(false)
|
||||
const [uploadCounter, setUploadCounter] = useState(0)
|
||||
|
||||
const uploadQueue = useRef<UploadQueueEntry[]>([])
|
||||
const incompleteCounter = useRef(0)
|
||||
const loadingAnimation = useRef<AnimeInstance>()
|
||||
const loadingLogo = useRef<SVGSVGElement>(null)
|
||||
|
||||
const setupAnim = useCallback(() => {
|
||||
if(!loadingLogo.current) return
|
||||
|
||||
if(incompleteCounter.current <= 0) {
|
||||
anime({
|
||||
targets: "#"+loadingLogo.current.id+" .number",
|
||||
duration: 500,
|
||||
easing: "easeInOutCubic",
|
||||
opacity: 1,
|
||||
})
|
||||
loadingAnimation.current = undefined
|
||||
return
|
||||
}
|
||||
|
||||
loadingAnimation.current = anime({
|
||||
targets: "#"+loadingLogo.current.id+" .number",
|
||||
duration: 500,
|
||||
easing: "easeInOutCubic",
|
||||
opacity: () => anime.random(.25, 1),
|
||||
complete: () => setupAnim()
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if(!loadingLogo.current) return
|
||||
|
||||
if(!loadingAnimation.current && incompleteCounter.current > 0) setupAnim()
|
||||
}, [uploadCounter, setupAnim])
|
||||
|
||||
const processFile = (file: File) => {
|
||||
|
||||
const reader = new FileReader()
|
||||
|
||||
reader.addEventListener('load', (ev) => {
|
||||
const res = ev.target!.result as ArrayBuffer;
|
||||
|
||||
const hash = sha512(res)
|
||||
|
||||
uploadQueue.current.push({
|
||||
fileName: file.name,
|
||||
fileHash: hash,
|
||||
})
|
||||
|
||||
incompleteCounter.current--
|
||||
|
||||
setUploadCounter(prev => prev + 1)
|
||||
})
|
||||
|
||||
reader.addEventListener('error', (err) => {
|
||||
console.error(err)
|
||||
incompleteCounter.current--
|
||||
})
|
||||
|
||||
reader.readAsArrayBuffer(file)
|
||||
}
|
||||
|
||||
const processDirectory = (directory: FileSystemDirectoryEntry) => {
|
||||
const reader = directory.createReader()
|
||||
reader.readEntries((entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if(entry.isFile) {
|
||||
(entry as FileSystemFileEntry).file((file) => {
|
||||
processFile(file)
|
||||
incompleteCounter.current++
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if(entry.isDirectory) {
|
||||
processDirectory(entry as FileSystemDirectoryEntry)
|
||||
incompleteCounter.current++
|
||||
return
|
||||
}
|
||||
})
|
||||
incompleteCounter.current--
|
||||
}, (err) => {
|
||||
console.error("Could not read directory", directory.fullPath, err)
|
||||
incompleteCounter.current--
|
||||
})
|
||||
}
|
||||
|
||||
const processDataTransfer = (items: DataTransferItemList) => {
|
||||
|
||||
for(let i = 0; i < items.length; i++) {
|
||||
const item = items[i];
|
||||
|
||||
const entry = item.webkitGetAsEntry()
|
||||
|
||||
if(!entry) {
|
||||
continue
|
||||
}
|
||||
|
||||
if(entry.isDirectory) {
|
||||
const dir = entry as FileSystemDirectoryEntry;
|
||||
|
||||
processDirectory(dir)
|
||||
continue
|
||||
}
|
||||
if(entry.isFile) {
|
||||
const file = entry as FileSystemFileEntry;
|
||||
|
||||
file.file((file) => {
|
||||
processFile(file)
|
||||
})
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return <div className={styles.roomsContainer}>
|
||||
<div className={styles.roomsOverview + (outlet ? " "+styles.leaveSpace : "")}>
|
||||
<h1><Trans i18nKey={"entries.title"}>Entry Management</Trans></h1>
|
||||
<button onClick={() => setShowUploader(true)}>Upload New</button>
|
||||
|
||||
<EntriesTable initialQueryRef={data}/>
|
||||
</div>
|
||||
|
||||
<div className={styles.modalOuter + (showUploader ? " "+styles.active :"")}>
|
||||
<div className={styles.uploader} role={"dialog"} aria-modal={true}>
|
||||
<span className={styles.modalTitle}>Upload entries</span>
|
||||
|
||||
<p>In this form you'll be able to upload new entries. Only the hashes of the files will be sent to the server. The actual files never leave your device.</p>
|
||||
|
||||
{/*<div>
|
||||
<input type={"text"} placeholder={"Lists to upload to"} />
|
||||
</div>*/}
|
||||
|
||||
<div className={styles.dropArea} onDragOver={(ev) => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
ev.dataTransfer.dropEffect = 'copy';
|
||||
}} onDrop={(ev) => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
const fileList = ev.dataTransfer.items;
|
||||
processDataTransfer(fileList)
|
||||
}}>
|
||||
<div className={styles.dropAreaContent}>
|
||||
<Logo ref={loadingLogo} id={"loadingLogo"}/>
|
||||
<span>{incompleteCounter.current > 0 ? "Hashing..." : "Drop files to hash"}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.fileList}>
|
||||
{
|
||||
uploadQueue.current.reverse().slice(0, 5).map((entry) => {
|
||||
return <div className={styles.file}>
|
||||
<span className={styles.fileName}>{entry.fileName}</span>
|
||||
<span className={styles.fileHash}>{entry.fileHash}</span>
|
||||
</div>
|
||||
})
|
||||
}
|
||||
{uploadQueue.current.length > 5 && <span>And {uploadQueue.current.length - 5} more...</span>}
|
||||
</div>
|
||||
|
||||
<button onClick={() => setShowUploader(false)}>Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.slideOver + (outlet ? " "+styles.active : "")}>
|
||||
<EntriesSlideOverTitleContext.Provider value={setTitle}>
|
||||
<div className={styles.slideOverHeader}>
|
||||
|
|
|
@ -20,6 +20,7 @@ html, body, #root {
|
|||
|
||||
:root {
|
||||
--veles-color-background: #0d0d0d;
|
||||
--veles-color-background-transparent: #0d0d0df0;
|
||||
--veles-color-foreground: #fff;
|
||||
--veles-color-border: #1c1c1c;
|
||||
--veles-color-border-highlight: #464646;
|
||||
|
@ -41,6 +42,7 @@ html, body, #root {
|
|||
@media(prefers-color-scheme: light) {
|
||||
:root {
|
||||
--veles-color-background: #f2f2f2;
|
||||
--veles-color-background-transparent: #f2f2f2f0;
|
||||
--veles-color-foreground: #0d0d0d;
|
||||
--veles-color-border: #cccccc;
|
||||
--veles-color-border-highlight: #9b9b9b;
|
||||
|
|
|
@ -10,20 +10,20 @@
|
|||
<linearGradient id="linearGradient1303" x1="49.777" x2="70.07" y1="81.546" y2="81.546" gradientTransform="translate(0,6)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient43644"/>
|
||||
<linearGradient id="linearGradient31669" x1="91.453" x2="72.905" y1="48.722" y2="48.722" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient43644"/>
|
||||
</defs>
|
||||
<g transform="translate(-3.6704 12.24)" fill="url(#linearGradient31669)" style="shape-inside:url(#rect8261);white-space:pre" aria-label="101 011 110 100">
|
||||
<path d="m74.758 17.636h4.2969v-14.831l-4.6745 0.9375v-2.3958l4.6484-0.9375h2.6302v17.227h4.2969v2.2135h-11.198z"/>
|
||||
<path d="m96.894 2.1413q-2.0313 0-3.0599 2.0052-1.0156 1.9922-1.0156 6.0026 0 3.9974 1.0156 6.0026 1.0286 1.9922 3.0599 1.9922 2.0443 0 3.0599-1.9922 1.0286-2.0052 1.0286-6.0026 0-4.0104-1.0286-6.0026-1.0156-2.0052-3.0599-2.0052zm0-2.0833q3.2682 0 4.987 2.5911 1.7318 2.5781 1.7318 7.5 0 4.9089-1.7318 7.5-1.7188 2.5781-4.987 2.5781-3.2682 0-5-2.5781-1.7188-2.5911-1.7188-7.5 0-4.9219 1.7188-7.5 1.7318-2.5911 5-2.5911z"/>
|
||||
<path d="m108.69 17.636h4.2969v-14.831l-4.6745 0.9375v-2.3958l4.6484-0.9375h2.6302v17.227h4.2969v2.2135h-11.198z"/>
|
||||
<path d="m79.928 27.475q-2.0313 0-3.0599 2.0052-1.0156 1.9922-1.0156 6.0026 0 3.9974 1.0156 6.0026 1.0286 1.9922 3.0599 1.9922 2.0443 0 3.0599-1.9922 1.0286-2.0052 1.0286-6.0026 0-4.0104-1.0286-6.0026-1.0156-2.0052-3.0599-2.0052zm0-2.0833q3.2682 0 4.987 2.5911 1.7318 2.5781 1.7318 7.5 0 4.9089-1.7318 7.5-1.7188 2.5781-4.987 2.5781t-5-2.5781q-1.7188-2.5911-1.7188-7.5 0-4.9219 1.7188-7.5 1.7318-2.5911 5-2.5911z"/>
|
||||
<path d="m91.725 42.969h4.2969v-14.831l-4.6745 0.9375v-2.3958l4.6484-0.9375h2.6302v17.227h4.2969v2.2135h-11.198z"/>
|
||||
<path d="m108.69 42.969h4.2969v-14.831l-4.6745 0.9375v-2.3958l4.6484-0.9375h2.6302v17.227h4.2969v2.2135h-11.198z"/>
|
||||
<path d="m74.758 68.303h4.2969v-14.831l-4.6745 0.9375v-2.3958l4.6484-0.9375h2.6302v17.227h4.2969v2.2135h-11.198z"/>
|
||||
<path d="m91.725 68.303h4.2969v-14.831l-4.6745 0.9375v-2.3958l4.6484-0.9375h2.6302v17.227h4.2969v2.2135h-11.198z"/>
|
||||
<path d="m113.86 52.808q-2.0312 0-3.0599 2.0052-1.0156 1.9922-1.0156 6.0026 0 3.9974 1.0156 6.0026 1.0286 1.9922 3.0599 1.9922 2.0443 0 3.0599-1.9922 1.0286-2.0052 1.0286-6.0026 0-4.0104-1.0286-6.0026-1.0156-2.0052-3.0599-2.0052zm0-2.0833q3.2682 0 4.987 2.5911 1.7318 2.5781 1.7318 7.5 0 4.9089-1.7318 7.5-1.7188 2.5781-4.987 2.5781t-5-2.5781q-1.7188-2.5911-1.7188-7.5 0-4.9219 1.7188-7.5 1.7318-2.5911 5-2.5911z"/>
|
||||
<path d="m74.758 93.636h4.2969v-14.831l-4.6745 0.9375v-2.3958l4.6484-0.9375h2.6302v17.227h4.2969v2.2135h-11.198z"/>
|
||||
<path d="m96.894 78.141q-2.0313 0-3.0599 2.0052-1.0156 1.9922-1.0156 6.0026 0 3.9974 1.0156 6.0026 1.0286 1.9922 3.0599 1.9922 2.0443 0 3.0599-1.9922 1.0286-2.0052 1.0286-6.0026 0-4.0104-1.0286-6.0026-1.0156-2.0052-3.0599-2.0052zm0-2.0833q3.2682 0 4.987 2.5911 1.7318 2.5781 1.7318 7.5 0 4.9089-1.7318 7.5-1.7188 2.5781-4.987 2.5781-3.2682 0-5-2.5781-1.7188-2.5911-1.7188-7.5 0-4.9219 1.7188-7.5 1.7318-2.5911 5-2.5911z"/>
|
||||
<path d="m113.86 78.141q-2.0312 0-3.0599 2.0052-1.0156 1.9922-1.0156 6.0026 0 3.9974 1.0156 6.0026 1.0286 1.9922 3.0599 1.9922 2.0443 0 3.0599-1.9922 1.0286-2.0052 1.0286-6.0026 0-4.0104-1.0286-6.0026-1.0156-2.0052-3.0599-2.0052zm0-2.0833q3.2682 0 4.987 2.5911 1.7318 2.5781 1.7318 7.5 0 4.9089-1.7318 7.5-1.7188 2.5781-4.987 2.5781t-5-2.5781q-1.7188-2.5911-1.7188-7.5 0-4.9219 1.7188-7.5 1.7318-2.5911 5-2.5911z"/>
|
||||
</g>
|
||||
<g transform="translate(-3.6704 12.24)" fill="url(#linearGradient31669)" style="shape-inside:url(#rect8261);white-space:pre" aria-label="101 011 110 100">
|
||||
<path class="number" d="m74.758 17.636h4.2969v-14.831l-4.6745 0.9375v-2.3958l4.6484-0.9375h2.6302v17.227h4.2969v2.2135h-11.198z"/>
|
||||
<path class="number" d="m96.894 2.1413q-2.0313 0-3.0599 2.0052-1.0156 1.9922-1.0156 6.0026 0 3.9974 1.0156 6.0026 1.0286 1.9922 3.0599 1.9922 2.0443 0 3.0599-1.9922 1.0286-2.0052 1.0286-6.0026 0-4.0104-1.0286-6.0026-1.0156-2.0052-3.0599-2.0052zm0-2.0833q3.2682 0 4.987 2.5911 1.7318 2.5781 1.7318 7.5 0 4.9089-1.7318 7.5-1.7188 2.5781-4.987 2.5781-3.2682 0-5-2.5781-1.7188-2.5911-1.7188-7.5 0-4.9219 1.7188-7.5 1.7318-2.5911 5-2.5911z"/>
|
||||
<path class="number" d="m108.69 17.636h4.2969v-14.831l-4.6745 0.9375v-2.3958l4.6484-0.9375h2.6302v17.227h4.2969v2.2135h-11.198z"/>
|
||||
<path class="number" d="m79.928 27.475q-2.0313 0-3.0599 2.0052-1.0156 1.9922-1.0156 6.0026 0 3.9974 1.0156 6.0026 1.0286 1.9922 3.0599 1.9922 2.0443 0 3.0599-1.9922 1.0286-2.0052 1.0286-6.0026 0-4.0104-1.0286-6.0026-1.0156-2.0052-3.0599-2.0052zm0-2.0833q3.2682 0 4.987 2.5911 1.7318 2.5781 1.7318 7.5 0 4.9089-1.7318 7.5-1.7188 2.5781-4.987 2.5781t-5-2.5781q-1.7188-2.5911-1.7188-7.5 0-4.9219 1.7188-7.5 1.7318-2.5911 5-2.5911z"/>
|
||||
<path class="number" d="m91.725 42.969h4.2969v-14.831l-4.6745 0.9375v-2.3958l4.6484-0.9375h2.6302v17.227h4.2969v2.2135h-11.198z"/>
|
||||
<path class="number" d="m108.69 42.969h4.2969v-14.831l-4.6745 0.9375v-2.3958l4.6484-0.9375h2.6302v17.227h4.2969v2.2135h-11.198z"/>
|
||||
<path class="number" d="m74.758 68.303h4.2969v-14.831l-4.6745 0.9375v-2.3958l4.6484-0.9375h2.6302v17.227h4.2969v2.2135h-11.198z"/>
|
||||
<path class="number" d="m91.725 68.303h4.2969v-14.831l-4.6745 0.9375v-2.3958l4.6484-0.9375h2.6302v17.227h4.2969v2.2135h-11.198z"/>
|
||||
<path class="number" d="m113.86 52.808q-2.0312 0-3.0599 2.0052-1.0156 1.9922-1.0156 6.0026 0 3.9974 1.0156 6.0026 1.0286 1.9922 3.0599 1.9922 2.0443 0 3.0599-1.9922 1.0286-2.0052 1.0286-6.0026 0-4.0104-1.0286-6.0026-1.0156-2.0052-3.0599-2.0052zm0-2.0833q3.2682 0 4.987 2.5911 1.7318 2.5781 1.7318 7.5 0 4.9089-1.7318 7.5-1.7188 2.5781-4.987 2.5781t-5-2.5781q-1.7188-2.5911-1.7188-7.5 0-4.9219 1.7188-7.5 1.7318-2.5911 5-2.5911z"/>
|
||||
<path class="number" d="m74.758 93.636h4.2969v-14.831l-4.6745 0.9375v-2.3958l4.6484-0.9375h2.6302v17.227h4.2969v2.2135h-11.198z"/>
|
||||
<path class="number" d="m96.894 78.141q-2.0313 0-3.0599 2.0052-1.0156 1.9922-1.0156 6.0026 0 3.9974 1.0156 6.0026 1.0286 1.9922 3.0599 1.9922 2.0443 0 3.0599-1.9922 1.0286-2.0052 1.0286-6.0026 0-4.0104-1.0286-6.0026-1.0156-2.0052-3.0599-2.0052zm0-2.0833q3.2682 0 4.987 2.5911 1.7318 2.5781 1.7318 7.5 0 4.9089-1.7318 7.5-1.7188 2.5781-4.987 2.5781-3.2682 0-5-2.5781-1.7188-2.5911-1.7188-7.5 0-4.9219 1.7188-7.5 1.7318-2.5911 5-2.5911z"/>
|
||||
<path class="number" d="m113.86 78.141q-2.0312 0-3.0599 2.0052-1.0156 1.9922-1.0156 6.0026 0 3.9974 1.0156 6.0026 1.0286 1.9922 3.0599 1.9922 2.0443 0 3.0599-1.9922 1.0286-2.0052 1.0286-6.0026 0-4.0104-1.0286-6.0026-1.0156-2.0052-3.0599-2.0052zm0-2.0833q3.2682 0 4.987 2.5911 1.7318 2.5781 1.7318 7.5 0 4.9089-1.7318 7.5-1.7188 2.5781-4.987 2.5781t-5-2.5781q-1.7188-2.5911-1.7188-7.5 0-4.9219 1.7188-7.5 1.7318-2.5911 5-2.5911z"/>
|
||||
</g>
|
||||
<path d="m4.0226 8.0649 30.026 50.894h59.933l30.009-50.864" fill="none" stroke="url(#linearGradient1301)" stroke-linecap="round" stroke-linejoin="round" stroke-width="4.048"/>
|
||||
<path d="m36.324 67.382h47.484l-23.793 40.329z" fill="none" stroke="url(#linearGradient1303)" stroke-linejoin="round" stroke-width="4.048"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.5 KiB |
|
@ -1718,6 +1718,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
|
||||
integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
|
||||
|
||||
"@types/animejs@^3.1.5":
|
||||
version "3.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/animejs/-/animejs-3.1.5.tgz#3cb6c7b90069c6e2969a392eb65ec6311e92c1ab"
|
||||
integrity sha512-4i3i1YuNaNEPoHBJY78uzYu8qKIwyx96G04tnVtNhRMQC9I1Xhg6fY9GeWmZAzudaesKKrPkQgTCthT1zSGYyg==
|
||||
|
||||
"@types/aria-query@^4.2.0":
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.2.tgz#ed4e0ad92306a704f9fb132a0cfcf77486dbe2bc"
|
||||
|
@ -2443,6 +2448,11 @@ ajv@^8.0.0, ajv@^8.6.0, ajv@^8.8.0:
|
|||
require-from-string "^2.0.2"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
animejs@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/animejs/-/animejs-3.2.1.tgz#de9fe2e792f44a777a7fdf6ae160e26604b0cdda"
|
||||
integrity sha512-sWno3ugFryK5nhiDm/2BKeFCpZv7vzerWUcUPyAZLDhMek3+S/p418ldZJbJXo5ZUOpfm2kP2XRO4NJcULMy9A==
|
||||
|
||||
ansi-escapes@^4.2.1, ansi-escapes@^4.3.1:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
|
||||
|
@ -6168,6 +6178,11 @@ jest@^27.4.3:
|
|||
import-local "^3.0.2"
|
||||
jest-cli "^27.5.1"
|
||||
|
||||
js-sha512@^0.8.0:
|
||||
version "0.8.0"
|
||||
resolved "https://registry.yarnpkg.com/js-sha512/-/js-sha512-0.8.0.tgz#dd22db8d02756faccf19f218e3ed61ec8249f7d4"
|
||||
integrity sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
|
|
Loading…
Add table
Reference in a new issue