diff --git a/apps/optimism/optimistic_score_prototype/global.R b/apps/optimism/optimistic_score_prototype/global.R
index 2eef25f..5c2daa2 100644
--- a/apps/optimism/optimistic_score_prototype/global.R
+++ b/apps/optimism/optimistic_score_prototype/global.R
@@ -5,9 +5,11 @@ library(rjson)
#library(devtools)
#install_github("flipsidecrypto/user_metrics/apps/optimism/opAttestR")
+#install.packages("~/user_metrics/apps/optimism/opAttestR_0.0.0.9000.tar.gz", repos = NULL, type="source")
-
-load("data.RData")
+ifelse(Sys.info()[["user"]] == "rstudio-connect",
+ load("/rstudio-data/optimist_score_prototype_data.RData"),
+ load("data.RData"))
signerPrivateKey <- fromJSON(file="./secrets.json")$privateKey
provider <- fromJSON(file="./secrets.json")$provider
diff --git a/apps/optimism/optimistic_score_prototype/server.R b/apps/optimism/optimistic_score_prototype/server.R
index d8c9d81..6d65f9a 100644
--- a/apps/optimism/optimistic_score_prototype/server.R
+++ b/apps/optimism/optimistic_score_prototype/server.R
@@ -1,130 +1,142 @@
function(input, output, session) {
- # read the connected address from the metamask connect funciton
- output$connectedaddress <- renderText(paste0("connected as: ", input$eth_address))
+ # read the connected address from the metamask connect function
+ # output$connectedaddress <- renderText(paste0("connected as: ", input$eth_address))
# isolate the data for that address so we can use it over and over
- thisAddyData <- reactive(op.metrics.w[user_address == tolower(input$eth_address)])
- #thisAddyData <- function() op.metrics.w[user_address == tolower(input$eth_address)]
+ thisAddyData <- reactive({
+
+ print("connectpop:")
+ print(input$connectpop)
+ print("connect:")
+ print(input$connect)
+ print("address")
+ print(input$eth_address)
+ op.metrics.w[user_address == tolower(input$eth_address)]
+ })
- # get the airdrop score and output an empty or full star depending on achievement
+ observeEvent(input$eth_address, {
+ if(substr(input$eth_address, 1, 2) == "0x") {
+ updateActionButton(session = session, inputId = "connect",
+ label = paste0("connected as ", substr(input$eth_address, 1, 7), "..."),
+ icon = character(0))
+ } else {
+
+ updateActionButton(session = session, inputId = "connect",
+ icon = icon("wallet"), label = " Connect Wallet")
+ }
+ })
+
+ output$connectedaddress <- renderText({
+ if(substr(input$eth_address, 1, 2) == "0x") {
+ paste0("Connected as ", substr(input$eth_address, 1, 10), "...")
+ } else {
+ ""
+ }
+ })
+
+ # get the airdrop score and output an empty or full button_filled depending on achievement
# for the connected address
- output$airdropscore <- renderImage({
+ output$airdropscore <- renderText({
# no address available:
if(substr(input$eth_address, 1, 2) != "0x") {
- return(list(src = "www/emptystar.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "X"))
+ return(0)
# does not score or no data available
} else if (nrow(thisAddyData()) == 0) {
- return(list(src = "www/emptystar.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "X"))
+ return(0)
# score!
} else if (thisAddyData()$airdrop_score == 0) {
- return(list(src = "www/emptystar.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "X"))
+ return(0)
} else {
- return(list(src = "www/star.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "⭐️"))
+ return(1)
}
- }, deleteFile = FALSE)
+ })
# repeat ^ for the other 4 scores:
- output$nftscore <- renderImage({
+ output$nftscore <- renderText({
# no address available:
if(substr(input$eth_address, 1, 2) != "0x") {
- return(list(src = "www/emptystar.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "X"))
+ return(0)
# does not score or no data available
} else if (nrow(thisAddyData()) == 0) {
- return(list(src = "www/emptystar.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "X"))
+ return(0)
} else if (thisAddyData()$nft_score == 0) {
- return(list(src = "www/emptystar.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "X"))
+ return(0)
# score!
} else {
- return(list(src = "www/star.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "⭐️"))
+ return(1)
}
- }, deleteFile = FALSE)
+ })
- output$delegatescore <- renderImage({
+ output$delegatescore <- renderText({
# no address available:
if(substr(input$eth_address, 1, 2) != "0x") {
- return(list(src = "www/emptystar.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "X"))
+ return(0)
# does not score or no data available
} else if (nrow(thisAddyData()) == 0) {
- return(list(src = "www/emptystar.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "X"))
+ return(0)
} else if (thisAddyData()$delegation_score == 0) {
- return(list(src = "www/emptystar.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "X"))
+ return(0)
# score!
} else {
- return(list(src = "www/star.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "⭐️"))
+ return(1)
}
- }, deleteFile = FALSE)
+ })
- output$cexscore <- renderImage({
+ output$cexscore <- renderText({
# no address available:
if(substr(input$eth_address, 1, 2) != "0x") {
- return(list(src = "www/emptystar.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "X"))
+ return(0)
# does not score or no data available
} else if (nrow(thisAddyData()) == 0) {
- return(list(src = "www/emptystar.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "X"))
+ return(1)
} else if (thisAddyData()$cex_score == 0) {
- return(list(src = "www/emptystar.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "X"))
+ return(1)
# score!
} else {
- return(list(src = "www/star.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "⭐️"))
+ return(1)
}
- }, deleteFile = FALSE)
+ })
- output$dexscore <- renderImage({
+ output$dexscore <- renderText({
# no address available:
if(substr(input$eth_address, 1, 2) != "0x") {
- return(list(src = "www/emptystar.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "X"))
+ return(0)
# does not score or no data available
} else if (nrow(thisAddyData()) == 0) {
- return(list(src = "www/emptystar.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "X"))
+ return(0)
} else if (thisAddyData()$dex_score == 0) {
- return(list(src = "www/emptystar.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "X"))
+ return(0)
# score!
} else {
- return(list(src = "www/star.svg", contentType = 'image/svg+xml', height = 30, width = 30, alt = "⭐️"))
+ return(1)
}
- }, deleteFile = FALSE)
-
+ })
output$totalscore <- renderText({
-
-
- if(substr(input$eth_address, 1, 2) != "0x") {
-
- "Connect to get your Optimist Score"
-
- } else if(nrow(thisAddyData()) == 0) {
-
-
- "You don't qualify for an Optimist Score. Maybe buy an nft? or delegate some OP?"
-
+ ifelse(substr(input$eth_address, 1, 2) == "0x", userScore(), 0)
+ })
+
+
+ userScore <- reactive({
+ if(nrow(thisAddyData()) > 0) {
+ thisAddyData()$total_score
} else {
-
- paste("You're a ", paste(rep("⭐️", thisAddyData()$total_score), collapse = ""), " Optimist")
-
+ 1
}
-
})
- observeEvent(input$eth_address, {
- print(input$eth_address)
- })
-
- print(signerPrivateKey)
- print(provider)
-
output$tx_handler <- renderUI({
TransactionHandler(
"tx_button",
chainId = 420,
- label = "Make Attestation",
+ label = "Attest Your Score On Chain",
contract_address = "0xD870A73a32d0b8C34CcF1E6098E9A26977CB605b",
contract_abi = abi,
contract_method = "attest",
provider = provider,
- signerPrivateKey = signerPrivateKey,
- args = c(input$eth_address, "Flipside_user_scoring", thisAddyData()$total_score),
+ args = c(input$eth_address, "Flipside_user_scoring", userScore()),
enabled = TRUE
)
})
diff --git a/apps/optimism/optimistic_score_prototype/ui.R b/apps/optimism/optimistic_score_prototype/ui.R
index 8249be8..7e0b22b 100644
--- a/apps/optimism/optimistic_score_prototype/ui.R
+++ b/apps/optimism/optimistic_score_prototype/ui.R
@@ -2,34 +2,77 @@ fluidPage(
tags$head(
tags$link(rel = "stylesheet", type = "text/css", href = "shiny.css"),
tags$link(rel = "stylesheet", href = "https://fonts.googleapis.com/css?family=Roboto+Mono"),
- tags$link(rel = "stylesheet", href = "https://fonts.googleapis.com/css?family=Inter")
+ tags$link(rel = "stylesheet", href = "https://fonts.googleapis.com/css?family=Open+Sans"),
+ tags$link(rel = "stylesheet", href = "https://fonts.googleapis.com/css?family=Rubik")
),
+ # background: linear-gradient(90deg, rgba(255,196,202,0.19511554621848737) 0%, rgba(255,255,255,0) 100%); color: #919EAB;
+
+ fluidRow(class = "titlebar",
+ column(9, img(src = "app_logo.svg", height = "44px", style = "margin-left: 13px; margin-top: 13px; margin-bottom: 13px;")),
+ column(3, style = "text-align: right;", actionButton("connect", icon = icon("wallet"), label = " Connect Wallet")),
+ bsModal(id = "connectpop", title = "", trigger = "connect",
+ WalletHandler("eth_address", chainId = 420))
+ ),
fluidRow(class = "wrapper",
- fluidRow(img(src = "app_logo.svg")),
- fluidRow(class = "walletpart",
- actionButton("connect", icon = icon("wallet"), label = "Connect Wallet"),
- bsModal(id = "connectpop", title = "", trigger = "connect",
- WalletHandler("eth_address", chainId = 420)),
- textOutput("connectedaddress")
+ fluidRow(class = "scoreholder",
+ fluidRow(class = "description", div("Score up to 5 points by doing things that contribute to the Optimism Network. Then click 'Attest Your Score On Chain' to use the ",
+ a("AttestationStation", href = "https://community.optimism.io/docs/governance/attestation-station/", target = "_blank"),
+ " to get your score onchain.")),
+ br(),
+ fluidRow(class = "scorebox",
+ div(class = "alignholder",
+ div(class = "left", textOutput("airdropscore")),
+ div(class = "text", "Claimed the original OP airdrop") )
+ ),
+ fluidRow(class = "scorebox",
+ div(class = "alignholder",
+ div(class = "left", textOutput("delegatescore")),
+ div(class = "text", "Delegated OP at least once") )
+ ),
+ fluidRow(class = "scorebox",
+ div(class = "alignholder",
+ div(class = "left", textOutput("dexscore")),
+ div(class = "text", "Swapped at least once on a dex") )
+ ),
+ fluidRow(class = "scorebox",
+ div(class = "alignholder",
+ div(class = "left", textOutput("nftscore")),
+ div(class = "text", "Bought or Sold at least 1 NFT") )
+ ),
+ fluidRow(class = "scorebox",
+ div(class = "alignholder",
+ div(class = "left", textOutput("cexscore")),
+ div(class = "text", "Sent $0 to a cex or bought more than sold") )
+ ),
+
+
+ br(),
+ fluidRow(div(class = "totalscorebox",
+ div(class = "scorecircle", textOutput("totalscore")),
+ div(class = "scorecolumns", uiOutput("tx_handler"))
+ )
+ )
),
+ br(),
-
-
-
- fluidRow("Earn 1 star for doing each thing on Optimism in the last 180 days:"),
-
- fluidRow(class = "scorebox", imageOutput("airdropscore"), "Claimed the original OP airdrop"),
- fluidRow(class = "scorebox", imageOutput("nftscore"), "Bought or Sold at least 1 NFT"),
- fluidRow(class = "scorebox", imageOutput("delegatescore"), "Delegated OP at least once"),
- fluidRow(class = "scorebox", imageOutput("cexscore"), "Sent $0 to an exchange or bought more than you sold"),
- fluidRow(class = "scorebox", imageOutput("dexscore"), "Swapped at least once on a dex"),
- hr(),
- fluidRow(class = "totalscore", textOutput("totalscore")),
- uiOutput("tx_handler")
- #fluidRow(class = "proveit", actionButton(inputId = "attest", label = "PROVE IT on chain!"))
-
+ fluidRow(class = "bottom",
+ div(class = "LINKS", "FAQ:"),
+ div(class = "links",
+ a(href = "https://community.optimism.io/docs/governance/attestation-station/",
+ "What is Attestation Station?", target = "_blank")),
+ div(class = "links",
+ a(href = "https://github.com/FlipsideCrypto/user_metrics/tree/main/apps/optimism/optimistic_score_prototype",
+ "Can I have this code?", target = "_blank")),
+ div(class = "links",
+ a(href = "https://app.flipsidecrypto.com/dashboard/optimist-score-queries-data-Jp7kIN",
+ "Can I have this data?", target = "_blank")),
+ div(class = "links",
+ a(href = "https://flipsidecrypto.xyz/", "What is Flipside?", target = "_blank"))
+ )
+
+
),
)
\ No newline at end of file
diff --git a/apps/optimism/optimistic_score_prototype/update_data.R b/apps/optimism/optimistic_score_prototype/update_data.R
index e4c5ca7..bac2b2c 100644
--- a/apps/optimism/optimistic_score_prototype/update_data.R
+++ b/apps/optimism/optimistic_score_prototype/update_data.R
@@ -1,43 +1,36 @@
library(shroomDK)
+library(data.table)
-#source("~/data_science/util/util_functions.R")
-# need to replace query snowflake with shrrom dk's
+airdrop.claims <- auto_paginate_query(query = paste(readLines("~/user_metrics/sql/airdrops/optimism/airdrop_claims.sql"), collapse = "\n"),
+ api_key = readLines("api_key.txt"))
+cex.activity <- auto_paginate_query(query = paste(readLines("~/user_metrics/sql/bags/optimism/cex_activity.sql"), collapse = "\n"),
+ api_key = readLines("api_key.txt"))
-airdrop.claims <- QuerySnowflake(paste(readLines("~/user_metrics/sql/airdrops/optimism/airdrop_claims.sql"), collapse = "\n"))
-cex.activity <- QuerySnowflake(paste(readLines("~/user_metrics/sql/bags/optimism/cex_activity.sql"), collapse = "\n"))
-chain.stakes <- QuerySnowflake(paste(readLines("~/user_metrics/sql/governance/optimism/chain_stakes.sql"), collapse = "\n"))
-nft.trades <- QuerySnowflake(paste(readLines("~/user_metrics/sql/nfts/optimism/nft_trades.sql"), collapse = "\n"))
-dex.swaps <- QuerySnowflake(paste(readLines("~/user_metrics/sql/defi/optimism/dex_swaps.sql"), collapse = "\n"))
+chain.stakes <- auto_paginate_query(query = paste(readLines("~/user_metrics/sql/governance/optimism/chain_stakes.sql"), collapse = "\n"),
+ api_key = readLines("api_key.txt"))
-# dex.swaps <- auto_paginate_query(query = paste(readLines("~/user_metrics/sql/airdrops/optimism/airdrop_claims.sql"), collapse = "\n"),
-# api_key = readLines("api_key.txt"))
-#
-# dex.swaps <- auto_paginate_query(query = paste(readLines("~/user_metrics/sql/airdrops/optimism/airdrop_claims.sql"), collapse = "\n"),
-# api_key = readLines("api_key.txt"))
-#
-# dex.swaps <- auto_paginate_query(query = paste(readLines("~/user_metrics/sql/airdrops/optimism/airdrop_claims.sql"), collapse = "\n"),
-# api_key = readLines("api_key.txt"))
-#
-# dex.swaps <- auto_paginate_query(query = paste(readLines("~/user_metrics/sql/airdrops/optimism/airdrop_claims.sql"), collapse = "\n"),
-# api_key = readLines("api_key.txt"))
-#
-# dex.swaps <- data.table(auto_paginate_query(query = paste(readLines("~/user_metrics/sql/airdrops/optimism/airdrop_claims.sql"), collapse = "\n"),
-# api_key = readLines("api_key.txt")))
+nft.trades <- auto_paginate_query(query = paste(readLines("~/user_metrics/sql/nfts/optimism/nft_trades.sql"), collapse = "\n"),
+ api_key = readLines("api_key.txt"))
-op.metrics.w <- MergeDataFrames(
- list(airdrop.claims[, list(user_address, airdrop_tokens_claimed = token_volume)],
- cex.activity[, list(user_address, net_cex_wdraw = wdraw_usd_volume - dep_usd_volume)],
- chain.stakes[, list(user_address, n_delegations = n_stakes)],
- nft.trades[, list(n_trades = sum(n_buys + n_sells)), by = user_address],
- dex.swaps),
- by = "user_address", all = TRUE
-)
+dex.swaps <- data.table(auto_paginate_query(query = paste(readLines("~/user_metrics/sql/defi/optimism/dex_swaps.sql"), collapse = "\n"),
+ api_key = readLines("api_key.txt")))
+op.metrics.w <- merge(airdrop.claims[, list(user_address, airdrop_tokens_claimed = token_volume)],
+ cex.activity[, list(user_address, net_cex_wdraw = wdraw_usd_volume - dep_usd_volume)],
+ by = "user_address", all = TRUE)
+op.metrics.w <- merge(op.metrics.w,
+ chain.stakes[, list(user_address, n_delegations = n_stakes)],
+ by = "user_address", all = TRUE)
+op.metrics.w <- merge(op.metrics.w,
+ cnft.trades[, list(n_trades = sum(n_buys + n_sells)), by = user_address],
+ by = "user_address", all = TRUE)
-ReplaceValues(op.metrics.w)
+op.metrics.w <- merge(op.metrics.w,
+ dex.swaps,
+ by = "user_address", all = TRUE)
op.metrics.w[, airdrop_score := ifelse(airdrop_tokens_claimed > 0, 1, 0)]
op.metrics.w[, cex_score := ifelse(net_cex_wdraw >= 0, 1, 0)]
@@ -47,10 +40,8 @@ op.metrics.w[, dex_score := ifelse(n_swaps > 0, 1, 0)]
op.metrics.w[, total_score := airdrop_score + cex_score + delegation_score + nft_score + dex_score]
-# op.metrics.w[, .N, by = total_score][order(total_score)]
op.metrics.w <- op.metrics.w[total_score > 0]
save(op.metrics.w, file = "data.RData")
-#op.metrics.w[user_address == tolower("0xf76e2d2bba0292cf88f71934aff52ea54baa64d9")]
diff --git a/apps/optimism/optimistic_score_prototype/www/app_logo.svg b/apps/optimism/optimistic_score_prototype/www/app_logo.svg
index 977e21e..102ef38 100644
--- a/apps/optimism/optimistic_score_prototype/www/app_logo.svg
+++ b/apps/optimism/optimistic_score_prototype/www/app_logo.svg
@@ -1,155 +1,131 @@
diff --git a/apps/optimism/optimistic_score_prototype/www/button_empty.svg b/apps/optimism/optimistic_score_prototype/www/button_empty.svg
new file mode 100644
index 0000000..fcdc109
--- /dev/null
+++ b/apps/optimism/optimistic_score_prototype/www/button_empty.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/optimism/optimistic_score_prototype/www/button_filled.svg b/apps/optimism/optimistic_score_prototype/www/button_filled.svg
new file mode 100644
index 0000000..25b589a
--- /dev/null
+++ b/apps/optimism/optimistic_score_prototype/www/button_filled.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/optimism/optimistic_score_prototype/www/shiny.css b/apps/optimism/optimistic_score_prototype/www/shiny.css
index 3075c6d..3bf59f2 100644
--- a/apps/optimism/optimistic_score_prototype/www/shiny.css
+++ b/apps/optimism/optimistic_score_prototype/www/shiny.css
@@ -1,53 +1,202 @@
body {
-background: white;
-background: linear-gradient(90deg, rgba(255,196,202,0.19511554621848737) 0%, rgba(255,255,255,0) 100%); color: #919EAB;
- font-family: 'Inter';
- font-size: 18px;
+ background: white;
+ font-family: 'Open Sans', sans-serif;
+ font-size: 16px;
font-weight: 400;
+ color: black;
+}
+
+a, a:hover, a:visited, a:active {
+ color: red;
}
.container-fluid {
background-color: transparent;
- max-width: 700px;
margin: 0 auto;
height: 100%;
- padding-top: 5%;
padding-left: 0;
padding-right: 0;
}
+.titlebar {
+ height: 70px;
+ box-shadow: rgb(20 23 26 / 6%) 0px 6px 8px -6px, rgb(20 23 26 / 4%) 0px 8px 16px -6px;
+ margin-bottom: 25px;
+ padding-left: 2%;
+}
+
.wrapper {
- border-radius: 16px;
- border: 1px solid #FF0420;
background-color: white;
- margin-top: -5%;
- padding-top: 25px;
- padding-bottom: 3%;
- padding-right: 5%;
- padding-left: 5%;
- margin-bottom: 30px;
+}
+
+#connect {
+ font-family: Rubik;
+ color: #F60001;
+ font-size: 1.02em;
+ padding: 8px;
+ background: linear-gradient(white, white) padding-box,
+ linear-gradient(to right, #F60001, #F60001) border-box;
+ border-radius: 4px;
+ border: 3px solid transparent;
}
.walletpart {
padding-top: 2%;
padding-bottom: 2%;
+ text-align: right;
+}
+
+.description {
+ font-size: 0.85em;
+ color: #353535;
+}
+
+.alignholder {
+ display: flex;
+ width: 85%;
+ margin-left: 10%;
+ margin-right: 10%;
+}
+
+.left {
+ height: 50px;
+ line-height: 50px;
+ width: 20%;
+ background-color: white;
+ border: 2px red solid;
+ border-radius: 4px 0 0 4px;
+ color: red;
+ text-align: center;
+ font-family: Rubik;
+ font-weight: 600;
+ font-size: 1.2em;
}
+.text {
+ height: 50px;
+ line-height: 50px;
+ width: 80%;
+ background-color: red;
+ border-radius: 0 4px 4px 0;
+ border: 2px red solid;
+ color: white;
+ text-align: left;
+ padding-left: 10px;
+}
+
+
+.scoreholder {
+ border: 2px solid red;
+ border-radius: 17px;
+ padding: 10px 30px 0 37px;
+ max-width: 630px;
+ margin: auto;
+}
+
+.bottom {
+ padding: 10px 30px 0 37px;
+ max-width: 634px;
+ margin: auto;
+ text-align: center;
+}
+
+.links > a {
+ text-decoration: underline;
+}
+
+
.scorebox {
display: flex;
- border: 1px solid black;
- border-radius: 5px;
padding: 10px;
- margin-left: 10%;
- margin-right: 10%;
- margin-bottom: 20px;
+}
+
+.totalscorebox {
+ display: flex;
+ width: 86%;
+ margin-left: 12%;
+ margin-right: 12%;
+ margin-bottom: 38px;
+}
+
+.scorecircle {
+ background-color: red;
+ color: white;
+ font-family: Rubik;
+ font-size: 4em;
+ text-align: center;
+ border-radius: 50px;
+ height: 100px;
+ width: 100px;
+ line-height: 100px;
}
.shiny-image-output {
- height: 30px !important;
- width: 30px !important;
+ height: 25px !important;
+ width: 25px !important;
margin-right: 10px;
}
+button {
+ border: 1px red solid;
+ padding: 5px;
+ color: red;
+ background-color: white;
+ margin: 10px;
+ border-radius: 4px;
+ min-width: 250px;
+}
+
+
+#tx_button > button {
+ font-family: Rubik;
+ color: white;
+ background-color: #F60001;
+ font-size: 1.3em;
+ padding: 10px;
+ border-radius: 4px;
+ border: 3px solid transparent;
+}
+
+.scorecolumns {
+ padding-left: 30px;
+ padding-right: 30px;
+ margin-top: 10px;
+}
+
+
+.txbuttondiv {
+ padding-top: 7%;
+}
+
+.modal-dialog {
+ margin-left: 30%;
+ margin-right: 30%;
+}
+
+.modal-content {
+ background-color: white;
+ border: 1px solid #F60001;
+}
+.modal-title {
+ color: red;
+ font-weight: bold;
+ border: none;
+}
+.modal-body {
+ border: none;
+ text-align: center;
+}
+.modal-footer {
+ border: none;
+}
+
+
+
+.links {
+ color: red;
+ font-size: 0.95em;
+ text-align: center;
+}
+