Compare commits
No commits in common. "f332d9b1771cc01a2ed6b6815f5b88ff9796e552" and "56eeeaaf20b23f56c200731b91aac178615fa5aa" have entirely different histories.
f332d9b177
...
56eeeaaf20
4 changed files with 23 additions and 188 deletions
|
@ -22,7 +22,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Dialog to display transaction details and copy TX ID
|
- Dialog to display transaction details and copy TX ID
|
||||||
- Dialog to send a new transaction
|
- Dialog to send a new transaction
|
||||||
- Dialog to display Tx ID after successful broadcast
|
- Dialog to display Tx ID after successful broadcast
|
||||||
- Unconfirmed balance display on TUI and GUI
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
|
@ -180,7 +180,6 @@ data State = State
|
||||||
, _timer :: !Int
|
, _timer :: !Int
|
||||||
, _txForm :: !(Form SendInput () Name)
|
, _txForm :: !(Form SendInput () Name)
|
||||||
, _sentTx :: !(Maybe HexString)
|
, _sentTx :: !(Maybe HexString)
|
||||||
, _unconfBalance :: !Integer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
makeLenses ''State
|
makeLenses ''State
|
||||||
|
@ -216,12 +215,6 @@ drawUI s = [splashDialog s, helpDialog s, displayDialog s, inputDialog s, ui s]
|
||||||
if st ^. network == MainNet
|
if st ^. network == MainNet
|
||||||
then displayZec (st ^. balance)
|
then displayZec (st ^. balance)
|
||||||
else displayTaz (st ^. balance))) <=>
|
else displayTaz (st ^. balance))) <=>
|
||||||
C.hCenter
|
|
||||||
(str
|
|
||||||
("Unconf: " ++
|
|
||||||
if st ^. network == MainNet
|
|
||||||
then displayZec (st ^. unconfBalance)
|
|
||||||
else displayTaz (st ^. unconfBalance))) <=>
|
|
||||||
listAddressBox "Addresses" (st ^. addresses) <+>
|
listAddressBox "Addresses" (st ^. addresses) <+>
|
||||||
B.vBorder <+>
|
B.vBorder <+>
|
||||||
(C.hCenter (str ("Last block seen: " ++ show (st ^. syncBlock))) <=>
|
(C.hCenter (str ("Last block seen: " ++ show (st ^. syncBlock))) <=>
|
||||||
|
@ -1053,10 +1046,6 @@ runZenithCLI config = do
|
||||||
if not (null accList)
|
if not (null accList)
|
||||||
then getBalance pool $ entityKey $ head accList
|
then getBalance pool $ entityKey $ head accList
|
||||||
else return 0
|
else return 0
|
||||||
uBal <-
|
|
||||||
if not (null accList)
|
|
||||||
then getUnconfirmedBalance pool $ entityKey $ head accList
|
|
||||||
else return 0
|
|
||||||
eventChan <- BC.newBChan 10
|
eventChan <- BC.newBChan 10
|
||||||
_ <-
|
_ <-
|
||||||
forkIO $
|
forkIO $
|
||||||
|
@ -1094,7 +1083,6 @@ runZenithCLI config = do
|
||||||
0
|
0
|
||||||
(mkSendForm 0 $ SendInput "" 0.0 "")
|
(mkSendForm 0 $ SendInput "" 0.0 "")
|
||||||
Nothing
|
Nothing
|
||||||
uBal
|
|
||||||
Left e -> do
|
Left e -> do
|
||||||
print $
|
print $
|
||||||
"No Zebra node available on port " <>
|
"No Zebra node available on port " <>
|
||||||
|
@ -1123,10 +1111,6 @@ refreshWallet s = do
|
||||||
if not (null aL)
|
if not (null aL)
|
||||||
then getBalance pool $ entityKey $ head aL
|
then getBalance pool $ entityKey $ head aL
|
||||||
else return 0
|
else return 0
|
||||||
uBal <-
|
|
||||||
if not (null aL)
|
|
||||||
then getUnconfirmedBalance pool $ entityKey $ head aL
|
|
||||||
else return 0
|
|
||||||
txL <-
|
txL <-
|
||||||
if not (null addrL)
|
if not (null addrL)
|
||||||
then getUserTx pool $ entityKey $ head addrL
|
then getUserTx pool $ entityKey $ head addrL
|
||||||
|
@ -1137,8 +1121,6 @@ refreshWallet s = do
|
||||||
let txL' = L.listReplace (Vec.fromList txL) (Just 0) (s ^. transactions)
|
let txL' = L.listReplace (Vec.fromList txL) (Just 0) (s ^. transactions)
|
||||||
return $
|
return $
|
||||||
s & wallets .~ wL & accounts .~ aL' & syncBlock .~ bl & balance .~ bal &
|
s & wallets .~ wL & accounts .~ aL' & syncBlock .~ bl & balance .~ bal &
|
||||||
unconfBalance .~
|
|
||||||
uBal &
|
|
||||||
addresses .~
|
addresses .~
|
||||||
addrL' &
|
addrL' &
|
||||||
transactions .~
|
transactions .~
|
||||||
|
@ -1209,7 +1191,6 @@ refreshAccount s = do
|
||||||
Just (_k, w) -> return w
|
Just (_k, w) -> return w
|
||||||
aL <- runNoLoggingT $ getAddresses pool $ entityKey selAccount
|
aL <- runNoLoggingT $ getAddresses pool $ entityKey selAccount
|
||||||
bal <- getBalance pool $ entityKey selAccount
|
bal <- getBalance pool $ entityKey selAccount
|
||||||
uBal <- getUnconfirmedBalance pool $ entityKey selAccount
|
|
||||||
let aL' = L.listReplace (Vec.fromList aL) (Just 0) (s ^. addresses)
|
let aL' = L.listReplace (Vec.fromList aL) (Just 0) (s ^. addresses)
|
||||||
selAddress <-
|
selAddress <-
|
||||||
do case L.listSelectedElement aL' of
|
do case L.listSelectedElement aL' of
|
||||||
|
@ -1220,17 +1201,13 @@ refreshAccount s = do
|
||||||
case selAddress of
|
case selAddress of
|
||||||
Nothing ->
|
Nothing ->
|
||||||
return $
|
return $
|
||||||
s & balance .~ bal & unconfBalance .~ uBal & addresses .~ aL' & msg .~
|
s & balance .~ bal & addresses .~ aL' & msg .~ "Switched to account: " ++
|
||||||
"Switched to account: " ++
|
|
||||||
T.unpack (zcashAccountName $ entityVal selAccount)
|
T.unpack (zcashAccountName $ entityVal selAccount)
|
||||||
Just (_i, a) -> do
|
Just (_i, a) -> do
|
||||||
tList <- getUserTx pool $ entityKey a
|
tList <- getUserTx pool $ entityKey a
|
||||||
let tL' = L.listReplace (Vec.fromList tList) (Just 0) (s ^. transactions)
|
let tL' = L.listReplace (Vec.fromList tList) (Just 0) (s ^. transactions)
|
||||||
return $
|
return $
|
||||||
s & balance .~ bal & unconfBalance .~ uBal & addresses .~ aL' &
|
s & balance .~ bal & addresses .~ aL' & transactions .~ tL' & msg .~
|
||||||
transactions .~
|
|
||||||
tL' &
|
|
||||||
msg .~
|
|
||||||
"Switched to account: " ++
|
"Switched to account: " ++
|
||||||
T.unpack (zcashAccountName $ entityVal selAccount)
|
T.unpack (zcashAccountName $ entityVal selAccount)
|
||||||
|
|
||||||
|
|
133
src/Zenith/DB.hs
133
src/Zenith/DB.hs
|
@ -1392,19 +1392,6 @@ getBalance pool za = do
|
||||||
let oBal = sum oAmts
|
let oBal = sum oAmts
|
||||||
return . fromIntegral $ tBal + sBal + oBal
|
return . fromIntegral $ tBal + sBal + oBal
|
||||||
|
|
||||||
getUnconfirmedBalance :: ConnectionPool -> ZcashAccountId -> IO Integer
|
|
||||||
getUnconfirmedBalance pool za = do
|
|
||||||
trNotes <- getWalletUnspentUnconfirmedTrNotes pool za
|
|
||||||
let tAmts = map (walletTrNoteValue . entityVal) trNotes
|
|
||||||
let tBal = sum tAmts
|
|
||||||
sapNotes <- getWalletUnspentUnconfirmedSapNotes pool za
|
|
||||||
let sAmts = map (walletSapNoteValue . entityVal) sapNotes
|
|
||||||
let sBal = sum sAmts
|
|
||||||
orchNotes <- getWalletUnspentUnconfirmedOrchNotes pool za
|
|
||||||
let oAmts = map (walletOrchNoteValue . entityVal) orchNotes
|
|
||||||
let oBal = sum oAmts
|
|
||||||
return . fromIntegral $ tBal + sBal + oBal
|
|
||||||
|
|
||||||
clearWalletTransactions :: ConnectionPool -> IO ()
|
clearWalletTransactions :: ConnectionPool -> IO ()
|
||||||
clearWalletTransactions pool = do
|
clearWalletTransactions pool = do
|
||||||
runNoLoggingT $
|
runNoLoggingT $
|
||||||
|
@ -1442,42 +1429,10 @@ getWalletUnspentTrNotes pool za = do
|
||||||
PS.retryOnBusy $
|
PS.retryOnBusy $
|
||||||
flip PS.runSqlPool pool $ do
|
flip PS.runSqlPool pool $ do
|
||||||
select $ do
|
select $ do
|
||||||
(txs :& tNotes) <-
|
n <- from $ table @WalletTrNote
|
||||||
from $ table @WalletTransaction `innerJoin` table @WalletTrNote `on`
|
where_ (n ^. WalletTrNoteAccId ==. val za)
|
||||||
(\(txs :& tNotes) ->
|
where_ (n ^. WalletTrNoteSpent ==. val False)
|
||||||
txs ^. WalletTransactionId ==. tNotes ^. WalletTrNoteTx)
|
pure n
|
||||||
where_ (tNotes ^. WalletTrNoteAccId ==. val za)
|
|
||||||
where_ (tNotes ^. WalletTrNoteSpent ==. val False)
|
|
||||||
where_
|
|
||||||
((tNotes ^. WalletTrNoteChange ==. val True &&. txs ^.
|
|
||||||
WalletTransactionConf >=.
|
|
||||||
val 3) ||.
|
|
||||||
(tNotes ^. WalletTrNoteChange ==. val False &&. txs ^.
|
|
||||||
WalletTransactionConf >=.
|
|
||||||
val 10))
|
|
||||||
pure tNotes
|
|
||||||
|
|
||||||
getWalletUnspentUnconfirmedTrNotes ::
|
|
||||||
ConnectionPool -> ZcashAccountId -> IO [Entity WalletTrNote]
|
|
||||||
getWalletUnspentUnconfirmedTrNotes pool za = do
|
|
||||||
runNoLoggingT $
|
|
||||||
PS.retryOnBusy $
|
|
||||||
flip PS.runSqlPool pool $ do
|
|
||||||
select $ do
|
|
||||||
(txs :& tNotes) <-
|
|
||||||
from $ table @WalletTransaction `innerJoin` table @WalletTrNote `on`
|
|
||||||
(\(txs :& tNotes) ->
|
|
||||||
txs ^. WalletTransactionId ==. tNotes ^. WalletTrNoteTx)
|
|
||||||
where_ (tNotes ^. WalletTrNoteAccId ==. val za)
|
|
||||||
where_ (tNotes ^. WalletTrNoteSpent ==. val False)
|
|
||||||
where_
|
|
||||||
((tNotes ^. WalletTrNoteChange ==. val True &&. txs ^.
|
|
||||||
WalletTransactionConf <.
|
|
||||||
val 3) ||.
|
|
||||||
(tNotes ^. WalletTrNoteChange ==. val False &&. txs ^.
|
|
||||||
WalletTransactionConf <.
|
|
||||||
val 10))
|
|
||||||
pure tNotes
|
|
||||||
|
|
||||||
getWalletUnspentSapNotes ::
|
getWalletUnspentSapNotes ::
|
||||||
ConnectionPool -> ZcashAccountId -> IO [Entity WalletSapNote]
|
ConnectionPool -> ZcashAccountId -> IO [Entity WalletSapNote]
|
||||||
|
@ -1486,42 +1441,10 @@ getWalletUnspentSapNotes pool za = do
|
||||||
PS.retryOnBusy $
|
PS.retryOnBusy $
|
||||||
flip PS.runSqlPool pool $ do
|
flip PS.runSqlPool pool $ do
|
||||||
select $ do
|
select $ do
|
||||||
(txs :& sNotes) <-
|
n1 <- from $ table @WalletSapNote
|
||||||
from $ table @WalletTransaction `innerJoin` table @WalletSapNote `on`
|
where_ (n1 ^. WalletSapNoteAccId ==. val za)
|
||||||
(\(txs :& sNotes) ->
|
where_ (n1 ^. WalletSapNoteSpent ==. val False)
|
||||||
txs ^. WalletTransactionId ==. sNotes ^. WalletSapNoteTx)
|
pure n1
|
||||||
where_ (sNotes ^. WalletSapNoteAccId ==. val za)
|
|
||||||
where_ (sNotes ^. WalletSapNoteSpent ==. val False)
|
|
||||||
where_
|
|
||||||
((sNotes ^. WalletSapNoteChange ==. val True &&. txs ^.
|
|
||||||
WalletTransactionConf >=.
|
|
||||||
val 3) ||.
|
|
||||||
(sNotes ^. WalletSapNoteChange ==. val False &&. txs ^.
|
|
||||||
WalletTransactionConf >=.
|
|
||||||
val 10))
|
|
||||||
pure sNotes
|
|
||||||
|
|
||||||
getWalletUnspentUnconfirmedSapNotes ::
|
|
||||||
ConnectionPool -> ZcashAccountId -> IO [Entity WalletSapNote]
|
|
||||||
getWalletUnspentUnconfirmedSapNotes pool za = do
|
|
||||||
runNoLoggingT $
|
|
||||||
PS.retryOnBusy $
|
|
||||||
flip PS.runSqlPool pool $ do
|
|
||||||
select $ do
|
|
||||||
(txs :& sNotes) <-
|
|
||||||
from $ table @WalletTransaction `innerJoin` table @WalletSapNote `on`
|
|
||||||
(\(txs :& sNotes) ->
|
|
||||||
txs ^. WalletTransactionId ==. sNotes ^. WalletSapNoteTx)
|
|
||||||
where_ (sNotes ^. WalletSapNoteAccId ==. val za)
|
|
||||||
where_ (sNotes ^. WalletSapNoteSpent ==. val False)
|
|
||||||
where_
|
|
||||||
((sNotes ^. WalletSapNoteChange ==. val True &&. txs ^.
|
|
||||||
WalletTransactionConf <.
|
|
||||||
val 3) ||.
|
|
||||||
(sNotes ^. WalletSapNoteChange ==. val False &&. txs ^.
|
|
||||||
WalletTransactionConf <.
|
|
||||||
val 10))
|
|
||||||
pure sNotes
|
|
||||||
|
|
||||||
getWalletUnspentOrchNotes ::
|
getWalletUnspentOrchNotes ::
|
||||||
ConnectionPool -> ZcashAccountId -> IO [Entity WalletOrchNote]
|
ConnectionPool -> ZcashAccountId -> IO [Entity WalletOrchNote]
|
||||||
|
@ -1530,42 +1453,10 @@ getWalletUnspentOrchNotes pool za = do
|
||||||
PS.retryOnBusy $
|
PS.retryOnBusy $
|
||||||
flip PS.runSqlPool pool $ do
|
flip PS.runSqlPool pool $ do
|
||||||
select $ do
|
select $ do
|
||||||
(txs :& oNotes) <-
|
n2 <- from $ table @WalletOrchNote
|
||||||
from $ table @WalletTransaction `innerJoin` table @WalletOrchNote `on`
|
where_ (n2 ^. WalletOrchNoteAccId ==. val za)
|
||||||
(\(txs :& oNotes) ->
|
where_ (n2 ^. WalletOrchNoteSpent ==. val False)
|
||||||
txs ^. WalletTransactionId ==. oNotes ^. WalletOrchNoteTx)
|
pure n2
|
||||||
where_ (oNotes ^. WalletOrchNoteAccId ==. val za)
|
|
||||||
where_ (oNotes ^. WalletOrchNoteSpent ==. val False)
|
|
||||||
where_
|
|
||||||
((oNotes ^. WalletOrchNoteChange ==. val True &&. txs ^.
|
|
||||||
WalletTransactionConf >=.
|
|
||||||
val 3) ||.
|
|
||||||
(oNotes ^. WalletOrchNoteChange ==. val False &&. txs ^.
|
|
||||||
WalletTransactionConf >=.
|
|
||||||
val 10))
|
|
||||||
pure oNotes
|
|
||||||
|
|
||||||
getWalletUnspentUnconfirmedOrchNotes ::
|
|
||||||
ConnectionPool -> ZcashAccountId -> IO [Entity WalletOrchNote]
|
|
||||||
getWalletUnspentUnconfirmedOrchNotes pool za = do
|
|
||||||
runNoLoggingT $
|
|
||||||
PS.retryOnBusy $
|
|
||||||
flip PS.runSqlPool pool $ do
|
|
||||||
select $ do
|
|
||||||
(txs :& oNotes) <-
|
|
||||||
from $ table @WalletTransaction `innerJoin` table @WalletOrchNote `on`
|
|
||||||
(\(txs :& oNotes) ->
|
|
||||||
txs ^. WalletTransactionId ==. oNotes ^. WalletOrchNoteTx)
|
|
||||||
where_ (oNotes ^. WalletOrchNoteAccId ==. val za)
|
|
||||||
where_ (oNotes ^. WalletOrchNoteSpent ==. val False)
|
|
||||||
where_
|
|
||||||
((oNotes ^. WalletOrchNoteChange ==. val True &&. txs ^.
|
|
||||||
WalletTransactionConf <.
|
|
||||||
val 3) ||.
|
|
||||||
(oNotes ^. WalletOrchNoteChange ==. val False &&. txs ^.
|
|
||||||
WalletTransactionConf <.
|
|
||||||
val 10))
|
|
||||||
pure oNotes
|
|
||||||
|
|
||||||
selectUnspentNotes ::
|
selectUnspentNotes ::
|
||||||
ConnectionPool
|
ConnectionPool
|
||||||
|
|
|
@ -75,7 +75,6 @@ data AppEvent
|
||||||
| SwitchAddr !Int
|
| SwitchAddr !Int
|
||||||
| SwitchAcc !Int
|
| SwitchAcc !Int
|
||||||
| SwitchWal !Int
|
| SwitchWal !Int
|
||||||
| UpdateBalance !(Integer, Integer)
|
|
||||||
| CopyAddr !(Maybe (Entity WalletAddress))
|
| CopyAddr !(Maybe (Entity WalletAddress))
|
||||||
| LoadTxs ![Entity UserTx]
|
| LoadTxs ![Entity UserTx]
|
||||||
| LoadAddrs ![Entity WalletAddress]
|
| LoadAddrs ![Entity WalletAddress]
|
||||||
|
@ -312,7 +311,7 @@ buildUI wenv model = widgetTree
|
||||||
hstack
|
hstack
|
||||||
[ addressBox
|
[ addressBox
|
||||||
, vstack
|
, vstack
|
||||||
[ mainButton "Send" ShowSend `styleBasic` [textFont "Bold"]
|
[ mainButton "Send" ShowSend
|
||||||
, txBox `nodeVisible` not (null $ model ^. transactions)
|
, txBox `nodeVisible` not (null $ model ^. transactions)
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -323,24 +322,19 @@ buildUI wenv model = widgetTree
|
||||||
box_
|
box_
|
||||||
[alignMiddle]
|
[alignMiddle]
|
||||||
(vstack
|
(vstack
|
||||||
[ hstack
|
[ animFadeIn
|
||||||
[ filler
|
(label (displayAmount (model ^. network) $ model ^. balance) `styleBasic`
|
||||||
, animFadeIn
|
|
||||||
(label
|
|
||||||
(displayAmount (model ^. network) $ model ^. balance) `styleBasic`
|
|
||||||
[textSize 20])
|
[textSize 20])
|
||||||
, filler
|
|
||||||
]
|
|
||||||
, hstack
|
, hstack
|
||||||
[ filler
|
[ filler
|
||||||
, remixIcon remixHourglassFill `styleBasic` [textSize 8]
|
, remixIcon remixHourglassFill `styleBasic` [textSize 8]
|
||||||
, label
|
, label
|
||||||
(maybe "0" (displayAmount (model ^. network)) $
|
(maybe "0" (displayAmount (model ^. network)) $
|
||||||
model ^. unconfBalance) `styleBasic`
|
model ^. unconfBalance) `styleBasic`
|
||||||
[textSize 8]
|
[textSize 8] `nodeVisible`
|
||||||
, filler
|
|
||||||
] `nodeVisible`
|
|
||||||
isJust (model ^. unconfBalance)
|
isJust (model ^. unconfBalance)
|
||||||
|
, filler
|
||||||
|
]
|
||||||
]) `styleBasic`
|
]) `styleBasic`
|
||||||
[bgColor white, radius 5, border 1 btnColor]
|
[bgColor white, radius 5, border 1 btnColor]
|
||||||
, filler
|
, filler
|
||||||
|
@ -929,15 +923,6 @@ handleEvent wenv node model evt =
|
||||||
case selectAccount i of
|
case selectAccount i of
|
||||||
Nothing -> return []
|
Nothing -> return []
|
||||||
Just acc -> runNoLoggingT $ getAddresses dbPool $ entityKey acc
|
Just acc -> runNoLoggingT $ getAddresses dbPool $ entityKey acc
|
||||||
, Task $
|
|
||||||
UpdateBalance <$> do
|
|
||||||
dbPool <- runNoLoggingT $ initPool $ c_dbPath $ model ^. configuration
|
|
||||||
case selectAccount i of
|
|
||||||
Nothing -> return (0, 0)
|
|
||||||
Just acc -> do
|
|
||||||
b <- getBalance dbPool $ entityKey acc
|
|
||||||
u <- getUnconfirmedBalance dbPool $ entityKey acc
|
|
||||||
return (b, u)
|
|
||||||
, Event $ SetPool Orchard
|
, Event $ SetPool Orchard
|
||||||
]
|
]
|
||||||
SwitchWal i ->
|
SwitchWal i ->
|
||||||
|
@ -949,13 +934,6 @@ handleEvent wenv node model evt =
|
||||||
Nothing -> return []
|
Nothing -> return []
|
||||||
Just wal -> runNoLoggingT $ getAccounts dbPool $ entityKey wal
|
Just wal -> runNoLoggingT $ getAccounts dbPool $ entityKey wal
|
||||||
]
|
]
|
||||||
UpdateBalance (b, u) ->
|
|
||||||
[ Model $
|
|
||||||
model & balance .~ b & unconfBalance .~
|
|
||||||
(if u == 0
|
|
||||||
then Nothing
|
|
||||||
else Just u)
|
|
||||||
]
|
|
||||||
CopyAddr a ->
|
CopyAddr a ->
|
||||||
[ setClipboardData ClipboardEmpty
|
[ setClipboardData ClipboardEmpty
|
||||||
, setClipboardData $
|
, setClipboardData $
|
||||||
|
@ -1268,14 +1246,6 @@ runZenithGUI config = do
|
||||||
if not (null addrList)
|
if not (null addrList)
|
||||||
then getQrCode pool Orchard $ entityKey $ head addrList
|
then getQrCode pool Orchard $ entityKey $ head addrList
|
||||||
else return Nothing
|
else return Nothing
|
||||||
bal <-
|
|
||||||
if not (null accList)
|
|
||||||
then getBalance pool $ entityKey $ head accList
|
|
||||||
else return 0
|
|
||||||
unconfBal <-
|
|
||||||
if not (null accList)
|
|
||||||
then getUnconfirmedBalance pool $ entityKey $ head accList
|
|
||||||
else return 0
|
|
||||||
let model =
|
let model =
|
||||||
AppModel
|
AppModel
|
||||||
config
|
config
|
||||||
|
@ -1290,10 +1260,8 @@ runZenithGUI config = do
|
||||||
0
|
0
|
||||||
Nothing
|
Nothing
|
||||||
True
|
True
|
||||||
bal
|
314259000
|
||||||
(if unconfBal == 0
|
(Just 300000)
|
||||||
then Nothing
|
|
||||||
else Just unconfBal)
|
|
||||||
Orchard
|
Orchard
|
||||||
qr
|
qr
|
||||||
False
|
False
|
||||||
|
|
Loading…
Reference in a new issue