commit
623c5bb485
@ -8,11 +8,11 @@ https://user-images.githubusercontent.com/3998421/153323093-b664bb68-2928-480b-b
|
|||||||
- [x] Support multiple model architectures
|
- [x] Support multiple model architectures
|
||||||
1. [LaMa](https://github.com/saic-mdal/lama)
|
1. [LaMa](https://github.com/saic-mdal/lama)
|
||||||
1. [LDM](https://github.com/CompVis/latent-diffusion)
|
1. [LDM](https://github.com/CompVis/latent-diffusion)
|
||||||
|
- [x] Support CPU & GPU
|
||||||
- [x] High resolution support
|
- [x] High resolution support
|
||||||
- [x] Run as a desktop APP
|
- [x] Run as a desktop APP
|
||||||
- [x] Multi stroke support. Press and hold the `cmd/ctrl` key to enable multi stroke mode.
|
- [x] Multi stroke support. Press and hold the `cmd/ctrl` key to enable multi stroke mode.
|
||||||
- [x] Zoom & Pan
|
- [x] Zoom & Pan
|
||||||
- [ ] Keep image EXIF data
|
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
{
|
{
|
||||||
"files": {
|
"files": {
|
||||||
"main.css": "/static/css/main.4201b632.chunk.css",
|
"main.css": "/static/css/main.d1028b29.chunk.css",
|
||||||
"main.js": "/static/js/main.18cd2cfc.chunk.js",
|
"main.js": "/static/js/main.b169e669.chunk.js",
|
||||||
"runtime-main.js": "/static/js/runtime-main.5e86ac81.js",
|
"runtime-main.js": "/static/js/runtime-main.5e86ac81.js",
|
||||||
"static/js/2.2d367d07.chunk.js": "/static/js/2.2d367d07.chunk.js",
|
"static/js/2.1b1d3019.chunk.js": "/static/js/2.1b1d3019.chunk.js",
|
||||||
"index.html": "/index.html",
|
"index.html": "/index.html",
|
||||||
"static/js/2.2d367d07.chunk.js.LICENSE.txt": "/static/js/2.2d367d07.chunk.js.LICENSE.txt",
|
"static/js/2.1b1d3019.chunk.js.LICENSE.txt": "/static/js/2.1b1d3019.chunk.js.LICENSE.txt",
|
||||||
"static/media/_index.scss": "/static/media/WorkSans-SemiBold.1e98db4e.ttf"
|
"static/media/_index.scss": "/static/media/WorkSans-SemiBold.1e98db4e.ttf"
|
||||||
},
|
},
|
||||||
"entrypoints": [
|
"entrypoints": [
|
||||||
"static/js/runtime-main.5e86ac81.js",
|
"static/js/runtime-main.5e86ac81.js",
|
||||||
"static/js/2.2d367d07.chunk.js",
|
"static/js/2.1b1d3019.chunk.js",
|
||||||
"static/css/main.4201b632.chunk.css",
|
"static/css/main.d1028b29.chunk.css",
|
||||||
"static/js/main.18cd2cfc.chunk.js"
|
"static/js/main.b169e669.chunk.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -1 +1 @@
|
|||||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"/><meta name="theme-color" content="#ffffff"/><title>lama-cleaner - Image inpainting powered by LaMa</title><link href="/static/css/main.4201b632.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>"localhost"===location.hostname&&(self.FIREBASE_APPCHECK_DEBUG_TOKEN=!0)</script><script>!function(e){function r(r){for(var n,l,a=r[0],f=r[1],i=r[2],p=0,s=[];p<a.length;p++)l=a[p],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(c&&c(r);s.length;)s.shift()();return u.push.apply(u,i||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++){var f=t[a];0!==o[f]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var a=this["webpackJsonplama-cleaner"]=this["webpackJsonplama-cleaner"]||[],f=a.push.bind(a);a.push=r,a=a.slice();for(var i=0;i<a.length;i++)r(a[i]);var c=f;t()}([])</script><script src="/static/js/2.2d367d07.chunk.js"></script><script src="/static/js/main.18cd2cfc.chunk.js"></script></body></html>
|
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"/><meta name="theme-color" content="#ffffff"/><title>lama-cleaner - Image inpainting powered by LaMa</title><link href="/static/css/main.d1028b29.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,l,a=r[0],f=r[1],i=r[2],p=0,s=[];p<a.length;p++)l=a[p],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(c&&c(r);s.length;)s.shift()();return u.push.apply(u,i||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++){var f=t[a];0!==o[f]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var a=this["webpackJsonplama-cleaner"]=this["webpackJsonplama-cleaner"]||[],f=a.push.bind(a);a.push=r,a=a.slice();for(var i=0;i<a.length;i++)r(a[i]);var c=f;t()}([])</script><script src="/static/js/2.1b1d3019.chunk.js"></script><script src="/static/js/main.b169e669.chunk.js"></script></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
lama_cleaner/app/build/static/js/2.1b1d3019.chunk.js
Normal file
2
lama_cleaner/app/build/static/js/2.1b1d3019.chunk.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
lama_cleaner/app/build/static/js/main.b169e669.chunk.js
Normal file
1
lama_cleaner/app/build/static/js/main.b169e669.chunk.js
Normal file
File diff suppressed because one or more lines are too long
@ -5,6 +5,8 @@
|
|||||||
"proxy": "http://localhost:8080",
|
"proxy": "http://localhost:8080",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@heroicons/react": "^1.0.4",
|
"@heroicons/react": "^1.0.4",
|
||||||
|
"@radix-ui/react-dialog": "0.1.8-rc.25",
|
||||||
|
"@radix-ui/react-select": "0.1.2-rc.27",
|
||||||
"@radix-ui/react-switch": "^0.1.5",
|
"@radix-ui/react-switch": "^0.1.5",
|
||||||
"@radix-ui/react-toast": "^0.1.1",
|
"@radix-ui/react-toast": "^0.1.1",
|
||||||
"@testing-library/jest-dom": "^5.14.1",
|
"@testing-library/jest-dom": "^5.14.1",
|
||||||
|
@ -22,10 +22,5 @@
|
|||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<script>
|
|
||||||
if (location.hostname === 'localhost') {
|
|
||||||
self.FIREBASE_APPCHECK_DEBUG_TOKEN = true
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -29,8 +29,12 @@ function App() {
|
|||||||
setTheme(newTheme)
|
setTheme(newTheme)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.body.setAttribute('data-theme', theme)
|
||||||
|
}, [theme])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="lama-cleaner" data-theme={theme}>
|
<div className="lama-cleaner">
|
||||||
<Header />
|
<Header />
|
||||||
{file ? <Workspace file={file} /> : <LandingPage />}
|
{file ? <Workspace file={file} /> : <LandingPage />}
|
||||||
</div>
|
</div>
|
||||||
|
@ -52,7 +52,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.editor-toolkit-panel {
|
.editor-toolkit-panel {
|
||||||
// width: 100%;
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0.5rem;
|
bottom: 0.5rem;
|
||||||
border-radius: 3rem;
|
border-radius: 3rem;
|
||||||
@ -110,80 +109,3 @@
|
|||||||
border: 1px solid var(--yellow-accent);
|
border: 1px solid var(--yellow-accent);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-size-selector-options {
|
|
||||||
position: fixed;
|
|
||||||
display: grid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-size-selector {
|
|
||||||
grid-area: toolkit-size-selector;
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, max-content);
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-size-selector-main {
|
|
||||||
@include accented-display(var(white));
|
|
||||||
user-select: none;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
outline: none;
|
|
||||||
gap: 8px;
|
|
||||||
width: 128px;
|
|
||||||
|
|
||||||
border: 1px solid var(--editor-size-border-color);
|
|
||||||
color: var(--options-text-color);
|
|
||||||
|
|
||||||
svg {
|
|
||||||
width: 1rem;
|
|
||||||
height: 1rem;
|
|
||||||
margin-top: 0.25rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-size-options {
|
|
||||||
@include accented-display(var(--btn-primary-bg));
|
|
||||||
width: 128px;
|
|
||||||
padding: 0;
|
|
||||||
display: grid;
|
|
||||||
justify-self: center;
|
|
||||||
position: fixed;
|
|
||||||
bottom: 4rem;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
color: var(--options-text-color);
|
|
||||||
background-color: var(--page-bg);
|
|
||||||
border: 1px solid var(--editor-size-border-color);
|
|
||||||
|
|
||||||
border-radius: 0.6rem;
|
|
||||||
|
|
||||||
@include mobile {
|
|
||||||
bottom: 11.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-size-option {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
height: 40px;
|
|
||||||
user-select: none;
|
|
||||||
padding: 0.2rem 0.8rem;
|
|
||||||
|
|
||||||
&:first-of-type {
|
|
||||||
border-top-right-radius: 0.5rem;
|
|
||||||
border-top-left-radius: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-of-type {
|
|
||||||
border-bottom-left-radius: 0.5rem;
|
|
||||||
border-bottom-right-radius: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--yellow-accent);
|
|
||||||
color: var(--btn-text-hover-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -21,7 +21,13 @@ import inpaint from '../../adapters/inpainting'
|
|||||||
import Button from '../shared/Button'
|
import Button from '../shared/Button'
|
||||||
import Slider from './Slider'
|
import Slider from './Slider'
|
||||||
import SizeSelector from './SizeSelector'
|
import SizeSelector from './SizeSelector'
|
||||||
import { downloadImage, loadImage, useImage } from '../../utils'
|
import {
|
||||||
|
downloadImage,
|
||||||
|
isMidClick,
|
||||||
|
isRightClick,
|
||||||
|
loadImage,
|
||||||
|
useImage,
|
||||||
|
} from '../../utils'
|
||||||
import { settingState } from '../../store/Atoms'
|
import { settingState } from '../../store/Atoms'
|
||||||
|
|
||||||
const TOOLBAR_SIZE = 200
|
const TOOLBAR_SIZE = 200
|
||||||
@ -78,6 +84,7 @@ export default function Editor(props: EditorProps) {
|
|||||||
const [curLineGroup, setCurLineGroup] = useState<LineGroup>([])
|
const [curLineGroup, setCurLineGroup] = useState<LineGroup>([])
|
||||||
const [{ x, y }, setCoords] = useState({ x: -1, y: -1 })
|
const [{ x, y }, setCoords] = useState({ x: -1, y: -1 })
|
||||||
const [showBrush, setShowBrush] = useState(false)
|
const [showBrush, setShowBrush] = useState(false)
|
||||||
|
const [showRefBrush, setShowRefBrush] = useState(false)
|
||||||
const [isPanning, setIsPanning] = useState<boolean>(false)
|
const [isPanning, setIsPanning] = useState<boolean>(false)
|
||||||
const [showOriginal, setShowOriginal] = useState(false)
|
const [showOriginal, setShowOriginal] = useState(false)
|
||||||
const [isInpaintingLoading, setIsInpaintingLoading] = useState(false)
|
const [isInpaintingLoading, setIsInpaintingLoading] = useState(false)
|
||||||
@ -86,6 +93,8 @@ export default function Editor(props: EditorProps) {
|
|||||||
const [minScale, setMinScale] = useState<number>(1.0)
|
const [minScale, setMinScale] = useState<number>(1.0)
|
||||||
const [sizeLimit, setSizeLimit] = useState<number>(1080)
|
const [sizeLimit, setSizeLimit] = useState<number>(1080)
|
||||||
const windowSize = useWindowSize()
|
const windowSize = useWindowSize()
|
||||||
|
const windowCenterX = windowSize.width / 2
|
||||||
|
const windowCenterY = windowSize.height / 2
|
||||||
const viewportRef = useRef<ReactZoomPanPinchRef | undefined | null>()
|
const viewportRef = useRef<ReactZoomPanPinchRef | undefined | null>()
|
||||||
// Indicates that the image has been loaded and is centered on first load
|
// Indicates that the image has been loaded and is centered on first load
|
||||||
const [initialCentered, setInitialCentered] = useState(false)
|
const [initialCentered, setInitialCentered] = useState(false)
|
||||||
@ -259,6 +268,7 @@ export default function Editor(props: EditorProps) {
|
|||||||
isOriginalLoaded,
|
isOriginalLoaded,
|
||||||
windowSize,
|
windowSize,
|
||||||
initialCentered,
|
initialCentered,
|
||||||
|
drawOnCurrentRender,
|
||||||
])
|
])
|
||||||
|
|
||||||
// Zoom reset
|
// Zoom reset
|
||||||
@ -338,7 +348,11 @@ export default function Editor(props: EditorProps) {
|
|||||||
drawOnCurrentRender(lineGroup)
|
drawOnCurrentRender(lineGroup)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onPointerUp = () => {
|
const onPointerUp = (ev: SyntheticEvent) => {
|
||||||
|
if (isMidClick(ev)) {
|
||||||
|
setIsPanning(false)
|
||||||
|
}
|
||||||
|
|
||||||
if (isPanning) {
|
if (isPanning) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -382,6 +396,16 @@ export default function Editor(props: EditorProps) {
|
|||||||
if (isInpaintingLoading) {
|
if (isInpaintingLoading) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isRightClick(ev)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isMidClick(ev)) {
|
||||||
|
setIsPanning(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
setIsDraging(true)
|
setIsDraging(true)
|
||||||
|
|
||||||
let lineGroup: LineGroup = []
|
let lineGroup: LineGroup = []
|
||||||
@ -531,6 +555,13 @@ export default function Editor(props: EditorProps) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Manual Inpainting Hotkey
|
||||||
|
useKeyPressEvent('R', () => {
|
||||||
|
if (settings.runInpaintingManually && hadDrawSomething()) {
|
||||||
|
runInpainting()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// Toggle clean/zoom tool on spacebar.
|
// Toggle clean/zoom tool on spacebar.
|
||||||
useKeyPressEvent(
|
useKeyPressEvent(
|
||||||
' ',
|
' ',
|
||||||
@ -556,17 +587,28 @@ export default function Editor(props: EditorProps) {
|
|||||||
return s!
|
return s!
|
||||||
}
|
}
|
||||||
|
|
||||||
const getBrushStyle = () => {
|
const getBrushStyle = (_x: number, _y: number) => {
|
||||||
const curScale = getCurScale()
|
const curScale = getCurScale()
|
||||||
return {
|
return {
|
||||||
width: `${brushSize * curScale}px`,
|
width: `${brushSize * curScale}px`,
|
||||||
height: `${brushSize * curScale}px`,
|
height: `${brushSize * curScale}px`,
|
||||||
left: `${x}px`,
|
left: `${_x}px`,
|
||||||
top: `${y}px`,
|
top: `${_y}px`,
|
||||||
transform: 'translate(-50%, -50%)',
|
transform: 'translate(-50%, -50%)',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleSliderChange = (value: number) => {
|
||||||
|
setBrushSize(value)
|
||||||
|
|
||||||
|
if (!showRefBrush) {
|
||||||
|
setShowRefBrush(true)
|
||||||
|
window.setTimeout(() => {
|
||||||
|
setShowRefBrush(false)
|
||||||
|
}, 10000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="editor-container"
|
className="editor-container"
|
||||||
@ -615,7 +657,10 @@ export default function Editor(props: EditorProps) {
|
|||||||
onContextMenu={e => {
|
onContextMenu={e => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
}}
|
}}
|
||||||
onMouseOver={() => toggleShowBrush(true)}
|
onMouseOver={() => {
|
||||||
|
toggleShowBrush(true)
|
||||||
|
setShowRefBrush(false)
|
||||||
|
}}
|
||||||
onFocus={() => toggleShowBrush(true)}
|
onFocus={() => toggleShowBrush(true)}
|
||||||
onMouseLeave={() => toggleShowBrush(false)}
|
onMouseLeave={() => toggleShowBrush(false)}
|
||||||
onMouseDown={onMouseDown}
|
onMouseDown={onMouseDown}
|
||||||
@ -660,7 +705,14 @@ export default function Editor(props: EditorProps) {
|
|||||||
</TransformWrapper>
|
</TransformWrapper>
|
||||||
|
|
||||||
{showBrush && !isInpaintingLoading && !isPanning && (
|
{showBrush && !isInpaintingLoading && !isPanning && (
|
||||||
<div className="brush-shape" style={getBrushStyle()} />
|
<div className="brush-shape" style={getBrushStyle(x, y)} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
{showRefBrush && (
|
||||||
|
<div
|
||||||
|
className="brush-shape"
|
||||||
|
style={getBrushStyle(windowCenterX, windowCenterY)}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="editor-toolkit-panel">
|
<div className="editor-toolkit-panel">
|
||||||
@ -674,15 +726,20 @@ export default function Editor(props: EditorProps) {
|
|||||||
min={10}
|
min={10}
|
||||||
max={150}
|
max={150}
|
||||||
value={brushSize}
|
value={brushSize}
|
||||||
onChange={setBrushSize}
|
onChange={handleSliderChange}
|
||||||
|
onClick={() => setShowRefBrush(false)}
|
||||||
/>
|
/>
|
||||||
<div className="editor-toolkit-btns">
|
<div className="editor-toolkit-btns">
|
||||||
<Button
|
<Button
|
||||||
|
toolTip="Reset Zoom & Pan"
|
||||||
|
tooltipPosition="top"
|
||||||
icon={<ArrowsExpandIcon />}
|
icon={<ArrowsExpandIcon />}
|
||||||
disabled={scale === minScale && panned === false}
|
disabled={scale === minScale && panned === false}
|
||||||
onClick={resetZoom}
|
onClick={resetZoom}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
|
toolTip="Undo"
|
||||||
|
tooltipPosition="top"
|
||||||
icon={
|
icon={
|
||||||
<svg
|
<svg
|
||||||
width="19"
|
width="19"
|
||||||
@ -701,6 +758,8 @@ export default function Editor(props: EditorProps) {
|
|||||||
disabled={disableUndo()}
|
disabled={disableUndo()}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
|
toolTip="Show Original"
|
||||||
|
tooltipPosition="top"
|
||||||
icon={<EyeIcon />}
|
icon={<EyeIcon />}
|
||||||
className={showOriginal ? 'eyeicon-active' : ''}
|
className={showOriginal ? 'eyeicon-active' : ''}
|
||||||
onDown={ev => {
|
onDown={ev => {
|
||||||
@ -721,6 +780,8 @@ export default function Editor(props: EditorProps) {
|
|||||||
disabled={renders.length === 0}
|
disabled={renders.length === 0}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
|
toolTip="Save Image"
|
||||||
|
tooltipPosition="top"
|
||||||
icon={<DownloadIcon />}
|
icon={<DownloadIcon />}
|
||||||
disabled={!renders.length}
|
disabled={!renders.length}
|
||||||
onClick={download}
|
onClick={download}
|
||||||
@ -728,6 +789,8 @@ export default function Editor(props: EditorProps) {
|
|||||||
|
|
||||||
{settings.runInpaintingManually && (
|
{settings.runInpaintingManually && (
|
||||||
<Button
|
<Button
|
||||||
|
toolTip="Run Inpainting"
|
||||||
|
tooltipPosition="top"
|
||||||
icon={
|
icon={
|
||||||
<svg
|
<svg
|
||||||
width="24"
|
width="24"
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React, { useCallback, useRef, useState } from 'react'
|
import React, { useCallback, useState } from 'react'
|
||||||
import { useClickAway } from 'react-use'
|
import Selector from '../shared/Selector'
|
||||||
import { ChevronUpIcon } from '@heroicons/react/outline'
|
|
||||||
|
|
||||||
const sizes = ['720', '1080', '2000', 'Original']
|
const sizes = ['720', '1080', '2000', 'Original']
|
||||||
|
|
||||||
@ -12,24 +11,9 @@ type SizeSelectorProps = {
|
|||||||
|
|
||||||
export default function SizeSelector(props: SizeSelectorProps) {
|
export default function SizeSelector(props: SizeSelectorProps) {
|
||||||
const { originalHeight, originalWidth, onChange } = props
|
const { originalHeight, originalWidth, onChange } = props
|
||||||
const [showOptions, setShowOptions] = useState<boolean>(false)
|
|
||||||
const sizeSelectorRef = useRef(null)
|
|
||||||
const [activeSize, setActiveSize] = useState<string>('Original')
|
const [activeSize, setActiveSize] = useState<string>('Original')
|
||||||
const longSide: number = Math.max(originalWidth, originalHeight)
|
const longSide: number = Math.max(originalWidth, originalHeight)
|
||||||
|
|
||||||
const getValidSizes = useCallback(() => {
|
|
||||||
const validSizes: string[] = []
|
|
||||||
for (let i = 0; i < sizes.length; i += 1) {
|
|
||||||
if (sizes[i] === 'Original') {
|
|
||||||
validSizes.push(sizes[i])
|
|
||||||
}
|
|
||||||
if (parseInt(sizes[i], 10) < longSide) {
|
|
||||||
validSizes.push(sizes[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return validSizes
|
|
||||||
}, [longSide])
|
|
||||||
|
|
||||||
const getSizeShowName = useCallback(
|
const getSizeShowName = useCallback(
|
||||||
(size: string) => {
|
(size: string) => {
|
||||||
if (size === 'Original') {
|
if (size === 'Original') {
|
||||||
@ -46,57 +30,38 @@ export default function SizeSelector(props: SizeSelectorProps) {
|
|||||||
[originalWidth, originalHeight, longSide]
|
[originalWidth, originalHeight, longSide]
|
||||||
)
|
)
|
||||||
|
|
||||||
const showOptionsHandler = () => {
|
const getValidSizes = useCallback(() => {
|
||||||
setShowOptions(currentShowOptionsState => !currentShowOptionsState)
|
const validSizes: string[] = []
|
||||||
}
|
for (let i = 0; i < sizes.length; i += 1) {
|
||||||
|
if (sizes[i] === 'Original') {
|
||||||
|
validSizes.push(getSizeShowName(sizes[i]))
|
||||||
|
}
|
||||||
|
if (parseInt(sizes[i], 10) < longSide) {
|
||||||
|
validSizes.push(getSizeShowName(sizes[i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return validSizes
|
||||||
|
}, [longSide, getSizeShowName])
|
||||||
|
|
||||||
useClickAway(sizeSelectorRef, () => {
|
const sizeChangeHandler = (value: string) => {
|
||||||
setShowOptions(false)
|
const currentRes = value.split('x')
|
||||||
})
|
|
||||||
|
|
||||||
const sizeChangeHandler = (e: any) => {
|
|
||||||
const currentRes = e.target.textContent.split('x')
|
|
||||||
if (originalWidth > originalHeight) {
|
if (originalWidth > originalHeight) {
|
||||||
setActiveSize(currentRes[0])
|
setActiveSize(currentRes[0])
|
||||||
onChange(currentRes[0])
|
onChange(parseInt(currentRes[0], 10))
|
||||||
} else {
|
} else {
|
||||||
setActiveSize(currentRes[1])
|
setActiveSize(currentRes[1])
|
||||||
onChange(currentRes[1])
|
onChange(parseInt(currentRes[1], 10))
|
||||||
}
|
}
|
||||||
setShowOptions(!showOptions)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="editor-size-selector" ref={sizeSelectorRef}>
|
<Selector
|
||||||
<div
|
width={100}
|
||||||
className="editor-size-selector-main"
|
autoFocusAfterClose={false}
|
||||||
role="button"
|
value={getSizeShowName(activeSize.toString())}
|
||||||
tabIndex={0}
|
options={getValidSizes()}
|
||||||
onClick={showOptionsHandler}
|
onChange={sizeChangeHandler}
|
||||||
aria-hidden="true"
|
chevronDirection="up"
|
||||||
>
|
/>
|
||||||
<p>{getSizeShowName(activeSize.toString())}</p>
|
|
||||||
<div className="editor-size-selector-icon">
|
|
||||||
<ChevronUpIcon />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{showOptions && (
|
|
||||||
<div className="editor-size-options">
|
|
||||||
{getValidSizes().map(size => (
|
|
||||||
<div
|
|
||||||
className="editor-size-option"
|
|
||||||
role="button"
|
|
||||||
tabIndex={0}
|
|
||||||
key={size}
|
|
||||||
onClick={sizeChangeHandler}
|
|
||||||
aria-hidden="true"
|
|
||||||
>
|
|
||||||
{getSizeShowName(size)}
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,11 @@ type SliderProps = {
|
|||||||
min?: number
|
min?: number
|
||||||
max?: number
|
max?: number
|
||||||
onChange: (value: number) => void
|
onChange: (value: number) => void
|
||||||
|
onClick: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Slider(props: SliderProps) {
|
export default function Slider(props: SliderProps) {
|
||||||
const { value, onChange, label, min, max } = props
|
const { value, onChange, onClick, label, min, max } = props
|
||||||
|
|
||||||
const step = ((max || 100) - (min || 0)) / 100
|
const step = ((max || 100) - (min || 0)) / 100
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ export default function Slider(props: SliderProps) {
|
|||||||
ev.stopPropagation()
|
ev.stopPropagation()
|
||||||
onChange(parseInt(ev.currentTarget.value, 10))
|
onChange(parseInt(ev.currentTarget.value, 10))
|
||||||
}}
|
}}
|
||||||
|
onClick={onClick}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -26,15 +26,15 @@ const Header = () => {
|
|||||||
{resolution === 'desktop' ? 'Start New' : undefined}
|
{resolution === 'desktop' ? 'Start New' : undefined}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="header-icons-wrapper">
|
<div className="header-icons-wrapper">
|
||||||
<div
|
|
||||||
className="header-icons"
|
|
||||||
style={{ visibility: file ? 'visible' : 'hidden' }}
|
|
||||||
>
|
|
||||||
<SettingIcon />
|
|
||||||
<Shortcuts />
|
|
||||||
</div>
|
|
||||||
<ThemeChanger />
|
<ThemeChanger />
|
||||||
|
{file && (
|
||||||
|
<div className="header-icons">
|
||||||
|
<Shortcuts />
|
||||||
|
<SettingIcon />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
)
|
)
|
||||||
|
@ -119,6 +119,7 @@ function HDSettingBlock() {
|
|||||||
title="High Resolution Strategy"
|
title="High Resolution Strategy"
|
||||||
input={
|
input={
|
||||||
<Selector
|
<Selector
|
||||||
|
width={80}
|
||||||
value={setting.hdStrategy as string}
|
value={setting.hdStrategy as string}
|
||||||
options={Object.values(HDStrategy)}
|
options={Object.values(HDStrategy)}
|
||||||
onChange={val => onStrategyChange(val as HDStrategy)}
|
onChange={val => onStrategyChange(val as HDStrategy)}
|
||||||
|
@ -15,7 +15,7 @@ const ManualRunInpaintingSettingBlock: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingBlock
|
<SettingBlock
|
||||||
title="Run inpainting manually"
|
title="Manual Inpainting Mode"
|
||||||
input={
|
input={
|
||||||
<Switch
|
<Switch
|
||||||
checked={setting.runInpaintingManually}
|
checked={setting.runInpaintingManually}
|
||||||
|
@ -90,6 +90,7 @@ function ModelSettingBlock() {
|
|||||||
title="Inpainting Model"
|
title="Inpainting Model"
|
||||||
input={
|
input={
|
||||||
<Selector
|
<Selector
|
||||||
|
width={80}
|
||||||
value={setting.model as string}
|
value={setting.model as string}
|
||||||
options={Object.values(AIModel)}
|
options={Object.values(AIModel)}
|
||||||
onChange={val => onModelChange(val as AIModel)}
|
onChange={val => onModelChange(val as AIModel)}
|
||||||
|
@ -14,6 +14,8 @@ const SettingIcon = () => {
|
|||||||
<div>
|
<div>
|
||||||
<Button
|
<Button
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
|
toolTip="Settings"
|
||||||
|
tooltipPosition="bottom"
|
||||||
style={{ border: 0 }}
|
style={{ border: 0 }}
|
||||||
icon={
|
icon={
|
||||||
<svg
|
<svg
|
||||||
|
@ -34,11 +34,10 @@
|
|||||||
|
|
||||||
.shortcut-key {
|
.shortcut-key {
|
||||||
justify-self: end;
|
justify-self: end;
|
||||||
font-family: 'WorkSans-Bold';
|
|
||||||
border: 1px solid var(--modal-hotkey-border-color);
|
border: 1px solid var(--modal-hotkey-border-color);
|
||||||
padding: 0.4rem 1rem;
|
padding: 0.4rem 0.4rem;
|
||||||
width: max-content;
|
width: max-content;
|
||||||
border-radius: 0.4rem;
|
border-radius: 0.2rem;
|
||||||
|
|
||||||
@include mobile {
|
@include mobile {
|
||||||
padding: 0.2rem 0.4rem;
|
padding: 0.2rem 0.4rem;
|
||||||
@ -48,7 +47,6 @@
|
|||||||
.shortcut-description {
|
.shortcut-description {
|
||||||
justify-self: start;
|
justify-self: start;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
width: 18rem;
|
|
||||||
|
|
||||||
@include mobile {
|
@include mobile {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
@ -22,6 +22,8 @@ const Shortcuts = () => {
|
|||||||
<div className="shortcuts">
|
<div className="shortcuts">
|
||||||
<Button
|
<Button
|
||||||
onClick={shortcutStateHandler}
|
onClick={shortcutStateHandler}
|
||||||
|
toolTip="Hotkeys"
|
||||||
|
tooltipPosition="bottom"
|
||||||
disabled={shortcutVisibility}
|
disabled={shortcutVisibility}
|
||||||
style={{ border: 0 }}
|
style={{ border: 0 }}
|
||||||
icon={
|
icon={
|
||||||
|
@ -4,21 +4,37 @@ import { shortcutsState } from '../../store/Atoms'
|
|||||||
import Modal from '../shared/Modal'
|
import Modal from '../shared/Modal'
|
||||||
|
|
||||||
interface Shortcut {
|
interface Shortcut {
|
||||||
children: ReactNode
|
|
||||||
content: string
|
content: string
|
||||||
|
keys: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
function ShortCut(props: Shortcut) {
|
function ShortCut(props: Shortcut) {
|
||||||
const { children, content } = props
|
const { content, keys } = props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="shortcut-option">
|
<div className="shortcut-option">
|
||||||
<div className="shortcut-description">{content}</div>
|
<div className="shortcut-description">{content}</div>
|
||||||
<div className="shortcut-key">{children}</div>
|
<div style={{ display: 'flex', justifySelf: 'end', gap: '8px' }}>
|
||||||
|
{keys.map((k, index) => (
|
||||||
|
<div className="shortcut-key" key={k}>
|
||||||
|
{k}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isMac = (function () {
|
||||||
|
return /macintosh|mac os x/i.test(navigator.userAgent)
|
||||||
|
})()
|
||||||
|
|
||||||
|
const isWindows = (function () {
|
||||||
|
return /windows|win32/i.test(navigator.userAgent)
|
||||||
|
})()
|
||||||
|
|
||||||
|
const CmdOrCtrl = isMac ? 'Cmd' : 'Ctrl'
|
||||||
|
|
||||||
export default function ShortcutsModal() {
|
export default function ShortcutsModal() {
|
||||||
const [shortcutsShow, setShortcutState] = useRecoilState(shortcutsState)
|
const [shortcutsShow, setShortcutState] = useRecoilState(shortcutsState)
|
||||||
|
|
||||||
@ -34,36 +50,20 @@ export default function ShortcutsModal() {
|
|||||||
show={shortcutsShow}
|
show={shortcutsShow}
|
||||||
>
|
>
|
||||||
<div className="shortcut-options">
|
<div className="shortcut-options">
|
||||||
<ShortCut content="Enable multi-stroke mask drawing">
|
<ShortCut
|
||||||
<p>Hold Cmd/Ctrl</p>
|
content="Enable Multi-Stroke Mask Drawing"
|
||||||
</ShortCut>
|
keys={[`Hold ${CmdOrCtrl}`]}
|
||||||
<ShortCut content="Undo inpainting">
|
/>
|
||||||
<p>Cmd/Ctrl + Z</p>
|
<ShortCut content="Undo Inpainting" keys={[CmdOrCtrl, 'Z']} />
|
||||||
</ShortCut>
|
<ShortCut content="Pan" keys={['Space & Drag']} />
|
||||||
<ShortCut content="Pan">
|
<ShortCut content="View Original Image" keys={['Hold Tag']} />
|
||||||
<p>Space & Drag</p>
|
<ShortCut content="Reset Zoom/Pan" keys={['Esc']} />
|
||||||
</ShortCut>
|
<ShortCut content="Cancel Mask Drawing" keys={['Esc']} />
|
||||||
<ShortCut content="View original image">
|
<ShortCut content="Run Inpainting Manually" keys={['Shift', 'R']} />
|
||||||
<p>Hold Tab</p>
|
<ShortCut content="Decrease Brush Size" keys={['[']} />
|
||||||
</ShortCut>
|
<ShortCut content="Increase Brush Size" keys={[']']} />
|
||||||
<ShortCut content="Reset zoom/pan">
|
<ShortCut content="Toggle Dark Mode" keys={['Shift', 'D']} />
|
||||||
<p>Esc</p>
|
<ShortCut content="Toggle Hotkeys Panel" keys={['H']} />
|
||||||
</ShortCut>
|
|
||||||
<ShortCut content="Cancel mask drawing">
|
|
||||||
<p>Esc</p>
|
|
||||||
</ShortCut>
|
|
||||||
<ShortCut content="Decrease Brush Size">
|
|
||||||
<p>[</p>
|
|
||||||
</ShortCut>
|
|
||||||
<ShortCut content="Increase Brush Size">
|
|
||||||
<p>]</p>
|
|
||||||
</ShortCut>
|
|
||||||
<ShortCut content="Toggle Dark Mode">
|
|
||||||
<p>Shift + D</p>
|
|
||||||
</ShortCut>
|
|
||||||
<ShortCut content="Toggle Hotkeys Panel">
|
|
||||||
<p>H</p>
|
|
||||||
</ShortCut>
|
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
)
|
)
|
||||||
|
@ -4,7 +4,7 @@ import Editor from './Editor/Editor'
|
|||||||
import ShortcutsModal from './Shortcuts/ShortcutsModal'
|
import ShortcutsModal from './Shortcuts/ShortcutsModal'
|
||||||
import SettingModal from './Settings/SettingsModal'
|
import SettingModal from './Settings/SettingsModal'
|
||||||
import Toast from './shared/Toast'
|
import Toast from './shared/Toast'
|
||||||
import { Settings, settingState, toastState } from '../store/Atoms'
|
import { settingState, toastState } from '../store/Atoms'
|
||||||
import {
|
import {
|
||||||
currentModel,
|
currentModel,
|
||||||
modelDownloaded,
|
modelDownloaded,
|
||||||
@ -79,7 +79,7 @@ const Workspace = ({ file }: WorkspaceProps) => {
|
|||||||
return { ...old, model: model as AIModel }
|
return { ...old, model: model as AIModel }
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}, [])
|
}, [setSettingState])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
|
@use '../../styles/Mixins/' as *;
|
||||||
|
|
||||||
.btn-primary {
|
.btn-primary {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-auto-flow: column;
|
grid-auto-flow: column;
|
||||||
column-gap: 1rem;
|
column-gap: 1rem;
|
||||||
border: 1px solid var(--btn-border-color);
|
|
||||||
color: var(--btn-text-color);
|
color: var(--btn-text-color);
|
||||||
font-family: 'WorkSans', sans-serif;
|
font-family: 'WorkSans', sans-serif;
|
||||||
width: max-content;
|
width: max-content;
|
||||||
|
@ -5,6 +5,8 @@ interface ButtonProps {
|
|||||||
children?: ReactNode
|
children?: ReactNode
|
||||||
className?: string
|
className?: string
|
||||||
icon?: ReactNode
|
icon?: ReactNode
|
||||||
|
toolTip?: string
|
||||||
|
tooltipPosition?: string
|
||||||
onKeyDown?: () => void
|
onKeyDown?: () => void
|
||||||
onClick?: () => void
|
onClick?: () => void
|
||||||
onDown?: (ev: PointerEvent) => void
|
onDown?: (ev: PointerEvent) => void
|
||||||
@ -18,6 +20,8 @@ const Button: React.FC<ButtonProps> = props => {
|
|||||||
className,
|
className,
|
||||||
disabled,
|
disabled,
|
||||||
icon,
|
icon,
|
||||||
|
toolTip,
|
||||||
|
tooltipPosition,
|
||||||
onKeyDown,
|
onKeyDown,
|
||||||
onClick,
|
onClick,
|
||||||
onDown,
|
onDown,
|
||||||
@ -33,6 +37,7 @@ const Button: React.FC<ButtonProps> = props => {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
role="button"
|
role="button"
|
||||||
|
data-tooltip={toolTip}
|
||||||
style={style}
|
style={style}
|
||||||
onKeyDown={onKeyDown}
|
onKeyDown={onKeyDown}
|
||||||
onClick={blurOnClick}
|
onClick={blurOnClick}
|
||||||
@ -47,6 +52,8 @@ const Button: React.FC<ButtonProps> = props => {
|
|||||||
'btn-primary',
|
'btn-primary',
|
||||||
children ? 'btn-primary-content' : '',
|
children ? 'btn-primary-content' : '',
|
||||||
disabled === true ? 'btn-primary-disabled' : '',
|
disabled === true ? 'btn-primary-disabled' : '',
|
||||||
|
toolTip ? 'info-tooltip' : '',
|
||||||
|
tooltipPosition ? `info-tooltip-${tooltipPosition}` : '',
|
||||||
className,
|
className,
|
||||||
].join(' ')}
|
].join(' ')}
|
||||||
>
|
>
|
||||||
|
@ -1,17 +1,33 @@
|
|||||||
.modal-mask {
|
.modal-mask {
|
||||||
z-index: 9999;
|
position: fixed;
|
||||||
height: 100%;
|
z-index: 9998;
|
||||||
width: 100%;
|
inset: 0;
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
position: absolute;
|
|
||||||
background-color: var(--model-mask-bg);
|
background-color: var(--model-mask-bg);
|
||||||
backdrop-filter: blur(12px);
|
backdrop-filter: blur(12px);
|
||||||
-webkit-backdrop-filter: blur(12px);
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
animation: opacityReveal 150ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes contentShow {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate(-50%, -48%) scale(0.96);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translate(-50%, -50%) scale(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal {
|
.modal {
|
||||||
|
background-color: var(--page-bg);
|
||||||
|
z-index: 9999;
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-auto-rows: max-content;
|
grid-auto-rows: max-content;
|
||||||
row-gap: 2rem;
|
row-gap: 2rem;
|
||||||
@ -19,6 +35,10 @@
|
|||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
border-radius: 0.95rem;
|
border-radius: 0.95rem;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
.modal-header {
|
.modal-header {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, auto);
|
grid-template-columns: repeat(2, auto);
|
||||||
@ -28,4 +48,8 @@
|
|||||||
justify-self: end;
|
justify-self: end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
animation: contentShow 150ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { XIcon } from '@heroicons/react/outline'
|
import { XIcon } from '@heroicons/react/outline'
|
||||||
import React, { ReactNode, useRef } from 'react'
|
import React, { ReactNode } from 'react'
|
||||||
import { useClickAway, useKey, useKeyPress, useKeyPressEvent } from 'react-use'
|
import * as DialogPrimitive from '@radix-ui/react-dialog'
|
||||||
import Button from './Button'
|
import Button from './Button'
|
||||||
|
|
||||||
export interface ModalProps {
|
export interface ModalProps {
|
||||||
@ -11,34 +11,35 @@ export interface ModalProps {
|
|||||||
className?: string
|
className?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Modal(props: ModalProps) {
|
const Modal = React.forwardRef<
|
||||||
|
React.ElementRef<typeof DialogPrimitive.Root>,
|
||||||
|
ModalProps
|
||||||
|
>((props, forwardedRef) => {
|
||||||
const { show, children, onClose, className, title } = props
|
const { show, children, onClose, className, title } = props
|
||||||
const ref = useRef(null)
|
|
||||||
|
|
||||||
useClickAway(ref, () => {
|
const onOpenChange = (open: boolean) => {
|
||||||
if (show) {
|
if (!open) {
|
||||||
onClose?.()
|
onClose?.()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
useKeyPressEvent('Escape', e => {
|
|
||||||
if (show) {
|
|
||||||
onClose?.()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<DialogPrimitive.Root open={show} onOpenChange={onOpenChange}>
|
||||||
className="modal-mask"
|
<DialogPrimitive.Portal>
|
||||||
style={{ visibility: show === true ? 'visible' : 'hidden' }}
|
<DialogPrimitive.Overlay className="modal-mask" />
|
||||||
>
|
<DialogPrimitive.Content
|
||||||
<div ref={ref} className={`modal ${className}`}>
|
ref={forwardedRef}
|
||||||
<div className="modal-header">
|
className={`modal ${className}`}
|
||||||
<h2>{title}</h2>
|
>
|
||||||
<Button icon={<XIcon />} onClick={onClose} />
|
<div className="modal-header">
|
||||||
</div>
|
<DialogPrimitive.Title>{title}</DialogPrimitive.Title>
|
||||||
{children}
|
<Button icon={<XIcon />} onClick={onClose} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{children}
|
||||||
|
</DialogPrimitive.Content>
|
||||||
|
</DialogPrimitive.Portal>
|
||||||
|
</DialogPrimitive.Root>
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
|
||||||
|
export default Modal
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
all: unset;
|
all: unset;
|
||||||
flex: 1 0 auto;
|
flex: 1 0 auto;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
padding: 0.2rem 0.8rem;
|
padding: 0.4rem 0.8rem;
|
||||||
line-height: 1;
|
|
||||||
outline: 1px solid var(--border-color);
|
outline: 1px solid var(--border-color);
|
||||||
|
|
||||||
&:focus-visible {
|
&:focus-visible {
|
||||||
|
@ -1,26 +1,14 @@
|
|||||||
@use '../../styles/Mixins' as *;
|
.select-trigger {
|
||||||
|
all: unset;
|
||||||
.selector {
|
display: inline-flex;
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
border-radius: 0.5rem;
|
||||||
|
height: 38px;
|
||||||
.selector-main {
|
|
||||||
@include accented-display(var(white));
|
|
||||||
width: 100%;
|
|
||||||
user-select: none;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
outline: none;
|
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
padding: 0.2rem 0.8rem;
|
padding: 0 0.8rem;
|
||||||
|
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
|
background-color: var(--page-bg);
|
||||||
color: var(--options-text-color);
|
color: var(--options-text-color);
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
@ -28,47 +16,52 @@
|
|||||||
height: 1rem;
|
height: 1rem;
|
||||||
margin-top: 0.25rem;
|
margin-top: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--yellow-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// &:focus-visible {
|
||||||
|
// border-color: var(--yellow-accent);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
.selector-options {
|
.select-content {
|
||||||
@include accented-display(var(--btn-primary-bg));
|
overflow: hidden;
|
||||||
width: 100%;
|
|
||||||
padding: 0;
|
|
||||||
display: grid;
|
|
||||||
justify-self: center;
|
|
||||||
position: absolute;
|
|
||||||
cursor: pointer;
|
|
||||||
top: 3rem;
|
|
||||||
|
|
||||||
color: var(--options-text-color);
|
|
||||||
background-color: var(--page-bg);
|
background-color: var(--page-bg);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-viewport {
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
border-radius: 0.6rem;
|
.select-item {
|
||||||
|
all: unset;
|
||||||
|
background-color: var(--page-bg);
|
||||||
|
color: var(--options-text-color);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
|
||||||
@include mobile {
|
padding: 6px 6px 6px 25px;
|
||||||
bottom: 11.5rem;
|
position: relative;
|
||||||
}
|
user-select: none;
|
||||||
|
|
||||||
.selector-option {
|
&:focus {
|
||||||
display: flex;
|
color: var(--btn-text-hover-color);
|
||||||
align-items: center;
|
background-color: var(--yellow-accent);
|
||||||
user-select: none;
|
|
||||||
padding: 0.5rem 0.8rem;
|
|
||||||
|
|
||||||
&:first-of-type {
|
|
||||||
border-top-right-radius: 0.5rem;
|
|
||||||
border-top-left-radius: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-of-type {
|
|
||||||
border-bottom-left-radius: 0.5rem;
|
|
||||||
border-bottom-right-radius: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--yellow-accent);
|
|
||||||
color: var(--btn-text-hover-color);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.select-item-indicator {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 25px;
|
||||||
|
padding-right: 4px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
@ -1,86 +1,84 @@
|
|||||||
import React, { MutableRefObject, useCallback, useRef, useState } from 'react'
|
import React, { useRef } from 'react'
|
||||||
import { useClickAway, useKeyPressEvent } from 'react-use'
|
import {
|
||||||
import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/outline'
|
CheckIcon,
|
||||||
|
ChevronDownIcon,
|
||||||
|
ChevronUpIcon,
|
||||||
|
} from '@heroicons/react/outline'
|
||||||
|
import * as Select from '@radix-ui/react-select'
|
||||||
|
|
||||||
type SelectorChevronDirection = 'up' | 'down'
|
type SelectorChevronDirection = 'up' | 'down'
|
||||||
|
|
||||||
type SelectorProps = {
|
interface Props {
|
||||||
minWidth?: number
|
width?: number
|
||||||
chevronDirection?: SelectorChevronDirection
|
|
||||||
value: string
|
value: string
|
||||||
options: string[]
|
options: string[]
|
||||||
|
chevronDirection?: SelectorChevronDirection
|
||||||
|
autoFocusAfterClose?: boolean
|
||||||
onChange: (value: string) => void
|
onChange: (value: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectorDefaultProps = {
|
const Selector = (props: Props) => {
|
||||||
minWidth: 128,
|
const {
|
||||||
chevronDirection: 'down',
|
width,
|
||||||
}
|
value,
|
||||||
|
chevronDirection,
|
||||||
|
options,
|
||||||
|
autoFocusAfterClose,
|
||||||
|
onChange,
|
||||||
|
} = props
|
||||||
|
|
||||||
function Selector(props: SelectorProps) {
|
const contentRef = useRef<HTMLButtonElement>(null)
|
||||||
const { minWidth, chevronDirection, value, options, onChange } = props
|
|
||||||
const [showOptions, setShowOptions] = useState<boolean>(false)
|
|
||||||
const selectorRef = useRef<HTMLDivElement | null>(null)
|
|
||||||
|
|
||||||
const showOptionsHandler = () => {
|
const onOpenChange = (open: boolean) => {
|
||||||
// console.log(selectorRef.current?.focus)
|
if (!open) {
|
||||||
// selectorRef?.current?.focus()
|
if (!autoFocusAfterClose) {
|
||||||
setShowOptions(currentShowOptionsState => !currentShowOptionsState)
|
// 如果使用 Select.Content 的 onCloseAutoFocus 来取消 focus(防止空格继续打开这个 select)
|
||||||
}
|
// 会导致其它快捷键失效,原因未知
|
||||||
|
window.setTimeout(() => {
|
||||||
useClickAway(selectorRef, () => {
|
contentRef?.current?.blur()
|
||||||
setShowOptions(false)
|
}, 100)
|
||||||
})
|
}
|
||||||
|
}
|
||||||
// TODO: how to prevent Modal close?
|
|
||||||
// useKeyPressEvent('Escape', (e: KeyboardEvent) => {
|
|
||||||
// if (showOptions === true) {
|
|
||||||
// console.log(`selector ${e}`)
|
|
||||||
// e.preventDefault()
|
|
||||||
// e.stopPropagation()
|
|
||||||
// setShowOptions(false)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
const onOptionClick = (e: any, newIndex: number) => {
|
|
||||||
const currentRes = e.target.textContent.split('x')
|
|
||||||
onChange(currentRes[0])
|
|
||||||
setShowOptions(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="selector" ref={selectorRef} style={{ minWidth }}>
|
<Select.Root
|
||||||
<div
|
value={value}
|
||||||
className="selector-main"
|
onValueChange={onChange}
|
||||||
role="button"
|
onOpenChange={onOpenChange}
|
||||||
onClick={showOptionsHandler}
|
>
|
||||||
aria-hidden="true"
|
<Select.Trigger
|
||||||
|
className="select-trigger"
|
||||||
|
style={{ width }}
|
||||||
|
ref={contentRef}
|
||||||
>
|
>
|
||||||
<p>{value}</p>
|
<Select.Value />
|
||||||
<div className="selector-icon">
|
<Select.Icon>
|
||||||
{chevronDirection === 'up' ? <ChevronUpIcon /> : <ChevronDownIcon />}
|
{chevronDirection === 'up' ? <ChevronUpIcon /> : <ChevronDownIcon />}
|
||||||
</div>
|
</Select.Icon>
|
||||||
</div>
|
</Select.Trigger>
|
||||||
|
|
||||||
{showOptions && (
|
<Select.Content className="select-content">
|
||||||
<div className="selector-options">
|
<Select.Viewport className="select-viewport">
|
||||||
{options.map((val, _index) => (
|
{options.map(val => (
|
||||||
<div
|
<Select.Item value={val} className="select-item" key={val}>
|
||||||
className="selector-option"
|
<Select.ItemText>{val}</Select.ItemText>
|
||||||
role="button"
|
<Select.ItemIndicator className="select-item-indicator">
|
||||||
tabIndex={0}
|
<CheckIcon />
|
||||||
key={val}
|
</Select.ItemIndicator>
|
||||||
onClick={e => onOptionClick(e, _index)}
|
</Select.Item>
|
||||||
aria-hidden="true"
|
|
||||||
>
|
|
||||||
{val}
|
|
||||||
</div>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</Select.Viewport>
|
||||||
)}
|
</Select.Content>
|
||||||
</div>
|
</Select.Root>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selectorDefaultProps = {
|
||||||
|
chevronDirection: 'down',
|
||||||
|
autoFocusAfterClose: true,
|
||||||
|
}
|
||||||
|
|
||||||
Selector.defaultProps = selectorDefaultProps
|
Selector.defaultProps = selectorDefaultProps
|
||||||
|
|
||||||
export default Selector
|
export default Selector
|
||||||
|
33
lama_cleaner/app/src/components/shared/Tooltip.scss
Normal file
33
lama_cleaner/app/src/components/shared/Tooltip.scss
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
$tooltip-translate: 100%;
|
||||||
|
$tooltip-margin: 1.5rem;
|
||||||
|
|
||||||
|
.info-tooltip {
|
||||||
|
&:hover:before {
|
||||||
|
content: attr(data-tooltip);
|
||||||
|
position: absolute;
|
||||||
|
background-color: var(--tooltip-bg);
|
||||||
|
color: var(--tooltip-text-color);
|
||||||
|
padding: 0.5rem;
|
||||||
|
border-radius: 0.3rem;
|
||||||
|
z-index: 2;
|
||||||
|
opacity: 0;
|
||||||
|
animation-name: opacityReveal;
|
||||||
|
animation-duration: 0.2s;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
animation-delay: 1s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-tooltip-top {
|
||||||
|
&:hover:before {
|
||||||
|
transform: translateY(calc($tooltip-translate * -1));
|
||||||
|
margin-bottom: $tooltip-margin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-tooltip-bottom {
|
||||||
|
&:hover:before {
|
||||||
|
transform: translateY($tooltip-translate);
|
||||||
|
margin-top: $tooltip-margin;
|
||||||
|
}
|
||||||
|
}
|
@ -9,12 +9,15 @@
|
|||||||
--link-color: rgb(0, 0, 0);
|
--link-color: rgb(0, 0, 0);
|
||||||
--border-color: rgb(100, 100, 120);
|
--border-color: rgb(100, 100, 120);
|
||||||
--border-color-light: rgba(100, 100, 120, 0.5);
|
--border-color-light: rgba(100, 100, 120, 0.5);
|
||||||
|
--tooltip-bg: rgb(230, 230, 234);
|
||||||
|
--tooltip-text-color: rgb(0, 0,0);
|
||||||
|
|
||||||
--error-color: rgb(239, 68, 68);
|
--error-color: rgb(239, 68, 68);
|
||||||
--success-color: rgb(16, 185, 129);
|
--success-color: rgb(16, 185, 129);
|
||||||
|
|
||||||
// Editor
|
// Editor
|
||||||
--editor-toolkit-bg: rgba(255, 255, 255, 0.5);
|
--editor-toolkit-bg: rgba(255, 255, 255, 0.5);
|
||||||
|
--editor-options-bg: rgb(230, 230, 234);
|
||||||
--options-text-color: var(--page-text-color);
|
--options-text-color: var(--page-text-color);
|
||||||
--editor-size-border-color: var(--border-color);
|
--editor-size-border-color: var(--border-color);
|
||||||
--editor-toolkit-panel-border: 0;
|
--editor-toolkit-panel-border: 0;
|
||||||
|
@ -9,9 +9,12 @@
|
|||||||
--link-color: var(--yellow-accent);
|
--link-color: var(--yellow-accent);
|
||||||
--border-color: rgb(100, 100, 120);
|
--border-color: rgb(100, 100, 120);
|
||||||
--border-color-light: rgba(102, 102, 102);
|
--border-color-light: rgba(102, 102, 102);
|
||||||
|
--tooltip-bg: rgb(33, 33, 33);
|
||||||
|
--tooltip-text-color: rgb(210, 210, 210);
|
||||||
|
|
||||||
// Editor
|
// Editor
|
||||||
--editor-toolkit-bg: rgba(0, 0, 0, 0.5);
|
--editor-toolkit-bg: rgba(0, 0, 0, 0.5);
|
||||||
|
--editor-options-bg: rgb(33, 33, 33);
|
||||||
--options-text-color: var(--page-text-color);
|
--options-text-color: var(--page-text-color);
|
||||||
--editor-size-border-color: var(--yellow-accent);
|
--editor-size-border-color: var(--yellow-accent);
|
||||||
--editor-toolkit-panel-border: 1px solid rgb(100, 100, 120, 0.4);
|
--editor-toolkit-panel-border: 1px solid rgb(100, 100, 120, 0.4);
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
@use '../components/shared/Switch';
|
@use '../components/shared/Switch';
|
||||||
@use '../components/shared/NumberInput';
|
@use '../components/shared/NumberInput';
|
||||||
@use '../components/shared/Toast';
|
@use '../components/shared/Toast';
|
||||||
|
@use '../components/shared/Tooltip';
|
||||||
|
|
||||||
// Main CSS
|
// Main CSS
|
||||||
*,
|
*,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { SyntheticEvent, useEffect, useState } from 'react'
|
||||||
|
|
||||||
export function dataURItoBlob(dataURI: string) {
|
export function dataURItoBlob(dataURI: string) {
|
||||||
const mime = dataURI.split(',')[0].split(':')[1].split(';')[0]
|
const mime = dataURI.split(',')[0].split(':')[1].split(';')[0]
|
||||||
@ -182,3 +182,13 @@ export function keepGUIAlive() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isRightClick(ev: SyntheticEvent) {
|
||||||
|
const mouseEvent = ev.nativeEvent as MouseEvent
|
||||||
|
return mouseEvent.button === 2
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isMidClick(ev: SyntheticEvent) {
|
||||||
|
const mouseEvent = ev.nativeEvent as MouseEvent
|
||||||
|
return mouseEvent.button === 1
|
||||||
|
}
|
||||||
|
@ -1544,6 +1544,13 @@
|
|||||||
schema-utils "^2.6.5"
|
schema-utils "^2.6.5"
|
||||||
source-map "^0.7.3"
|
source-map "^0.7.3"
|
||||||
|
|
||||||
|
"@radix-ui/number@0.1.0":
|
||||||
|
version "0.1.0"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/number/-/number-0.1.0.tgz#73ad13d5cc5f75fa5e147d72e5d5d5e50d688256"
|
||||||
|
integrity sha512-rpf6QiOWLHAkM4FEMYu9i+5Jr8cKT893+R4mPpcdsy4LD7omr9JfdOqj/h/xPA5+EcVrpMMlU6rrRYpUB5UI8g==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@radix-ui/primitive@0.1.0":
|
"@radix-ui/primitive@0.1.0":
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/primitive/-/primitive-0.1.0.tgz#6206b97d379994f0d1929809db035733b337e543"
|
resolved "https://registry.npmmirror.com/@radix-ui/primitive/-/primitive-0.1.0.tgz#6206b97d379994f0d1929809db035733b337e543"
|
||||||
@ -1551,6 +1558,17 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-collection@0.1.5-rc.18":
|
||||||
|
version "0.1.5-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-collection/-/react-collection-0.1.5-rc.18.tgz#4dc03a8f464643748c0dad781b472f149d671d5c"
|
||||||
|
integrity sha512-ZTxuynXn3FgNVQ2+1/G+QLBoNH7F826OIUHAHc/tkuMsSjTKv1QVUxkE1t+UuyApYS4aqvFcrgyQlbcdqp4MpA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-compose-refs" "0.1.1-rc.18"
|
||||||
|
"@radix-ui/react-context" "0.1.2-rc.18"
|
||||||
|
"@radix-ui/react-primitive" "0.1.5-rc.18"
|
||||||
|
"@radix-ui/react-slot" "0.1.3-rc.18"
|
||||||
|
|
||||||
"@radix-ui/react-compose-refs@0.1.0":
|
"@radix-ui/react-compose-refs@0.1.0":
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/react-compose-refs/-/react-compose-refs-0.1.0.tgz#cff6e780a0f73778b976acff2c2a5b6551caab95"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-compose-refs/-/react-compose-refs-0.1.0.tgz#cff6e780a0f73778b976acff2c2a5b6551caab95"
|
||||||
@ -1558,6 +1576,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-compose-refs@0.1.1-rc.18":
|
||||||
|
version "0.1.1-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-compose-refs/-/react-compose-refs-0.1.1-rc.18.tgz#5d6d8e74aa98f41f8e740f22067aa4c30718af68"
|
||||||
|
integrity sha512-K0txrUszW1rI0af8tUBGHTxcfLzMH/criPZirLFBsZ1nJTg1GItJvQdoEAZeP51ooPXRtn0VWdD1va0eHtAGVA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@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.npmmirror.com/@radix-ui/react-context/-/react-context-0.1.1.tgz#06996829ea124d9a1bc1dbe3e51f33588fab0875"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-context/-/react-context-0.1.1.tgz#06996829ea124d9a1bc1dbe3e51f33588fab0875"
|
||||||
@ -1565,6 +1590,41 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-context@0.1.2-rc.18":
|
||||||
|
version "0.1.2-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-context/-/react-context-0.1.2-rc.18.tgz#b5746bd609d6d7372ae6f5c778c7d5a6c7eb6834"
|
||||||
|
integrity sha512-ZQD/FTtNb1Y+O9kML5RLWYzpdbwrhwQHJcVh/BSeaxJvAqQtWqfMlKPSKjvQgkPMljWK7o6hqUptdicVdNpIRQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-dialog@0.1.8-rc.25":
|
||||||
|
version "0.1.8-rc.25"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-dialog/-/react-dialog-0.1.8-rc.25.tgz#dea6af32268b34070346ed5d6d609ff699a1de43"
|
||||||
|
integrity sha512-THdTgtqCWmOs06zQOod8lNgH+eoBFlqJKwLOC6TVIgj76lNahEotPOz8K5Dio/IyJ7U2NAVZtGgV6ZQkdjtKFQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/primitive" "0.1.0"
|
||||||
|
"@radix-ui/react-compose-refs" "0.1.1-rc.18"
|
||||||
|
"@radix-ui/react-context" "0.1.2-rc.18"
|
||||||
|
"@radix-ui/react-dismissable-layer" "0.1.6-rc.18"
|
||||||
|
"@radix-ui/react-focus-guards" "0.1.1-rc.18"
|
||||||
|
"@radix-ui/react-focus-scope" "0.1.5-rc.18"
|
||||||
|
"@radix-ui/react-id" "0.1.6-rc.18"
|
||||||
|
"@radix-ui/react-portal" "0.1.5-rc.18"
|
||||||
|
"@radix-ui/react-presence" "0.1.3-rc.18"
|
||||||
|
"@radix-ui/react-primitive" "0.1.5-rc.18"
|
||||||
|
"@radix-ui/react-slot" "0.1.3-rc.18"
|
||||||
|
"@radix-ui/react-use-controllable-state" "0.1.1-rc.18"
|
||||||
|
aria-hidden "^1.1.1"
|
||||||
|
react-remove-scroll "^2.4.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-direction@0.1.0-rc.21":
|
||||||
|
version "0.1.0-rc.21"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-direction/-/react-direction-0.1.0-rc.21.tgz#01954caa203ebd87e9a770b727c34956b9829eca"
|
||||||
|
integrity sha512-c2mlHIXhgkLT7RiXdaqHhLC0b3XtWKimG5FUFGxUSr3+IKADg7CioTAVwOqz2Pa+AKO8tYJG/2aE583mmE9OMg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@radix-ui/react-dismissable-layer@0.1.5":
|
"@radix-ui/react-dismissable-layer@0.1.5":
|
||||||
version "0.1.5"
|
version "0.1.5"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-0.1.5.tgz#9379032351e79028d472733a5cc8ba4a0ea43314"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-0.1.5.tgz#9379032351e79028d472733a5cc8ba4a0ea43314"
|
||||||
@ -1578,6 +1638,36 @@
|
|||||||
"@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-dismissable-layer@0.1.6-rc.18":
|
||||||
|
version "0.1.6-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-0.1.6-rc.18.tgz#0827b3f6148048c934a5f26feccb5f6a360817b2"
|
||||||
|
integrity sha512-7ZrO3UbvlLfmVFgqhbT3E1Nss7iz4SpUba8/wCbgcoEmb2gXHukFpZhvXunkublFcNxs6kb58jHZtdPL98vMHQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/primitive" "0.1.0"
|
||||||
|
"@radix-ui/react-compose-refs" "0.1.1-rc.18"
|
||||||
|
"@radix-ui/react-primitive" "0.1.5-rc.18"
|
||||||
|
"@radix-ui/react-use-body-pointer-events" "0.1.2-rc.18"
|
||||||
|
"@radix-ui/react-use-callback-ref" "0.1.1-rc.18"
|
||||||
|
"@radix-ui/react-use-escape-keydown" "0.1.1-rc.18"
|
||||||
|
|
||||||
|
"@radix-ui/react-focus-guards@0.1.1-rc.18":
|
||||||
|
version "0.1.1-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-focus-guards/-/react-focus-guards-0.1.1-rc.18.tgz#f0e2ebd3cbfd363a71682e3234b274ab7d7df4ce"
|
||||||
|
integrity sha512-eJq8XBF/vh5uPMqB8kWpaRfXjwDAPK3hXi7a8NrxhDDL4DLrIT5VnKzdNptmIu59SAwWBdb7maS71J4/oS9tWA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-focus-scope@0.1.5-rc.18":
|
||||||
|
version "0.1.5-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-focus-scope/-/react-focus-scope-0.1.5-rc.18.tgz#e26a0317130687fd3668af8ec68e19e04dc7668f"
|
||||||
|
integrity sha512-uiiOQqbcsV68zPrbUO0V86DJ7SNhZ6HQSBYkQI5NRVOOP4NAx2KJoj8838M4JHxwBq2EvmGvhH1xCOEF8YGuwA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-compose-refs" "0.1.1-rc.18"
|
||||||
|
"@radix-ui/react-primitive" "0.1.5-rc.18"
|
||||||
|
"@radix-ui/react-use-callback-ref" "0.1.1-rc.18"
|
||||||
|
|
||||||
"@radix-ui/react-id@0.1.5":
|
"@radix-ui/react-id@0.1.5":
|
||||||
version "0.1.5"
|
version "0.1.5"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/react-id/-/react-id-0.1.5.tgz#010d311bedd5a2884c1e9bb6aaaa4e6cc1d1d3b8"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-id/-/react-id-0.1.5.tgz#010d311bedd5a2884c1e9bb6aaaa4e6cc1d1d3b8"
|
||||||
@ -1586,6 +1676,14 @@
|
|||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/react-use-layout-effect" "0.1.0"
|
"@radix-ui/react-use-layout-effect" "0.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-id@0.1.6-rc.18":
|
||||||
|
version "0.1.6-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-id/-/react-id-0.1.6-rc.18.tgz#8a73ddeabf8195babe9153e3ab68b6a61eb0dc07"
|
||||||
|
integrity sha512-NWSNlEdCSq9uNWsoWkmIHdjNNl5Sir8R17k5GPWez5uC0p72ymxNQRrIEm6Lp+kdaBFHwiNLUcMECMpF4gvDuw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-use-layout-effect" "0.1.1-rc.18"
|
||||||
|
|
||||||
"@radix-ui/react-label@0.1.5":
|
"@radix-ui/react-label@0.1.5":
|
||||||
version "0.1.5"
|
version "0.1.5"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/react-label/-/react-label-0.1.5.tgz#12cd965bfc983e0148121d4c99fb8e27a917c45c"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-label/-/react-label-0.1.5.tgz#12cd965bfc983e0148121d4c99fb8e27a917c45c"
|
||||||
@ -1597,6 +1695,17 @@
|
|||||||
"@radix-ui/react-id" "0.1.5"
|
"@radix-ui/react-id" "0.1.5"
|
||||||
"@radix-ui/react-primitive" "0.1.4"
|
"@radix-ui/react-primitive" "0.1.4"
|
||||||
|
|
||||||
|
"@radix-ui/react-label@0.1.6-rc.18":
|
||||||
|
version "0.1.6-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-label/-/react-label-0.1.6-rc.18.tgz#91a01c97553d92f6b3683702dd939b5ff13bd5d8"
|
||||||
|
integrity sha512-T+pnKxUTCy4E0TcasaN9mbI80jI3SCmUlcLIofHjT8gMfNKB6ctbZVnRZ+8NhkXdkcPtrTbL+xtX3YAlukn3Xg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-compose-refs" "0.1.1-rc.18"
|
||||||
|
"@radix-ui/react-context" "0.1.2-rc.18"
|
||||||
|
"@radix-ui/react-id" "0.1.6-rc.18"
|
||||||
|
"@radix-ui/react-primitive" "0.1.5-rc.18"
|
||||||
|
|
||||||
"@radix-ui/react-portal@0.1.4":
|
"@radix-ui/react-portal@0.1.4":
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/react-portal/-/react-portal-0.1.4.tgz#17bdce3d7f1a9a0b35cb5e935ab8bc562441a7d2"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-portal/-/react-portal-0.1.4.tgz#17bdce3d7f1a9a0b35cb5e935ab8bc562441a7d2"
|
||||||
@ -1606,6 +1715,15 @@
|
|||||||
"@radix-ui/react-primitive" "0.1.4"
|
"@radix-ui/react-primitive" "0.1.4"
|
||||||
"@radix-ui/react-use-layout-effect" "0.1.0"
|
"@radix-ui/react-use-layout-effect" "0.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-portal@0.1.5-rc.18":
|
||||||
|
version "0.1.5-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-portal/-/react-portal-0.1.5-rc.18.tgz#8ff156abc2d4a4cc43f7fb95605edf677dc4983f"
|
||||||
|
integrity sha512-DlmS8wDoI3hFrLLALD44l0O8UI10S3e220RcIADxwhhfSg4mwKOznKMdeZLUW/Hmqcmhqwez7Y3u4ktClT82QQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-primitive" "0.1.5-rc.18"
|
||||||
|
"@radix-ui/react-use-layout-effect" "0.1.1-rc.18"
|
||||||
|
|
||||||
"@radix-ui/react-presence@0.1.2":
|
"@radix-ui/react-presence@0.1.2":
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/react-presence/-/react-presence-0.1.2.tgz#9f11cce3df73cf65bc348e8b76d891f0d54c1fe3"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-presence/-/react-presence-0.1.2.tgz#9f11cce3df73cf65bc348e8b76d891f0d54c1fe3"
|
||||||
@ -1615,6 +1733,15 @@
|
|||||||
"@radix-ui/react-compose-refs" "0.1.0"
|
"@radix-ui/react-compose-refs" "0.1.0"
|
||||||
"@radix-ui/react-use-layout-effect" "0.1.0"
|
"@radix-ui/react-use-layout-effect" "0.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-presence@0.1.3-rc.18":
|
||||||
|
version "0.1.3-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-presence/-/react-presence-0.1.3-rc.18.tgz#53994cf898d29f41246e4eb81c4627a5fe46da61"
|
||||||
|
integrity sha512-hr1/71w5alELTUnap4FtTCSkT83HROwRr3+J+5NAU3niEeebdUJTpCBGg+hV7h/SV67vmIivZdI2VmPuWyx69A==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-compose-refs" "0.1.1-rc.18"
|
||||||
|
"@radix-ui/react-use-layout-effect" "0.1.1-rc.18"
|
||||||
|
|
||||||
"@radix-ui/react-primitive@0.1.4":
|
"@radix-ui/react-primitive@0.1.4":
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/react-primitive/-/react-primitive-0.1.4.tgz#6c233cf08b0cb87fecd107e9efecb3f21861edc1"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-primitive/-/react-primitive-0.1.4.tgz#6c233cf08b0cb87fecd107e9efecb3f21861edc1"
|
||||||
@ -1623,6 +1750,40 @@
|
|||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/react-slot" "0.1.2"
|
"@radix-ui/react-slot" "0.1.2"
|
||||||
|
|
||||||
|
"@radix-ui/react-primitive@0.1.5-rc.18":
|
||||||
|
version "0.1.5-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-primitive/-/react-primitive-0.1.5-rc.18.tgz#a6ac3ddb1a96b448de2241e7af8d83335aa31b18"
|
||||||
|
integrity sha512-JJ+u0LSb3C7i2Pqlq0L37aysfbYvyXc2ZFvlzQLpSLnac2pJEkftih2ODGDZHyWW3OdJne/eL442xi+CeKoJpw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-slot" "0.1.3-rc.18"
|
||||||
|
|
||||||
|
"@radix-ui/react-select@0.1.2-rc.27":
|
||||||
|
version "0.1.2-rc.27"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-select/-/react-select-0.1.2-rc.27.tgz#91948d482b3db8cf83172838dfae0f4bedec9566"
|
||||||
|
integrity sha512-bU7edMZ57HSjD/QjFNUXqR1BNbKJiNa/Ue/i4pNSZzu1uoz93s7T1fNZcfUtz1TyJSCfSqw7M9qnteVgM67frg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/number" "0.1.0"
|
||||||
|
"@radix-ui/primitive" "0.1.0"
|
||||||
|
"@radix-ui/react-collection" "0.1.5-rc.18"
|
||||||
|
"@radix-ui/react-compose-refs" "0.1.1-rc.18"
|
||||||
|
"@radix-ui/react-context" "0.1.2-rc.18"
|
||||||
|
"@radix-ui/react-direction" "0.1.0-rc.21"
|
||||||
|
"@radix-ui/react-dismissable-layer" "0.1.6-rc.18"
|
||||||
|
"@radix-ui/react-focus-scope" "0.1.5-rc.18"
|
||||||
|
"@radix-ui/react-id" "0.1.6-rc.18"
|
||||||
|
"@radix-ui/react-label" "0.1.6-rc.18"
|
||||||
|
"@radix-ui/react-portal" "0.1.5-rc.18"
|
||||||
|
"@radix-ui/react-primitive" "0.1.5-rc.18"
|
||||||
|
"@radix-ui/react-use-callback-ref" "0.1.1-rc.18"
|
||||||
|
"@radix-ui/react-use-controllable-state" "0.1.1-rc.18"
|
||||||
|
"@radix-ui/react-use-layout-effect" "0.1.1-rc.18"
|
||||||
|
"@radix-ui/react-use-previous" "0.1.2-rc.18"
|
||||||
|
"@radix-ui/react-visually-hidden" "0.1.5-rc.18"
|
||||||
|
aria-hidden "^1.1.1"
|
||||||
|
react-remove-scroll "^2.4.0"
|
||||||
|
|
||||||
"@radix-ui/react-slot@0.1.2":
|
"@radix-ui/react-slot@0.1.2":
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-0.1.2.tgz#e6f7ad9caa8ce81cc8d532c854c56f9b8b6307c8"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-0.1.2.tgz#e6f7ad9caa8ce81cc8d532c854c56f9b8b6307c8"
|
||||||
@ -1631,6 +1792,14 @@
|
|||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/react-compose-refs" "0.1.0"
|
"@radix-ui/react-compose-refs" "0.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-slot@0.1.3-rc.18":
|
||||||
|
version "0.1.3-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-slot/-/react-slot-0.1.3-rc.18.tgz#370869c60e6d988f2bde0909771e4ad84c99e11f"
|
||||||
|
integrity sha512-7dOYAMzx0zhQFOPpSCgBSManKOvC+ezy67makxmBCMpfa8uV1B0A6sfWze6p0fBLnEt+bDVvR4ZGBEK1EnoQAA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-compose-refs" "0.1.1-rc.18"
|
||||||
|
|
||||||
"@radix-ui/react-switch@^0.1.5":
|
"@radix-ui/react-switch@^0.1.5":
|
||||||
version "0.1.5"
|
version "0.1.5"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/react-switch/-/react-switch-0.1.5.tgz#071ffa19a17a47fdc5c5e6f371bd5901c9fef2f4"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-switch/-/react-switch-0.1.5.tgz#071ffa19a17a47fdc5c5e6f371bd5901c9fef2f4"
|
||||||
@ -1672,6 +1841,14 @@
|
|||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/react-use-layout-effect" "0.1.0"
|
"@radix-ui/react-use-layout-effect" "0.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-use-body-pointer-events@0.1.2-rc.18":
|
||||||
|
version "0.1.2-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-use-body-pointer-events/-/react-use-body-pointer-events-0.1.2-rc.18.tgz#bfea07e70d07fc3fa5f17c97848a435bee3a0a1b"
|
||||||
|
integrity sha512-QvuzIsLrZJZDcbQEQMRoKyKX2ULfdPJO3BG/+NSvFDxJNht6VTV4OR7B+jNtV78EwtBvZ+o/14hUeSJR+InbAw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-use-layout-effect" "0.1.1-rc.18"
|
||||||
|
|
||||||
"@radix-ui/react-use-callback-ref@0.1.0":
|
"@radix-ui/react-use-callback-ref@0.1.0":
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-0.1.0.tgz#934b6e123330f5b3a6b116460e6662cbc663493f"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-0.1.0.tgz#934b6e123330f5b3a6b116460e6662cbc663493f"
|
||||||
@ -1679,6 +1856,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-use-callback-ref@0.1.1-rc.18":
|
||||||
|
version "0.1.1-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-0.1.1-rc.18.tgz#86cd931b69cbf333ff3ca888ba74edf119184ede"
|
||||||
|
integrity sha512-Jw0jcOL66xhfOTIAaPvcDfynN5KNE+Y2lokXnDS9n/erGeOAFANLem3hV5elqxel6xOAhTj55dubxzV08nJ1vg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@radix-ui/react-use-controllable-state@0.1.0":
|
"@radix-ui/react-use-controllable-state@0.1.0":
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-0.1.0.tgz#4fced164acfc69a4e34fb9d193afdab973a55de1"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-0.1.0.tgz#4fced164acfc69a4e34fb9d193afdab973a55de1"
|
||||||
@ -1687,6 +1871,14 @@
|
|||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/react-use-callback-ref" "0.1.0"
|
"@radix-ui/react-use-callback-ref" "0.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-use-controllable-state@0.1.1-rc.18":
|
||||||
|
version "0.1.1-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-0.1.1-rc.18.tgz#6a404591ff8f021ca2e8ca3a3ff6a79d5c2a8bd5"
|
||||||
|
integrity sha512-enVVaxWLlfd4hsqG9ezIGUd1H0nYdwsVOTVeswmwP0MCt4mX4hQUiXwdp2uwLfc19HpHFnHCN8pohmVIEx8tqg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-use-callback-ref" "0.1.1-rc.18"
|
||||||
|
|
||||||
"@radix-ui/react-use-escape-keydown@0.1.0":
|
"@radix-ui/react-use-escape-keydown@0.1.0":
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-0.1.0.tgz#dc80cb3753e9d1bd992adbad9a149fb6ea941874"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-0.1.0.tgz#dc80cb3753e9d1bd992adbad9a149fb6ea941874"
|
||||||
@ -1695,6 +1887,14 @@
|
|||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@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.1-rc.18":
|
||||||
|
version "0.1.1-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-0.1.1-rc.18.tgz#82bea76e7191d00023b4e1505d8acfb136726c05"
|
||||||
|
integrity sha512-z+syfHS88smrl7YpNTFNrUpT8FgFX0ejNnEu8STXyofuHr+K6uQHv/jjn/ZFRtHKXTPgkqL1MIxR3WSvlMlFAw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-use-callback-ref" "0.1.1-rc.18"
|
||||||
|
|
||||||
"@radix-ui/react-use-layout-effect@0.1.0":
|
"@radix-ui/react-use-layout-effect@0.1.0":
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-0.1.0.tgz#ebf71bd6d2825de8f1fbb984abf2293823f0f223"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-0.1.0.tgz#ebf71bd6d2825de8f1fbb984abf2293823f0f223"
|
||||||
@ -1702,6 +1902,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-use-layout-effect@0.1.1-rc.18":
|
||||||
|
version "0.1.1-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-0.1.1-rc.18.tgz#2b2010253fdb50a95a73c951daf7f74462a67d65"
|
||||||
|
integrity sha512-DR7qRSlsQnVYuEroMUyUGfEBUhxYBM+gLVJ0+c8rTKIShpJ2W2mDgTLynJQiD3bBa3o0J0/KkRbZg2FzbdDURQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@radix-ui/react-use-previous@0.1.1":
|
"@radix-ui/react-use-previous@0.1.1":
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/react-use-previous/-/react-use-previous-0.1.1.tgz#0226017f72267200f6e832a7103760e96a6db5d0"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-use-previous/-/react-use-previous-0.1.1.tgz#0226017f72267200f6e832a7103760e96a6db5d0"
|
||||||
@ -1709,6 +1916,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-use-previous@0.1.2-rc.18":
|
||||||
|
version "0.1.2-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-use-previous/-/react-use-previous-0.1.2-rc.18.tgz#7a94a4a8914849de595b3a5c5f9d6e0b7e12e45d"
|
||||||
|
integrity sha512-RbdV/yXkVtgMZwcvgtH7VbhJWO2ZUnnHZWZ3CzVoroEqvSunlBSYMZngPbnFLiO3ZKTSD9jFsi+FS6MJAj3iRw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@radix-ui/react-use-size@0.1.1":
|
"@radix-ui/react-use-size@0.1.1":
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.npmmirror.com/@radix-ui/react-use-size/-/react-use-size-0.1.1.tgz#f6b75272a5d41c3089ca78c8a2e48e5f204ef90f"
|
resolved "https://registry.npmmirror.com/@radix-ui/react-use-size/-/react-use-size-0.1.1.tgz#f6b75272a5d41c3089ca78c8a2e48e5f204ef90f"
|
||||||
@ -1724,6 +1938,14 @@
|
|||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/react-primitive" "0.1.4"
|
"@radix-ui/react-primitive" "0.1.4"
|
||||||
|
|
||||||
|
"@radix-ui/react-visually-hidden@0.1.5-rc.18":
|
||||||
|
version "0.1.5-rc.18"
|
||||||
|
resolved "https://registry.npmmirror.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-0.1.5-rc.18.tgz#d0a3fffa611258b57114c533718076353f6afb65"
|
||||||
|
integrity sha512-0e0JNOKdmh6hl41mzL5dGSVNfb8MMD1HzWluO6iTEYUyJrs6eBkwKpeGiZNp7sxmvGSbI/yFNEwMWbMFKq51Kw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-primitive" "0.1.5-rc.18"
|
||||||
|
|
||||||
"@rollup/plugin-node-resolve@^7.1.1":
|
"@rollup/plugin-node-resolve@^7.1.1":
|
||||||
version "7.1.3"
|
version "7.1.3"
|
||||||
resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz"
|
resolved "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz"
|
||||||
@ -2696,6 +2918,13 @@ argparse@^1.0.7:
|
|||||||
dependencies:
|
dependencies:
|
||||||
sprintf-js "~1.0.2"
|
sprintf-js "~1.0.2"
|
||||||
|
|
||||||
|
aria-hidden@^1.1.1:
|
||||||
|
version "1.1.3"
|
||||||
|
resolved "https://registry.npmmirror.com/aria-hidden/-/aria-hidden-1.1.3.tgz#bb48de18dc84787a3c6eee113709c473c64ec254"
|
||||||
|
integrity sha512-RhVWFtKH5BiGMycI72q2RAFMLQi8JP9bLuQXgR5a8Znp7P5KOIADSJeyfI8PCVxLEp067B2HbP5JIiI/PXIZeA==
|
||||||
|
dependencies:
|
||||||
|
tslib "^1.0.0"
|
||||||
|
|
||||||
aria-query@^4.2.2:
|
aria-query@^4.2.2:
|
||||||
version "4.2.2"
|
version "4.2.2"
|
||||||
resolved "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz"
|
resolved "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz"
|
||||||
@ -4435,6 +4664,11 @@ detect-newline@^3.0.0:
|
|||||||
resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz"
|
resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz"
|
||||||
integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==
|
integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==
|
||||||
|
|
||||||
|
detect-node-es@^1.1.0:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.npmmirror.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493"
|
||||||
|
integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==
|
||||||
|
|
||||||
detect-node@^2.0.4:
|
detect-node@^2.0.4:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz"
|
resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz"
|
||||||
@ -5628,6 +5862,11 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
|
|||||||
has "^1.0.3"
|
has "^1.0.3"
|
||||||
has-symbols "^1.0.1"
|
has-symbols "^1.0.1"
|
||||||
|
|
||||||
|
get-nonce@^1.0.0:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.npmmirror.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3"
|
||||||
|
integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==
|
||||||
|
|
||||||
get-own-enumerable-property-symbols@^3.0.0:
|
get-own-enumerable-property-symbols@^3.0.0:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz"
|
resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz"
|
||||||
@ -6236,6 +6475,13 @@ internal-slot@^1.0.3:
|
|||||||
has "^1.0.3"
|
has "^1.0.3"
|
||||||
side-channel "^1.0.4"
|
side-channel "^1.0.4"
|
||||||
|
|
||||||
|
invariant@^2.2.4:
|
||||||
|
version "2.2.4"
|
||||||
|
resolved "https://registry.npmmirror.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
|
||||||
|
integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
|
||||||
|
dependencies:
|
||||||
|
loose-envify "^1.0.0"
|
||||||
|
|
||||||
ip-regex@^2.1.0:
|
ip-regex@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz"
|
resolved "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz"
|
||||||
@ -7472,7 +7718,7 @@ loglevel@^1.6.8:
|
|||||||
resolved "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz"
|
resolved "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz"
|
||||||
integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==
|
integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==
|
||||||
|
|
||||||
loose-envify@^1.1.0, loose-envify@^1.4.0:
|
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
|
resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
|
||||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||||
@ -9606,6 +9852,25 @@ react-refresh@^0.8.3:
|
|||||||
resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz"
|
resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz"
|
||||||
integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==
|
integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==
|
||||||
|
|
||||||
|
react-remove-scroll-bar@^2.3.0:
|
||||||
|
version "2.3.0"
|
||||||
|
resolved "https://registry.npmmirror.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.0.tgz#4f1c8442e4a8bbf98f0cd7ba30fdaf7bf5bcffe5"
|
||||||
|
integrity sha512-v2vf8kgrRph5FQeLVZjSOmM0g3ZiBxwMk98VXhsiJDSPeRDUaXJrzYDk2Hhoe6qLggrhWtAXJZVxUwXmRXa93g==
|
||||||
|
dependencies:
|
||||||
|
react-style-singleton "^2.2.0"
|
||||||
|
tslib "^2.0.0"
|
||||||
|
|
||||||
|
react-remove-scroll@^2.4.0:
|
||||||
|
version "2.5.1"
|
||||||
|
resolved "https://registry.npmmirror.com/react-remove-scroll/-/react-remove-scroll-2.5.1.tgz#28c318c2e076040e5d6172bf28aab2916ad89b46"
|
||||||
|
integrity sha512-Lzam+uvyTLlSCqxGeEe5fLadZQkAYYWurr7P+9kgJfgBcBhs04T181D3yqmUzML63W0FLW/oqSd6dnaE0IIisQ==
|
||||||
|
dependencies:
|
||||||
|
react-remove-scroll-bar "^2.3.0"
|
||||||
|
react-style-singleton "^2.2.0"
|
||||||
|
tslib "^2.0.0"
|
||||||
|
use-callback-ref "^1.3.0"
|
||||||
|
use-sidecar "^1.1.2"
|
||||||
|
|
||||||
react-scripts@4.0.3:
|
react-scripts@4.0.3:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.npmjs.org/react-scripts/-/react-scripts-4.0.3.tgz"
|
resolved "https://registry.npmjs.org/react-scripts/-/react-scripts-4.0.3.tgz"
|
||||||
@ -9672,6 +9937,15 @@ react-scripts@4.0.3:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "^2.1.3"
|
fsevents "^2.1.3"
|
||||||
|
|
||||||
|
react-style-singleton@^2.2.0:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.npmmirror.com/react-style-singleton/-/react-style-singleton-2.2.0.tgz#70f45f5fef97fdb9a52eed98d1839fa6b9032b22"
|
||||||
|
integrity sha512-nK7mN92DMYZEu3cQcAhfwE48NpzO5RpxjG4okbSqRRbfal9Pk+fG2RdQXTMp+f6all1hB9LIJSt+j7dCYrU11g==
|
||||||
|
dependencies:
|
||||||
|
get-nonce "^1.0.0"
|
||||||
|
invariant "^2.2.4"
|
||||||
|
tslib "^2.0.0"
|
||||||
|
|
||||||
react-universal-interface@^0.6.2:
|
react-universal-interface@^0.6.2:
|
||||||
version "0.6.2"
|
version "0.6.2"
|
||||||
resolved "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz"
|
resolved "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz"
|
||||||
@ -11237,11 +11511,16 @@ tsconfig-paths@^3.11.0:
|
|||||||
minimist "^1.2.0"
|
minimist "^1.2.0"
|
||||||
strip-bom "^3.0.0"
|
strip-bom "^3.0.0"
|
||||||
|
|
||||||
tslib@^1.8.1:
|
tslib@^1.0.0, tslib@^1.8.1:
|
||||||
version "1.14.1"
|
version "1.14.1"
|
||||||
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
|
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
|
||||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||||
|
|
||||||
|
tslib@^2.0.0:
|
||||||
|
version "2.4.0"
|
||||||
|
resolved "https://registry.npmmirror.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
|
||||||
|
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
|
||||||
|
|
||||||
tslib@^2.0.3, tslib@^2.1.0:
|
tslib@^2.0.3, tslib@^2.1.0:
|
||||||
version "2.3.1"
|
version "2.3.1"
|
||||||
resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz"
|
resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz"
|
||||||
@ -11482,6 +11761,21 @@ url@^0.11.0:
|
|||||||
punycode "1.3.2"
|
punycode "1.3.2"
|
||||||
querystring "0.2.0"
|
querystring "0.2.0"
|
||||||
|
|
||||||
|
use-callback-ref@^1.3.0:
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.npmmirror.com/use-callback-ref/-/use-callback-ref-1.3.0.tgz#772199899b9c9a50526fedc4993fc7fa1f7e32d5"
|
||||||
|
integrity sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.0.0"
|
||||||
|
|
||||||
|
use-sidecar@^1.1.2:
|
||||||
|
version "1.1.2"
|
||||||
|
resolved "https://registry.npmmirror.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2"
|
||||||
|
integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==
|
||||||
|
dependencies:
|
||||||
|
detect-node-es "^1.1.0"
|
||||||
|
tslib "^2.0.0"
|
||||||
|
|
||||||
use@^3.1.0:
|
use@^3.1.0:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz"
|
resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz"
|
||||||
|
2
setup.py
2
setup.py
@ -21,7 +21,7 @@ def load_requirements():
|
|||||||
# https://setuptools.readthedocs.io/en/latest/setuptools.html#including-data-files
|
# https://setuptools.readthedocs.io/en/latest/setuptools.html#including-data-files
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="lama-cleaner",
|
name="lama-cleaner",
|
||||||
version="0.10.0",
|
version="0.11.0",
|
||||||
author="PanicByte",
|
author="PanicByte",
|
||||||
author_email="cwq1913@gmail.com",
|
author_email="cwq1913@gmail.com",
|
||||||
description="Image inpainting tool powered by SOTA AI Model",
|
description="Image inpainting tool powered by SOTA AI Model",
|
||||||
|
Loading…
Reference in New Issue
Block a user