From 5991631bfa584512e7688c7a4378f566cb512920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Schw=C3=B6rer?= Date: Fri, 18 Nov 2022 21:25:40 +0100 Subject: [PATCH] `POST:/users` works --- server/.idea/dataSources.xml | 2 +- server/.idea/sqldialects.xml | 6 +- server/api/apierr/enums.go | 20 +- server/api/handler/api.go | 167 ++++++ server/api/handler/common.go | 17 +- server/api/handler/compat.go | 165 +----- server/api/handler/message.go | 21 + server/api/handler/website.go | 98 ++++ server/api/models/client.go | 23 + server/api/models/user.go | 51 ++ server/api/models/utils.go | 14 + server/api/router.go | 122 ++++- server/cmd/scnserver/main.go | 7 +- server/common/ginresp/apiError.go | 9 +- server/common/ginresp/error.go | 6 - server/common/ginresp/resp.go | 19 +- server/common/ginresp/wrapper.go | 8 +- server/config.go | 61 ++- server/db/context.go | 15 + server/db/database.go | 51 +- server/db/methods.go | 112 +++++ server/db/{schema_1.0.sql => schema_1.0.ddl} | 0 server/db/{schema_2.0.sql => schema_2.0.ddl} | 0 server/db/{schema_3.0.sql => schema_3.0.ddl} | 54 +- server/db/schema_sqlite.ddl | 7 + server/db/utils.go | 15 + server/logic/application.go | 45 +- server/logic/context.go | 75 +++ server/swagger/swagger.json | 503 +++++++++---------- server/swagger/swagger.yaml | 330 ++++++------ server/website/api.html | 47 ++ server/website/api_more.html | 299 +++++++++++ server/website/css/mini-dark.min.css | 1 + server/website/css/mini-default.min.css | 1 + server/website/css/mini-nord.min.css | 1 + server/website/css/style.css | 250 +++++++++ server/website/css/toastify.min.css | 15 + server/website/favicon.ico | Bin 0 -> 99678 bytes server/website/favicon.png | Bin 0 -> 92707 bytes server/website/index.html | 69 +++ server/website/js/logic.js | 90 ++++ server/website/js/toastify.js | 8 + server/website/message_sent.html | 56 +++ server/website/website.go | 8 + 44 files changed, 2131 insertions(+), 737 deletions(-) create mode 100644 server/api/handler/api.go create mode 100644 server/api/handler/message.go create mode 100644 server/api/handler/website.go create mode 100644 server/api/models/client.go create mode 100644 server/api/models/user.go create mode 100644 server/api/models/utils.go delete mode 100644 server/common/ginresp/error.go create mode 100644 server/db/context.go create mode 100644 server/db/methods.go rename server/db/{schema_1.0.sql => schema_1.0.ddl} (100%) rename server/db/{schema_2.0.sql => schema_2.0.ddl} (100%) rename server/db/{schema_3.0.sql => schema_3.0.ddl} (69%) create mode 100644 server/db/schema_sqlite.ddl create mode 100644 server/db/utils.go create mode 100644 server/logic/context.go create mode 100644 server/website/api.html create mode 100644 server/website/api_more.html create mode 100644 server/website/css/mini-dark.min.css create mode 100644 server/website/css/mini-default.min.css create mode 100644 server/website/css/mini-nord.min.css create mode 100644 server/website/css/style.css create mode 100644 server/website/css/toastify.min.css create mode 100644 server/website/favicon.ico create mode 100644 server/website/favicon.png create mode 100644 server/website/index.html create mode 100644 server/website/js/logic.js create mode 100644 server/website/js/toastify.js create mode 100644 server/website/message_sent.html create mode 100644 server/website/website.go diff --git a/server/.idea/dataSources.xml b/server/.idea/dataSources.xml index 9f38ede..776c738 100644 --- a/server/.idea/dataSources.xml +++ b/server/.idea/dataSources.xml @@ -1,7 +1,7 @@ - + sqlite.xerial true org.sqlite.JDBC diff --git a/server/.idea/sqldialects.xml b/server/.idea/sqldialects.xml index a5d08e4..8a4b714 100644 --- a/server/.idea/sqldialects.xml +++ b/server/.idea/sqldialects.xml @@ -1,7 +1,11 @@ - + + + + + \ No newline at end of file diff --git a/server/api/apierr/enums.go b/server/api/apierr/enums.go index 9180476..8401c66 100644 --- a/server/api/apierr/enums.go +++ b/server/api/apierr/enums.go @@ -5,11 +5,15 @@ type APIError int const ( NO_ERROR APIError = 0000 - MISSING_UID APIError = 1101 - MISSING_TOK APIError = 1102 - MISSING_TITLE APIError = 1103 - INVALID_PRIO APIError = 1104 - REQ_METHOD APIError = 1105 + MISSING_UID APIError = 1101 + MISSING_TOK APIError = 1102 + MISSING_TITLE APIError = 1103 + INVALID_PRIO APIError = 1104 + REQ_METHOD APIError = 1105 + INVALID_CLIENTTYPE APIError = 1106 + MISSING_QUERY_PARAM APIError = 1151 + MISSING_BODY_PARAM APIError = 1152 + MISSING_URI_PARAM APIError = 1153 NO_TITLE APIError = 1201 TITLE_TOO_LONG APIError = 1202 @@ -24,6 +28,12 @@ const ( QUOTA_REACHED APIError = 2101 + FAILED_VERIFY_PRO_TOKEN APIError = 3001 + INVALID_PRO_TOKEN APIError = 3002 + + COMMIT_FAILED = 9001 + DATABASE_ERROR = 9002 + FIREBASE_COM_FAILED APIError = 9901 FIREBASE_COM_ERRORED APIError = 9902 INTERNAL_EXCEPTION APIError = 9903 diff --git a/server/api/handler/api.go b/server/api/handler/api.go new file mode 100644 index 0000000..12f03cc --- /dev/null +++ b/server/api/handler/api.go @@ -0,0 +1,167 @@ +package handler + +import ( + "blackforestbytes.com/simplecloudnotifier/api/apierr" + "blackforestbytes.com/simplecloudnotifier/api/models" + "blackforestbytes.com/simplecloudnotifier/common/ginresp" + "blackforestbytes.com/simplecloudnotifier/logic" + "github.com/gin-gonic/gin" + "net/http" +) + +type APIHandler struct { + app *logic.Application +} + +// CreateUser swaggerdoc +// +// @Summary Create a new user +// @ID api-user-create +// +// @Param post_body body handler.CreateUser.body false " " +// +// @Success 200 {object} models.UserJSON +// @Failure 400 {object} ginresp.apiError +// @Failure 500 {object} ginresp.apiError +// +// @Router /api-v2/user/ [POST] +func (h APIHandler) CreateUser(g *gin.Context) ginresp.HTTPResponse { + type body struct { + FCMToken string `form:"fcm_token"` + ProToken *string `form:"pro_token"` + Username *string `form:"username"` + AgentModel string `form:"agent_model"` + AgentVersion string `form:"agent_version"` + ClientType string `form:"client_type"` + } + + ctx := h.app.StartRequest(g) + defer ctx.Cancel() + + var b body + if err := g.ShouldBindJSON(&b); err != nil { + return ginresp.InternAPIError(apierr.MISSING_BODY_PARAM, "Failed to read body", err) + } + + var clientType models.ClientType + if b.ClientType == string(models.ClientTypeAndroid) { + clientType = models.ClientTypeAndroid + } else if b.ClientType == string(models.ClientTypeIOS) { + clientType = models.ClientTypeIOS + } else { + return ginresp.InternAPIError(apierr.INVALID_CLIENTTYPE, "Invalid ClientType", nil) + } + + if b.ProToken != nil { + ptok, err := h.app.VerifyProToken(*b.ProToken) + if err != nil { + return ginresp.InternAPIError(apierr.FAILED_VERIFY_PRO_TOKEN, "Failed to query purchase status", err) + } + + if !ptok { + return ginresp.InternAPIError(apierr.INVALID_PRO_TOKEN, "Purchase token could not be verified", nil) + } + } + + readKey := h.app.GenerateRandomAuthKey() + sendKey := h.app.GenerateRandomAuthKey() + adminKey := h.app.GenerateRandomAuthKey() + + err := h.app.Database.ClearFCMTokens(ctx, b.FCMToken) + if err != nil { + return ginresp.InternAPIError(apierr.DATABASE_ERROR, "Failed to clear existing fcm tokens", err) + } + + if b.ProToken != nil { + err := h.app.Database.ClearProTokens(ctx, b.FCMToken) + if err != nil { + return ginresp.InternAPIError(apierr.DATABASE_ERROR, "Failed to clear existing fcm tokens", err) + } + } + + userobj, err := h.app.Database.CreateUser(ctx, readKey, sendKey, adminKey, b.ProToken, b.Username) + if err != nil { + return ginresp.InternAPIError(apierr.DATABASE_ERROR, "Failed to create user in db", err) + } + + _, err = h.app.Database.CreateClient(ctx, userobj.UserID, clientType, b.FCMToken, b.AgentModel, b.AgentVersion) + if err != nil { + return ginresp.InternAPIError(apierr.DATABASE_ERROR, "Failed to create user in db", err) + } + + return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, userobj.JSON())) +} + +func (h APIHandler) GetUser(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) UpdateUser(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) ListClients(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) GetClient(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) AddClient(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) DeleteClient(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) ListChannels(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) GetChannel(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) GetChannelMessages(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) ListUserSubscriptions(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) ListChannelSubscriptions(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) GetSubscription(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) CancelSubscription(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) CreateSubscription(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) ListMessages(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) GetMessage(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func (h APIHandler) DeleteMessage(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func NewAPIHandler(app *logic.Application) APIHandler { + return APIHandler{ + app: app, + } +} diff --git a/server/api/handler/common.go b/server/api/handler/common.go index 9160c69..7e68130 100644 --- a/server/api/handler/common.go +++ b/server/api/handler/common.go @@ -34,7 +34,7 @@ type pingResponseInfo struct { // Ping swaggerdoc // // @Success 200 {object} pingResponse -// @Failure 500 {object} ginresp.errBody +// @Failure 500 {object} ginresp.apiError // @Router /ping [get] // @Router /ping [post] // @Router /ping [put] @@ -60,7 +60,7 @@ func (h CommonHandler) Ping(g *gin.Context) ginresp.HTTPResponse { // DatabaseTest swaggerdoc // // @Success 200 {object} handler.DatabaseTest.response -// @Failure 500 {object} ginresp.errBody +// @Failure 500 {object} ginresp.apiError // @Router /db-test [get] func (h CommonHandler) DatabaseTest(g *gin.Context) ginresp.HTTPResponse { type response struct { @@ -88,7 +88,7 @@ func (h CommonHandler) DatabaseTest(g *gin.Context) ginresp.HTTPResponse { // Health swaggerdoc // // @Success 200 {object} handler.Health.response -// @Failure 500 {object} ginresp.errBody +// @Failure 500 {object} ginresp.apiError // @Router /health [get] func (h CommonHandler) Health(*gin.Context) ginresp.HTTPResponse { type response struct { @@ -96,3 +96,14 @@ func (h CommonHandler) Health(*gin.Context) ginresp.HTTPResponse { } return ginresp.JSON(http.StatusOK, response{Status: "ok"}) } + +func (h CommonHandler) NoRoute(g *gin.Context) ginresp.HTTPResponse { + return ginresp.JSON(http.StatusNotFound, gin.H{ + "FullPath": g.FullPath(), + "Method": g.Request.Method, + "URL": g.Request.URL.String(), + "RequestURI": g.Request.RequestURI, + "Proto": g.Request.Proto, + "Header": g.Request.Header, + }) +} diff --git a/server/api/handler/compat.go b/server/api/handler/compat.go index 9bee99a..026db23 100644 --- a/server/api/handler/compat.go +++ b/server/api/handler/compat.go @@ -1,17 +1,10 @@ package handler import ( - "blackforestbytes.com/simplecloudnotifier/api/apierr" "blackforestbytes.com/simplecloudnotifier/api/models" "blackforestbytes.com/simplecloudnotifier/common/ginresp" "blackforestbytes.com/simplecloudnotifier/logic" - "context" - "database/sql" - "fmt" "github.com/gin-gonic/gin" - "net/http" - "strconv" - "time" ) type CompatHandler struct { @@ -32,8 +25,8 @@ func NewCompatHandler(app *logic.Application) CompatHandler { // @Param pro query string true "if the user is a paid account" Enums(true, false) // @Param pro_token query string true "the (android) IAP token" // @Success 200 {object} handler.Register.response -// @Failure 500 {object} ginresp.internAPIError -// @Router /register.php [get] +// @Failure 500 {object} ginresp.apiError +// @Router /api/register.php [get] func (h CompatHandler) Register(g *gin.Context) ginresp.HTTPResponse { type query struct { FCMToken *string `form:"fcm_token"` @@ -50,81 +43,9 @@ func (h CompatHandler) Register(g *gin.Context) ginresp.HTTPResponse { IsPro int `json:"is_pro"` } - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() + //TODO - var q query - if err := g.ShouldBindQuery(&q); err != nil { - return ginresp.InternAPIError(0, "Failed to read arguments") - } - - if q.FCMToken == nil { - return ginresp.InternAPIError(0, "Missing parameter [[fcm_token]]") - } - if q.Pro == nil { - return ginresp.InternAPIError(0, "Missing parameter [[pro]]") - } - if q.ProToken == nil { - return ginresp.InternAPIError(0, "Missing parameter [[pro_token]]") - } - - isProInt := 0 - isProBool := false - if *q.Pro == "true" { - isProInt = 1 - isProBool = true - } else { - q.ProToken = nil - } - - if isProBool { - ptok, err := h.app.VerifyProToken(*q.ProToken) - if err != nil { - return ginresp.InternAPIError(0, fmt.Sprintf("Failed to query purchaste status: %v", err)) - } - - if !ptok { - return ginresp.InternAPIError(0, "Purchase token could not be verified") - } - } - - userKey := h.app.GenerateRandomAuthKey() - - return h.app.RunTransaction(ctx, nil, func(tx *sql.Tx) (ginresp.HTTPResponse, bool) { - - res, err := tx.ExecContext(ctx, "INSERT INTO users (user_key, fcm_token, is_pro, pro_token, timestamp_accessed) VALUES (?, ?, ?, ?, NOW())", userKey, *q.FCMToken, isProInt, q.ProToken) - if err != nil { - return ginresp.InternAPIError(0, fmt.Sprintf("Failed to create user: %v", err)), false - } - - userId, err := res.LastInsertId() - if err != nil { - return ginresp.InternAPIError(0, fmt.Sprintf("Failed to get user_id: %v", err)), false - } - - _, err = tx.ExecContext(ctx, "UPDATE users SET fcm_token=NULL WHERE user_id <> ? AND fcm_token=?", userId, q.FCMToken) - if err != nil { - return ginresp.InternAPIError(0, fmt.Sprintf("Failed to update fcm: %v", err)), false - } - - if isProInt == 1 { - _, err := tx.ExecContext(ctx, "UPDATE users SET is_pro=0, pro_token=NULL WHERE user_id <> ? AND pro_token = ?", userId, q.ProToken) - if err != nil { - return ginresp.InternAPIError(0, fmt.Sprintf("Failed to update ispro: %v", err)), false - } - } - - return ginresp.JSON(http.StatusOK, response{ - Success: true, - Message: "New user registered", - UserID: strconv.FormatInt(userId, 10), - UserKey: userKey, - QuotaUsed: 0, - QuotaMax: h.app.QuotaMax(isProBool), - IsPro: isProInt, - }), true - - }) + return ginresp.NotImplemented() } // Info swaggerdoc @@ -134,8 +55,8 @@ func (h CompatHandler) Register(g *gin.Context) ginresp.HTTPResponse { // @Param user_id query string true "the user_id" // @Param user_key query string true "the user_key" // @Success 200 {object} handler.Info.response -// @Failure 500 {object} ginresp.internAPIError -// @Router /info.php [get] +// @Failure 500 {object} ginresp.apiError +// @Router /api/info.php [get] func (h CompatHandler) Info(g *gin.Context) ginresp.HTTPResponse { type query struct { UserID string `form:"user_id"` @@ -155,7 +76,7 @@ func (h CompatHandler) Info(g *gin.Context) ginresp.HTTPResponse { //TODO - return ginresp.InternAPIError(0, "NotImplemented") + return ginresp.NotImplemented() } // Ack swaggerdoc @@ -166,8 +87,8 @@ func (h CompatHandler) Info(g *gin.Context) ginresp.HTTPResponse { // @Param user_key query string true "the user_key" // @Param scn_msg_id query string true "the message id" // @Success 200 {object} handler.Ack.response -// @Failure 500 {object} ginresp.internAPIError -// @Router /ack.php [get] +// @Failure 500 {object} ginresp.apiError +// @Router /api/ack.php [get] func (h CompatHandler) Ack(g *gin.Context) ginresp.HTTPResponse { type query struct { UserID string `form:"user_id"` @@ -183,7 +104,7 @@ func (h CompatHandler) Ack(g *gin.Context) ginresp.HTTPResponse { //TODO - return ginresp.InternAPIError(0, "NotImplemented") + return ginresp.NotImplemented() } // Requery swaggerdoc @@ -193,8 +114,8 @@ func (h CompatHandler) Ack(g *gin.Context) ginresp.HTTPResponse { // @Param user_id query string true "the user_id" // @Param user_key query string true "the user_key" // @Success 200 {object} handler.Requery.response -// @Failure 500 {object} ginresp.internAPIError -// @Router /requery.php [get] +// @Failure 500 {object} ginresp.apiError +// @Router /api/requery.php [get] func (h CompatHandler) Requery(g *gin.Context) ginresp.HTTPResponse { type query struct { UserID string `form:"user_id"` @@ -209,7 +130,7 @@ func (h CompatHandler) Requery(g *gin.Context) ginresp.HTTPResponse { //TODO - return ginresp.InternAPIError(0, "NotImplemented") + return ginresp.NotImplemented() } // Update swaggerdoc @@ -220,8 +141,8 @@ func (h CompatHandler) Requery(g *gin.Context) ginresp.HTTPResponse { // @Param user_key query string true "the user_key" // @Param fcm_token query string true "the (android) fcm token" // @Success 200 {object} handler.Update.response -// @Failure 500 {object} ginresp.internAPIError -// @Router /update.php [get] +// @Failure 500 {object} ginresp.apiError +// @Router /api/update.php [get] func (h CompatHandler) Update(g *gin.Context) ginresp.HTTPResponse { type query struct { UserID string `form:"user_id"` @@ -240,7 +161,7 @@ func (h CompatHandler) Update(g *gin.Context) ginresp.HTTPResponse { //TODO - return ginresp.InternAPIError(0, "NotImplemented") + return ginresp.NotImplemented() } // Expand swaggerdoc @@ -248,8 +169,8 @@ func (h CompatHandler) Update(g *gin.Context) ginresp.HTTPResponse { // @Summary Get a whole (potentially truncated) message // @ID compat-expand // @Success 200 {object} handler.Expand.response -// @Failure 500 {object} ginresp.internAPIError -// @Router /expand.php [get] +// @Failure 500 {object} ginresp.apiError +// @Router /api/expand.php [get] func (h CompatHandler) Expand(g *gin.Context) ginresp.HTTPResponse { type query struct { UserID string `form:"user_id"` @@ -264,7 +185,7 @@ func (h CompatHandler) Expand(g *gin.Context) ginresp.HTTPResponse { //TODO - return ginresp.InternAPIError(0, "NotImplemented") + return ginresp.NotImplemented() } // Upgrade swaggerdoc @@ -276,8 +197,8 @@ func (h CompatHandler) Expand(g *gin.Context) ginresp.HTTPResponse { // @Param pro query string true "if the user is a paid account" Enums(true, false) // @Param pro_token query string true "the (android) IAP token" // @Success 200 {object} handler.Upgrade.response -// @Failure 500 {object} ginresp.internAPIError -// @Router /upgrade.php [get] +// @Failure 500 {object} ginresp.apiError +// @Router /api/upgrade.php [get] func (h CompatHandler) Upgrade(g *gin.Context) ginresp.HTTPResponse { type query struct { UserID string `form:"user_id"` @@ -293,47 +214,5 @@ func (h CompatHandler) Upgrade(g *gin.Context) ginresp.HTTPResponse { //TODO - return ginresp.InternAPIError(0, "NotImplemented") -} - -// Send swaggerdoc -// -// @Summary Send a message -// @Description (all arguments can either be supplied in the query or in the json body) -// @ID compat-send -// @Accept json -// @Produce json -// @Param _ query handler.Send.query false " " -// @Param post_body body handler.Send.body false " " -// @Success 200 {object} handler.Send.response -// @Failure 500 {object} ginresp.sendAPIError -// @Router /send.php [post] -func (h CompatHandler) Send(g *gin.Context) ginresp.HTTPResponse { - type query struct { - UserID string `form:"user_id" required:"true"` - UserKey string `form:"user_key" required:"true"` - Title string `form:"title" required:"true"` - Content *string `form:"content"` - Priority *string `form:"priority"` - MessageID *string `form:"msg_id"` - Timestamp *string `form:"timestamp"` - } - type body struct { - UserID string `json:"user_id" required:"true"` - UserKey string `json:"user_key" required:"true"` - Title string `json:"title" required:"true"` - Content *string `json:"content"` - Priority *string `json:"priority"` - MessageID *string `json:"msg_id"` - Timestamp *string `json:"timestamp"` - } - type response struct { - Success string `json:"success"` - Message string `json:"message"` - //TODO - } - - //TODO - - return ginresp.SendAPIError(apierr.INTERNAL_EXCEPTION, -1, "NotImplemented") + return ginresp.NotImplemented() } diff --git a/server/api/handler/message.go b/server/api/handler/message.go new file mode 100644 index 0000000..0c64fdc --- /dev/null +++ b/server/api/handler/message.go @@ -0,0 +1,21 @@ +package handler + +import ( + "blackforestbytes.com/simplecloudnotifier/common/ginresp" + "blackforestbytes.com/simplecloudnotifier/logic" + "github.com/gin-gonic/gin" +) + +type MessageHandler struct { + app *logic.Application +} + +func (h MessageHandler) SendMessage(g *gin.Context) ginresp.HTTPResponse { + return ginresp.NotImplemented() +} + +func NewMessageHandler(app *logic.Application) MessageHandler { + return MessageHandler{ + app: app, + } +} diff --git a/server/api/handler/website.go b/server/api/handler/website.go new file mode 100644 index 0000000..b93d539 --- /dev/null +++ b/server/api/handler/website.go @@ -0,0 +1,98 @@ +package handler + +import ( + "blackforestbytes.com/simplecloudnotifier/common/ginresp" + "blackforestbytes.com/simplecloudnotifier/logic" + "blackforestbytes.com/simplecloudnotifier/website" + "github.com/gin-gonic/gin" + "net/http" + "strings" +) + +type WebsiteHandler struct { + app *logic.Application +} + +func NewWebsiteHandler(app *logic.Application) WebsiteHandler { + return WebsiteHandler{ + app: app, + } +} + +func (h WebsiteHandler) Index(g *gin.Context) ginresp.HTTPResponse { + return h.serveAsset(g, "index.html") +} + +func (h WebsiteHandler) APIDocs(g *gin.Context) ginresp.HTTPResponse { + return h.serveAsset(g, "api.html") +} + +func (h WebsiteHandler) APIDocsMore(g *gin.Context) ginresp.HTTPResponse { + return h.serveAsset(g, "api_more.html") +} + +func (h WebsiteHandler) MessageSent(g *gin.Context) ginresp.HTTPResponse { + return h.serveAsset(g, "message_sent.html") +} + +func (h WebsiteHandler) FaviconIco(g *gin.Context) ginresp.HTTPResponse { + return h.serveAsset(g, "favicon.ico") +} + +func (h WebsiteHandler) FaviconPNG(g *gin.Context) ginresp.HTTPResponse { + return h.serveAsset(g, "favicon.png") +} + +func (h WebsiteHandler) Javascript(g *gin.Context) ginresp.HTTPResponse { + type uri struct { + Filename string `uri:"fn"` + } + + var u uri + if err := g.ShouldBindUri(&u); err != nil { + return ginresp.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + } + + return h.serveAsset(g, "js/"+u.Filename) +} + +func (h WebsiteHandler) CSS(g *gin.Context) ginresp.HTTPResponse { + type uri struct { + Filename string `uri:"fn"` + } + + var u uri + if err := g.ShouldBindUri(&u); err != nil { + return ginresp.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + } + + return h.serveAsset(g, "css/"+u.Filename) +} + +func (h WebsiteHandler) serveAsset(g *gin.Context, fn string) ginresp.HTTPResponse { + data, err := website.Assets.ReadFile(fn) + if err != nil { + return ginresp.Status(http.StatusNotFound) + } + + mime := "text/plain" + + lowerFN := strings.ToLower(fn) + if strings.HasSuffix(lowerFN, ".html") || strings.HasSuffix(lowerFN, ".htm") { + mime = "text/html" + } else if strings.HasSuffix(lowerFN, ".css") { + mime = "text/css" + } else if strings.HasSuffix(lowerFN, ".js") { + mime = "text/javascript" + } else if strings.HasSuffix(lowerFN, ".json") { + mime = "application/json" + } else if strings.HasSuffix(lowerFN, ".jpeg") || strings.HasSuffix(lowerFN, ".jpg") { + mime = "image/jpeg" + } else if strings.HasSuffix(lowerFN, ".png") { + mime = "image/png" + } else if strings.HasSuffix(lowerFN, ".svg") { + mime = "image/svg+xml" + } + + return ginresp.Data(http.StatusOK, mime, data) +} diff --git a/server/api/models/client.go b/server/api/models/client.go new file mode 100644 index 0000000..544a745 --- /dev/null +++ b/server/api/models/client.go @@ -0,0 +1,23 @@ +package models + +import "time" + +type ClientType string + +const ( + ClientTypeAndroid ClientType = "ANDROID" + ClientTypeIOS ClientType = "IOS" +) + +type Client struct { + ClientID int64 + UserID int64 + Type ClientType + FCMToken *string + TimestampCreated time.Time + AgentModel string + AgentVersion string +} + +type ClientJSON struct { +} diff --git a/server/api/models/user.go b/server/api/models/user.go new file mode 100644 index 0000000..cdb8919 --- /dev/null +++ b/server/api/models/user.go @@ -0,0 +1,51 @@ +package models + +import "time" + +type User struct { + UserID int64 + Username *string + ReadKey string + SendKey string + AdminKey string + TimestampCreated time.Time + TimestampLastRead *time.Time + TimestampLastSent *time.Time + MessagesSent int + QuotaToday int + QuotaDay *string + IsPro bool + ProToken *string +} + +func (u User) JSON() UserJSON { + return UserJSON{ + UserID: u.UserID, + Username: u.Username, + ReadKey: u.ReadKey, + SendKey: u.SendKey, + AdminKey: u.AdminKey, + TimestampCreated: u.TimestampCreated.Format(time.RFC3339Nano), + TimestampLastRead: timeOptFmt(u.TimestampLastRead, time.RFC3339Nano), + TimestampLastSent: timeOptFmt(u.TimestampLastSent, time.RFC3339Nano), + MessagesSent: u.MessagesSent, + QuotaToday: u.QuotaToday, + QuotaDay: u.QuotaDay, + IsPro: u.IsPro, + } +} + +type UserJSON struct { + UserID int64 `json:"user_id"` + Username *string `json:"username"` + ReadKey string `json:"read_key"` + SendKey string `json:"send_key"` + AdminKey string `json:"admin_key"` + TimestampCreated string `json:"timestamp_created"` + TimestampLastRead *string `json:"timestamp_last_read"` + TimestampLastSent *string `json:"timestamp_last_sent"` + MessagesSent int `json:"messages_sent"` + QuotaToday int `json:"quota_today"` + QuotaDay *string `json:"quota_day"` + IsPro bool `json:"is_pro"` +} diff --git a/server/api/models/utils.go b/server/api/models/utils.go new file mode 100644 index 0000000..6e2d0f4 --- /dev/null +++ b/server/api/models/utils.go @@ -0,0 +1,14 @@ +package models + +import ( + "gogs.mikescher.com/BlackForestBytes/goext/langext" + "time" +) + +func timeOptFmt(t *time.Time, fmt string) *string { + if t == nil { + return nil + } else { + return langext.Ptr(t.Format(fmt)) + } +} diff --git a/server/api/router.go b/server/api/router.go index 2985e6f..a0e79d9 100644 --- a/server/api/router.go +++ b/server/api/router.go @@ -12,16 +12,22 @@ import ( type Router struct { app *logic.Application - commonHandler handler.CommonHandler - compatHandler handler.CompatHandler + commonHandler handler.CommonHandler + compatHandler handler.CompatHandler + websiteHandler handler.WebsiteHandler + apiHandler handler.APIHandler + messageHandler handler.MessageHandler } func NewRouter(app *logic.Application) *Router { return &Router{ app: app, - commonHandler: handler.NewCommonHandler(app), - compatHandler: handler.NewCompatHandler(app), + commonHandler: handler.NewCommonHandler(app), + compatHandler: handler.NewCompatHandler(app), + websiteHandler: handler.NewWebsiteHandler(app), + apiHandler: handler.NewAPIHandler(app), + messageHandler: handler.NewMessageHandler(app), } } @@ -30,23 +36,101 @@ func NewRouter(app *logic.Application) *Router { // @version 2.0 // @description API for SCN // @host scn.blackforestbytes.com -// @BasePath /api/ +// @BasePath / func (r *Router) Init(e *gin.Engine) { - e.Any("/ping", ginresp.Wrap(r.commonHandler.Ping)) - e.POST("/db-test", ginresp.Wrap(r.commonHandler.DatabaseTest)) - e.GET("/health", ginresp.Wrap(r.commonHandler.Health)) + // ================ General ================ - e.GET("documentation/swagger", ginext.RedirectTemporary("/documentation/swagger/")) - e.GET("documentation/swagger/", ginresp.Wrap(swagger.Handle)) - e.GET("documentation/swagger/:fn", ginresp.Wrap(swagger.Handle)) + e.Any("/api/common/ping", ginresp.Wrap(r.commonHandler.Ping)) + e.POST("/api/common/db-test", ginresp.Wrap(r.commonHandler.DatabaseTest)) + e.GET("/api/common/health", ginresp.Wrap(r.commonHandler.Health)) + + // ================ Swagger ================ + + e.GET("/documentation/swagger", ginext.RedirectTemporary("/documentation/swagger/")) + e.GET("/documentation/swagger/", ginresp.Wrap(swagger.Handle)) + e.GET("/documentation/swagger/:fn", ginresp.Wrap(swagger.Handle)) + + // ================ Website ================ + + e.GET("/", ginresp.Wrap(r.websiteHandler.Index)) + e.GET("/index.php", ginresp.Wrap(r.websiteHandler.Index)) + e.GET("/index.html", ginresp.Wrap(r.websiteHandler.Index)) + e.GET("/index", ginresp.Wrap(r.websiteHandler.Index)) + + e.GET("/api", ginresp.Wrap(r.websiteHandler.APIDocs)) + e.GET("/api.php", ginresp.Wrap(r.websiteHandler.APIDocs)) + e.GET("/api.html", ginresp.Wrap(r.websiteHandler.APIDocs)) + + e.GET("/api_more", ginresp.Wrap(r.websiteHandler.APIDocsMore)) + e.GET("/api_more.php", ginresp.Wrap(r.websiteHandler.APIDocsMore)) + e.GET("/api_more.html", ginresp.Wrap(r.websiteHandler.APIDocsMore)) + + e.GET("/message_sent", ginresp.Wrap(r.websiteHandler.MessageSent)) + e.GET("/message_sent.php", ginresp.Wrap(r.websiteHandler.MessageSent)) + e.GET("/message_sent.html", ginresp.Wrap(r.websiteHandler.MessageSent)) + + e.GET("/favicon.ico", ginresp.Wrap(r.websiteHandler.FaviconIco)) + e.GET("/favicon.png", ginresp.Wrap(r.websiteHandler.FaviconPNG)) + + e.GET("/js/:fn", ginresp.Wrap(r.websiteHandler.Javascript)) + e.GET("/css/:fn", ginresp.Wrap(r.websiteHandler.CSS)) + + // ================ Compat (v1) ================ + + compat := e.Group("/api/") + { + compat.GET("/register.php", ginresp.Wrap(r.compatHandler.Register)) + compat.GET("/info.php", ginresp.Wrap(r.compatHandler.Info)) + compat.GET("/ack.php", ginresp.Wrap(r.compatHandler.Ack)) + compat.GET("/requery.php", ginresp.Wrap(r.compatHandler.Requery)) + compat.GET("/update.php", ginresp.Wrap(r.compatHandler.Update)) + compat.GET("/expand.php", ginresp.Wrap(r.compatHandler.Expand)) + compat.GET("/upgrade.php", ginresp.Wrap(r.compatHandler.Upgrade)) + } + + // ================ Manage API ================ + + apiv2 := e.Group("/api-v2/") + { + + apiv2.POST("/user/", ginresp.Wrap(r.apiHandler.CreateUser)) + apiv2.GET("/user/:uid", ginresp.Wrap(r.apiHandler.GetUser)) + apiv2.PATCH("/user/:uid", ginresp.Wrap(r.apiHandler.UpdateUser)) + + apiv2.GET("/user/:uid/clients", ginresp.Wrap(r.apiHandler.ListClients)) + apiv2.GET("/user/:uid/clients/:cid", ginresp.Wrap(r.apiHandler.GetClient)) + apiv2.POST("/user/:uid/clients", ginresp.Wrap(r.apiHandler.AddClient)) + apiv2.DELETE("/user/:uid/clients", ginresp.Wrap(r.apiHandler.DeleteClient)) + + apiv2.GET("/user/:uid/channels", ginresp.Wrap(r.apiHandler.ListChannels)) + apiv2.GET("/user/:uid/channels/:cid", ginresp.Wrap(r.apiHandler.GetChannel)) + apiv2.GET("/user/:uid/channels/:cid/messages", ginresp.Wrap(r.apiHandler.GetChannelMessages)) + apiv2.GET("/user/:uid/channels/:cid/subscriptions", ginresp.Wrap(r.apiHandler.ListChannelSubscriptions)) + + apiv2.GET("/user/:uid/subscriptions", ginresp.Wrap(r.apiHandler.ListUserSubscriptions)) + apiv2.GET("/user/:uid/subscriptions/:sid", ginresp.Wrap(r.apiHandler.GetSubscription)) + apiv2.DELETE("/user/:uid/subscriptions/:sid", ginresp.Wrap(r.apiHandler.CancelSubscription)) + apiv2.POST("/user/:uid/subscriptions", ginresp.Wrap(r.apiHandler.CreateSubscription)) + + apiv2.GET("/messages", ginresp.Wrap(r.apiHandler.ListMessages)) + apiv2.GET("/messages/:mid", ginresp.Wrap(r.apiHandler.GetMessage)) + apiv2.DELETE("/messages/:mid", ginresp.Wrap(r.apiHandler.DeleteMessage)) + + apiv2.POST("/messages", ginresp.Wrap(r.messageHandler.SendMessage)) + } + + // ================ Send API ================ + + sendAPI := e.Group("") + { + sendAPI.POST("/", ginresp.Wrap(r.messageHandler.SendMessage)) + sendAPI.POST("/send", ginresp.Wrap(r.messageHandler.SendMessage)) + sendAPI.POST("/send.php") + } + + if r.app.Config.ReturnRawErrors { + e.NoRoute(ginresp.Wrap(r.commonHandler.NoRoute)) + } - e.POST("/send.php", ginresp.Wrap(r.compatHandler.Send)) - e.GET("/register.php", ginresp.Wrap(r.compatHandler.Register)) - e.GET("/info.php", ginresp.Wrap(r.compatHandler.Info)) - e.GET("/ack.php", ginresp.Wrap(r.compatHandler.Ack)) - e.GET("/requery.php", ginresp.Wrap(r.compatHandler.Requery)) - e.GET("/update.php", ginresp.Wrap(r.compatHandler.Update)) - e.GET("/expand.php", ginresp.Wrap(r.compatHandler.Expand)) - e.GET("/upgrade.php", ginresp.Wrap(r.compatHandler.Upgrade)) } diff --git a/server/cmd/scnserver/main.go b/server/cmd/scnserver/main.go index 5c1287b..87d8ae7 100644 --- a/server/cmd/scnserver/main.go +++ b/server/cmd/scnserver/main.go @@ -7,7 +7,6 @@ import ( "blackforestbytes.com/simplecloudnotifier/common/ginext" "blackforestbytes.com/simplecloudnotifier/db" "blackforestbytes.com/simplecloudnotifier/logic" - "context" "fmt" "github.com/rs/zerolog/log" ) @@ -19,13 +18,17 @@ func main() { log.Info().Msg(fmt.Sprintf("Starting with config-namespace <%s>", conf.Namespace)) - sqlite, err := db.NewDatabase(context.Background(), conf) + sqlite, err := db.NewDatabase(conf) if err != nil { panic(err) } app := logic.NewApp(sqlite) + if err := app.Migrate(); err != nil { + panic(err) + } + ginengine := ginext.NewEngine(conf) router := api.NewRouter(app) diff --git a/server/common/ginresp/apiError.go b/server/common/ginresp/apiError.go index 638506b..358240d 100644 --- a/server/common/ginresp/apiError.go +++ b/server/common/ginresp/apiError.go @@ -1,14 +1,9 @@ package ginresp -type sendAPIError struct { +type apiError struct { Success bool `json:"success"` Error int `json:"error"` ErrorHighlight int `json:"errhighlight"` Message string `json:"message"` -} - -type internAPIError struct { - Success bool `json:"success"` - ErrorID int `json:"errid,omitempty"` - Message string `json:"message"` + RawError error `json:"errorObject,omitempty"` } diff --git a/server/common/ginresp/error.go b/server/common/ginresp/error.go deleted file mode 100644 index 9b2d4ff..0000000 --- a/server/common/ginresp/error.go +++ /dev/null @@ -1,6 +0,0 @@ -package ginresp - -type errBody struct { - Success bool `json:"success"` - Message string `json:"message"` -} diff --git a/server/common/ginresp/resp.go b/server/common/ginresp/resp.go index a0c368f..f1284fb 100644 --- a/server/common/ginresp/resp.go +++ b/server/common/ginresp/resp.go @@ -1,13 +1,14 @@ package ginresp import ( + scn "blackforestbytes.com/simplecloudnotifier" "blackforestbytes.com/simplecloudnotifier/api/apierr" "github.com/gin-gonic/gin" "net/http" ) type HTTPResponse interface { - Write(context *gin.Context) + Write(g *gin.Context) } type jsonHTTPResponse struct { @@ -73,13 +74,21 @@ func Text(sc int, data string) HTTPResponse { } func InternalError(e error) HTTPResponse { - return &errHTTPResponse{statusCode: http.StatusInternalServerError, data: errBody{Success: false, Message: e.Error()}} + return &errHTTPResponse{statusCode: http.StatusInternalServerError, data: apiError{Success: false, Error: int(apierr.INTERNAL_EXCEPTION), Message: e.Error()}} } -func InternAPIError(errid int, msg string) HTTPResponse { - return &errHTTPResponse{statusCode: http.StatusInternalServerError, data: internAPIError{Success: false, ErrorID: errid, Message: msg}} +func InternAPIError(errorid apierr.APIError, msg string, e error) HTTPResponse { + if scn.Conf.ReturnRawErrors { + return &errHTTPResponse{statusCode: http.StatusInternalServerError, data: apiError{Success: false, Error: int(errorid), Message: msg, RawError: e}} + } else { + return &errHTTPResponse{statusCode: http.StatusInternalServerError, data: apiError{Success: false, Error: int(errorid), Message: msg}} + } } func SendAPIError(errorid apierr.APIError, highlight int, msg string) HTTPResponse { - return &errHTTPResponse{statusCode: http.StatusInternalServerError, data: sendAPIError{Success: false, Error: int(errorid), ErrorHighlight: highlight, Message: msg}} + return &errHTTPResponse{statusCode: http.StatusInternalServerError, data: apiError{Success: false, Error: int(errorid), ErrorHighlight: highlight, Message: msg}} +} + +func NotImplemented() HTTPResponse { + return &errHTTPResponse{statusCode: http.StatusInternalServerError, data: apiError{Success: false, Error: -1, ErrorHighlight: 0, Message: "Not Implemented"}} } diff --git a/server/common/ginresp/wrapper.go b/server/common/ginresp/wrapper.go index 53838ce..32978f8 100644 --- a/server/common/ginresp/wrapper.go +++ b/server/common/ginresp/wrapper.go @@ -6,15 +6,15 @@ type WHandlerFunc func(*gin.Context) HTTPResponse func Wrap(fn WHandlerFunc) gin.HandlerFunc { - return func(context *gin.Context) { + return func(g *gin.Context) { - wrap := fn(context) + wrap := fn(g) - if context.Writer.Written() { + if g.Writer.Written() { panic("Writing in WrapperFunc is not supported") } - wrap.Write(context) + wrap.Write(g) } diff --git a/server/config.go b/server/config.go index 3e9d686..6a2ce78 100644 --- a/server/config.go +++ b/server/config.go @@ -3,48 +3,59 @@ package server import ( "github.com/rs/zerolog/log" "os" + "time" ) type Config struct { - Namespace string - GinDebug bool - ServerIP string - ServerPort string - DBFile string + Namespace string + GinDebug bool + ServerIP string + ServerPort string + DBFile string + RequestTimeout time.Duration + ReturnRawErrors bool } var Conf Config var configLoc = Config{ - Namespace: "local", - GinDebug: true, - ServerIP: "0.0.0.0", - ServerPort: "8080", - DBFile: ".run-data/db.sqlite3", + Namespace: "local", + GinDebug: true, + ServerIP: "0.0.0.0", + ServerPort: "8080", + DBFile: ".run-data/db.sqlite3", + RequestTimeout: 16 * time.Second, + ReturnRawErrors: true, } var configDev = Config{ - Namespace: "develop", - GinDebug: true, - ServerIP: "0.0.0.0", - ServerPort: "80", - DBFile: "/data/scn.sqlite3", + Namespace: "develop", + GinDebug: true, + ServerIP: "0.0.0.0", + ServerPort: "80", + DBFile: "/data/scn.sqlite3", + RequestTimeout: 16 * time.Second, + ReturnRawErrors: true, } var configStag = Config{ - Namespace: "staging", - GinDebug: true, - ServerIP: "0.0.0.0", - ServerPort: "80", - DBFile: "/data/scn.sqlite3", + Namespace: "staging", + GinDebug: true, + ServerIP: "0.0.0.0", + ServerPort: "80", + DBFile: "/data/scn.sqlite3", + RequestTimeout: 16 * time.Second, + ReturnRawErrors: true, } var configProd = Config{ - Namespace: "production", - GinDebug: false, - ServerIP: "0.0.0.0", - ServerPort: "80", - DBFile: "/data/scn.sqlite3", + Namespace: "production", + GinDebug: false, + ServerIP: "0.0.0.0", + ServerPort: "80", + DBFile: "/data/scn.sqlite3", + RequestTimeout: 16 * time.Second, + ReturnRawErrors: false, } var allConfig = []Config{ diff --git a/server/db/context.go b/server/db/context.go new file mode 100644 index 0000000..7e60b6f --- /dev/null +++ b/server/db/context.go @@ -0,0 +1,15 @@ +package db + +import ( + "database/sql" + "time" +) + +type TxContext interface { + Deadline() (deadline time.Time, ok bool) + Done() <-chan struct{} + Err() error + Value(key any) any + + GetOrCreateTransaction(db *Database) (*sql.Tx, error) +} diff --git a/server/db/database.go b/server/db/database.go index 532ae20..c3ce453 100644 --- a/server/db/database.go +++ b/server/db/database.go @@ -8,43 +8,60 @@ import ( "errors" "fmt" _ "github.com/mattn/go-sqlite3" + "time" ) -//go:embed schema_1.0.sql +//go:embed schema_1.0.ddl var schema_1_0 string -//go:embed schema_2.0.sql +//go:embed schema_2.0.ddl var schema_2_0 string -func NewDatabase(ctx context.Context, conf scn.Config) (*sql.DB, error) { +//go:embed schema_3.0.ddl +var schema_3_0 string + +type Database struct { + db *sql.DB +} + +func NewDatabase(conf scn.Config) (*Database, error) { db, err := sql.Open("sqlite3", conf.DBFile) if err != nil { return nil, err } - schema, err := getSchemaFromDB(ctx, db) + return &Database{db}, nil +} + +func (db *Database) Migrate(ctx context.Context) error { + ctx, cancel := context.WithTimeout(context.Background(), 24*time.Second) + defer cancel() + + schema, err := db.ReadSchema(ctx) if schema == 0 { - _, err = db.ExecContext(ctx, schema_1_0) + _, err = db.db.ExecContext(ctx, schema_3_0) if err != nil { - return nil, err + return err } - return db, nil + return nil } else if schema == 1 { - return nil, errors.New("cannot autom. upgrade schema 1") + return errors.New("cannot autom. upgrade schema 1") } else if schema == 2 { - return db, nil + return errors.New("cannot autom. upgrade schema 2") //TODO + } else if schema == 3 { + return nil // current } else { - return nil, errors.New(fmt.Sprintf("Unknown DB schema: %d", schema)) + return errors.New(fmt.Sprintf("Unknown DB schema: %d", schema)) } } -func getSchemaFromDB(ctx context.Context, db *sql.DB) (int, error) { +func (db *Database) ReadSchema(ctx context.Context) (int, error) { - r1, err := db.QueryContext(ctx, "SELECT name FROM sqlite_master WHERE type='table' AND name='meta'") + r1, err := db.db.QueryContext(ctx, "SELECT name FROM sqlite_master WHERE type='table' AND name='meta'") if err != nil { return 0, err } @@ -53,7 +70,7 @@ func getSchemaFromDB(ctx context.Context, db *sql.DB) (int, error) { return 0, nil } - r2, err := db.QueryContext(ctx, "SELECT value_int FROM meta WHERE key='schema'") + r2, err := db.db.QueryContext(ctx, "SELECT value_int FROM meta WHERE meta_key='schema'") if err != nil { return 0, err } @@ -69,3 +86,11 @@ func getSchemaFromDB(ctx context.Context, db *sql.DB) (int, error) { return schema, nil } + +func (db *Database) Ping() error { + return db.db.Ping() +} + +func (db *Database) BeginTx(ctx context.Context) (*sql.Tx, error) { + return db.db.BeginTx(ctx, nil) +} diff --git a/server/db/methods.go b/server/db/methods.go new file mode 100644 index 0000000..baf1a82 --- /dev/null +++ b/server/db/methods.go @@ -0,0 +1,112 @@ +package db + +import ( + "blackforestbytes.com/simplecloudnotifier/api/models" + "gogs.mikescher.com/BlackForestBytes/goext/langext" + "time" +) + +func (db *Database) CreateUser(ctx TxContext, readKey string, sendKey string, adminKey string, protoken *string, username *string) (models.User, error) { + tx, err := ctx.GetOrCreateTransaction(db) + if err != nil { + return models.User{}, err + } + + now := time.Now().UTC() + + res, err := tx.ExecContext(ctx, "INSERT INTO users (username, read_key, send_key, admin_key, is_pro, pro_token, timestamp_created) VALUES (?, ?, ?, ?, ?, ?, ?)", + username, + readKey, + sendKey, + adminKey, + bool2DB(protoken != nil), + protoken, + time2DB(now)) + if err != nil { + return models.User{}, err + } + + liid, err := res.LastInsertId() + if err != nil { + return models.User{}, err + } + + return models.User{ + UserID: liid, + Username: username, + ReadKey: readKey, + SendKey: sendKey, + AdminKey: adminKey, + TimestampCreated: now, + TimestampLastRead: nil, + TimestampLastSent: nil, + MessagesSent: 0, + QuotaToday: 0, + QuotaDay: nil, + IsPro: protoken != nil, + ProToken: protoken, + }, nil +} + +func (db *Database) CreateClient(ctx TxContext, userid int64, ctype models.ClientType, fcmToken string, agentModel string, agentVersion string) (models.Client, error) { + tx, err := ctx.GetOrCreateTransaction(db) + if err != nil { + return models.Client{}, err + } + + now := time.Now().UTC() + + res, err := tx.ExecContext(ctx, "INSERT INTO clients (user_id, type, fcm_token, timestamp_created, agent_model, agent_version) VALUES (?, ?, ?, ?, ?, ?)", + userid, + string(ctype), + fcmToken, + time2DB(now), + agentModel, + agentVersion) + if err != nil { + return models.Client{}, err + } + + liid, err := res.LastInsertId() + if err != nil { + return models.Client{}, err + } + + return models.Client{ + ClientID: liid, + UserID: userid, + Type: ctype, + FCMToken: langext.Ptr(fcmToken), + TimestampCreated: now, + AgentModel: agentModel, + AgentVersion: agentVersion, + }, nil +} + +func (db *Database) ClearFCMTokens(ctx TxContext, fcmtoken string) error { + tx, err := ctx.GetOrCreateTransaction(db) + if err != nil { + return err + } + + _, err = tx.ExecContext(ctx, "DELETE FROM clients WHERE fcm_token = ?", fcmtoken) + if err != nil { + return err + } + + return nil +} + +func (db *Database) ClearProTokens(ctx TxContext, protoken string) error { + tx, err := ctx.GetOrCreateTransaction(db) + if err != nil { + return err + } + + _, err = tx.ExecContext(ctx, "UPDATE users SET is_pro=0, pro_token=NULL WHERE pro_token = ?", protoken) + if err != nil { + return err + } + + return nil +} diff --git a/server/db/schema_1.0.sql b/server/db/schema_1.0.ddl similarity index 100% rename from server/db/schema_1.0.sql rename to server/db/schema_1.0.ddl diff --git a/server/db/schema_2.0.sql b/server/db/schema_2.0.ddl similarity index 100% rename from server/db/schema_2.0.sql rename to server/db/schema_2.0.ddl diff --git a/server/db/schema_3.0.sql b/server/db/schema_3.0.ddl similarity index 69% rename from server/db/schema_3.0.sql rename to server/db/schema_3.0.ddl index 18de924..01b7d60 100644 --- a/server/db/schema_3.0.sql +++ b/server/db/schema_3.0.ddl @@ -8,9 +8,9 @@ CREATE TABLE users send_key TEXT NOT NULL, admin_key TEXT NOT NULL, - timestamp_created TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, - timestamp_lastread TEXT NULL DEFAULT NULL, - timestamp_lastsent TEXT NULL DEFAULT NULL, + timestamp_created INTEGER NOT NULL, + timestamp_lastread INTEGER NULL DEFAULT NULL, + timestamp_lastsent INTEGER NULL DEFAULT NULL, messages_sent INTEGER NOT NULL DEFAULT '0', @@ -18,24 +18,23 @@ CREATE TABLE users quota_day TEXT NULL DEFAULT NULL, is_pro INTEGER CHECK(is_pro IN (0, 1)) NOT NULL DEFAULT 0, - pro_token TEXT NULL DEFAULT NULL, - - PRIMARY KEY (user_id) + pro_token TEXT NULL DEFAULT NULL ); -CREATE UNIQUE INDEX "idx_users_protoken" ON users (pro_token); +CREATE UNIQUE INDEX "idx_users_protoken" ON users (pro_token) WHERE pro_token IS NOT NULL; CREATE TABLE clients ( - client_id INTEGER PRIMARY KEY AUTOINCREMENT, + client_id INTEGER PRIMARY KEY AUTOINCREMENT, - user_id INTEGER NOT NULL, + user_id INTEGER NOT NULL, + type TEXT CHECK(type IN ('ANDROID', 'IOS')) NOT NULL, + fcm_token TEXT NULL, - type TEXT NOT NULL, + timestamp_created INTEGER NOT NULL, - fcm_token TEXT NULL, - - PRIMARY KEY (client_id) + agent_model TEXT NOT NULL, + agent_version TEXT NOT NULL ); CREATE INDEX "idx_clients_userid" ON clients (user_id); CREATE UNIQUE INDEX "idx_clients_fcmtoken" ON clients (fcm_token); @@ -54,11 +53,9 @@ CREATE TABLE channels messages_sent INTEGER NOT NULL DEFAULT '0', - timestamp_created TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, - timestamp_lastread TEXT NULL DEFAULT NULL, - timestamp_lastsent TEXT NULL DEFAULT NULL, - - PRIMARY KEY (channel_id) + timestamp_created INTEGER NOT NULL, + timestamp_lastread INTEGER NULL DEFAULT NULL, + timestamp_lastsent INTEGER NULL DEFAULT NULL ); CREATE UNIQUE INDEX "idx_channels_identity" ON channels (owner_user_id, name); @@ -68,9 +65,7 @@ CREATE TABLE subscriptions subscriber_user_id INTEGER NOT NULL, channel_owner_user_id INTEGER NOT NULL, - channel_name TEXT NOT NULL, - - PRIMARY KEY (subscription_id) + channel_name TEXT NOT NULL ); CREATE UNIQUE INDEX "idx_subscriptions_ref" ON subscriptions (subscriber_user_id, channel_owner_user_id, channel_name); @@ -83,15 +78,13 @@ CREATE TABLE messages channel_id INTEGER NOT NULL, - timestamp_real TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, - timestamp_client TEXT NULL, + timestamp_real INTEGER NOT NULL, + timestamp_client INTEGER NULL, title TEXT NOT NULL, content TEXT NULL, priority INTEGER CHECK(priority IN (0, 1, 2)) NOT NULL, - usr_message_id TEXT NULL, - - PRIMARY KEY (scn_message_id) + usr_message_id TEXT NULL ); CREATE INDEX "idx_messages_channel" ON messages (sender_user_id, channel_name); CREATE INDEX "idx_messages_idempotency" ON messages (sender_user_id, usr_message_id); @@ -105,16 +98,15 @@ CREATE TABLE deliveries receiver_user_id INTEGER NOT NULL, receiver_client_id INTEGER NOT NULL, - timestamp_created TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, - timestamp_finalized TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP, + timestamp_created INTEGER NOT NULL, + timestamp_finalized INTEGER NOT NULL, status TEXT CHECK(status IN ('RETRY','SUCCESS','FAILED')) NOT NULL, retry_count INTEGER NOT NULL DEFAULT 0, + next_delivery INTEGER NULL DEFAULT NULL, - fcm_message_id TEXT NULL, - - PRIMARY KEY (delivery_id) + fcm_message_id TEXT NULL ); CREATE INDEX "idx_deliveries_receiver" ON deliveries (scn_message_id, receiver_client_id); diff --git a/server/db/schema_sqlite.ddl b/server/db/schema_sqlite.ddl new file mode 100644 index 0000000..5194e91 --- /dev/null +++ b/server/db/schema_sqlite.ddl @@ -0,0 +1,7 @@ +CREATE TABLE sqlite_master ( + type text, + name text, + tbl_name text, + rootpage integer, + sql text +); \ No newline at end of file diff --git a/server/db/utils.go b/server/db/utils.go new file mode 100644 index 0000000..3258f51 --- /dev/null +++ b/server/db/utils.go @@ -0,0 +1,15 @@ +package db + +import "time" + +func bool2DB(b bool) int { + if b { + return 1 + } else { + return 0 + } +} + +func time2DB(t time.Time) int64 { + return t.UnixMilli() +} diff --git a/server/logic/application.go b/server/logic/application.go index 91adbe5..d99f780 100644 --- a/server/logic/application.go +++ b/server/logic/application.go @@ -2,10 +2,8 @@ package logic import ( scn "blackforestbytes.com/simplecloudnotifier" - "blackforestbytes.com/simplecloudnotifier/common/ginresp" + "blackforestbytes.com/simplecloudnotifier/db" "context" - "database/sql" - "fmt" "github.com/gin-gonic/gin" "github.com/rs/zerolog/log" "math/rand" @@ -20,10 +18,10 @@ import ( type Application struct { Config scn.Config Gin *gin.Engine - Database *sql.DB + Database *db.Database } -func NewApp(db *sql.DB) *Application { +func NewApp(db *db.Database) *Application { return &Application{Database: db} } @@ -74,30 +72,6 @@ func (app *Application) GenerateRandomAuthKey() string { return k } -func (app *Application) RunTransaction(ctx context.Context, opt *sql.TxOptions, fn func(tx *sql.Tx) (ginresp.HTTPResponse, bool)) ginresp.HTTPResponse { - - tx, err := app.Database.BeginTx(ctx, opt) - if err != nil { - return ginresp.InternAPIError(0, fmt.Sprintf("Failed to create transaction: %v", err)) - } - - res, commit := fn(tx) - - if commit { - err = tx.Commit() - if err != nil { - return ginresp.InternAPIError(0, fmt.Sprintf("Failed to commit transaction: %v", err)) - } - } else { - err = tx.Rollback() - if err != nil { - return ginresp.InternAPIError(0, fmt.Sprintf("Failed to rollback transaction: %v", err)) - } - } - - return res -} - func (app *Application) QuotaMax(ispro bool) int { if ispro { return 1000 @@ -109,3 +83,16 @@ func (app *Application) QuotaMax(ispro bool) int { func (app *Application) VerifyProToken(token string) (bool, error) { return false, nil //TODO implement pro verification } + +func (app *Application) Migrate() error { + ctx, cancel := context.WithTimeout(context.Background(), 24*time.Second) + defer cancel() + + return app.Database.Migrate(ctx) +} + +func (app *Application) StartRequest(g *gin.Context) *AppContext { + ctx, cancel := context.WithTimeout(context.Background(), app.Config.RequestTimeout) + + return &AppContext{inner: ctx, cancelFunc: cancel} +} diff --git a/server/logic/context.go b/server/logic/context.go new file mode 100644 index 0000000..3adfea2 --- /dev/null +++ b/server/logic/context.go @@ -0,0 +1,75 @@ +package logic + +import ( + "blackforestbytes.com/simplecloudnotifier/api/apierr" + "blackforestbytes.com/simplecloudnotifier/common/ginresp" + "blackforestbytes.com/simplecloudnotifier/db" + "context" + "database/sql" + "errors" + "time" +) + +type AppContext struct { + inner context.Context + cancelFunc context.CancelFunc + cancelled bool + transaction *sql.Tx +} + +func (ac *AppContext) Deadline() (deadline time.Time, ok bool) { + return ac.inner.Deadline() +} + +func (ac *AppContext) Done() <-chan struct{} { + return ac.inner.Done() +} + +func (ac *AppContext) Err() error { + return ac.inner.Err() +} + +func (ac *AppContext) Value(key any) any { + return ac.inner.Value(key) +} + +func (ac *AppContext) Cancel() { + ac.cancelled = true + if ac.transaction != nil { + err := ac.transaction.Rollback() + if err != nil { + panic("failed to rollback transaction: " + err.Error()) + } + ac.transaction = nil + } + ac.cancelFunc() +} + +func (ac *AppContext) FinishSuccess(res ginresp.HTTPResponse) ginresp.HTTPResponse { + if ac.cancelled { + panic("Cannot finish a cancelled request") + } + if ac.transaction != nil { + err := ac.transaction.Commit() + if err != nil { + return ginresp.InternAPIError(apierr.COMMIT_FAILED, "Failed to comit changes to DB", err) + } + ac.transaction = nil + } + return res +} + +func (ac *AppContext) GetOrCreateTransaction(db *db.Database) (*sql.Tx, error) { + if ac.cancelled { + return nil, errors.New("context cancelled") + } + if ac.transaction != nil { + return ac.transaction, nil + } + tx, err := db.BeginTx(ac) + if err != nil { + return nil, err + } + ac.transaction = tx + return tx, nil +} diff --git a/server/swagger/swagger.json b/server/swagger/swagger.json index 75d4068..df83e3a 100644 --- a/server/swagger/swagger.json +++ b/server/swagger/swagger.json @@ -7,9 +7,45 @@ "version": "2.0" }, "host": "scn.blackforestbytes.com", - "basePath": "/api/", + "basePath": "/", "paths": { - "/ack.php": { + "/api-v2/user/": { + "post": { + "summary": "Create a new user", + "operationId": "api-user-create", + "parameters": [ + { + "description": " ", + "name": "post_body", + "in": "body", + "schema": { + "$ref": "#/definitions/handler.CreateUser.body" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.UserJSON" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/ginresp.apiError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ginresp.apiError" + } + } + } + } + }, + "/api/ack.php": { "get": { "summary": "Acknowledge that a message was received", "operationId": "compat-ack", @@ -46,31 +82,13 @@ "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/ginresp.internAPIError" + "$ref": "#/definitions/ginresp.apiError" } } } } }, - "/db-test": { - "get": { - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/handler.DatabaseTest.response" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginresp.errBody" - } - } - } - } - }, - "/expand.php": { + "/api/expand.php": { "get": { "summary": "Get a whole (potentially truncated) message", "operationId": "compat-expand", @@ -84,31 +102,13 @@ "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/ginresp.internAPIError" + "$ref": "#/definitions/ginresp.apiError" } } } } }, - "/health": { - "get": { - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/handler.Health.response" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginresp.errBody" - } - } - } - } - }, - "/info.php": { + "/api/info.php": { "get": { "summary": "Get information about the current user", "operationId": "compat-info", @@ -138,95 +138,13 @@ "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/ginresp.internAPIError" + "$ref": "#/definitions/ginresp.apiError" } } } } }, - "/ping": { - "get": { - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/handler.pingResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginresp.errBody" - } - } - } - }, - "put": { - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/handler.pingResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginresp.errBody" - } - } - } - }, - "post": { - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/handler.pingResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginresp.errBody" - } - } - } - }, - "delete": { - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/handler.pingResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginresp.errBody" - } - } - } - }, - "patch": { - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/handler.pingResponse" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginresp.errBody" - } - } - } - } - }, - "/register.php": { + "/api/register.php": { "get": { "summary": "Register a new account", "operationId": "compat-register", @@ -267,13 +185,13 @@ "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/ginresp.internAPIError" + "$ref": "#/definitions/ginresp.apiError" } } } } }, - "/requery.php": { + "/api/requery.php": { "get": { "summary": "Return all not-acknowledged messages", "operationId": "compat-requery", @@ -303,85 +221,13 @@ "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/ginresp.internAPIError" + "$ref": "#/definitions/ginresp.apiError" } } } } }, - "/send.php": { - "post": { - "description": "(all arguments can either be supplied in the query or in the json body)", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "summary": "Send a message", - "operationId": "compat-send", - "parameters": [ - { - "type": "string", - "name": "content", - "in": "query" - }, - { - "type": "string", - "name": "messageID", - "in": "query" - }, - { - "type": "string", - "name": "priority", - "in": "query" - }, - { - "type": "string", - "name": "timestamp", - "in": "query" - }, - { - "type": "string", - "name": "title", - "in": "query" - }, - { - "type": "string", - "name": "userID", - "in": "query" - }, - { - "type": "string", - "name": "userKey", - "in": "query" - }, - { - "description": " ", - "name": "post_body", - "in": "body", - "schema": { - "$ref": "#/definitions/handler.Send.body" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/handler.Send.response" - } - }, - "500": { - "description": "Internal Server Error", - "schema": { - "$ref": "#/definitions/ginresp.sendAPIError" - } - } - } - } - }, - "/update.php": { + "/api/update.php": { "get": { "summary": "Set the fcm-token (android)", "operationId": "compat-update", @@ -418,13 +264,13 @@ "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/ginresp.internAPIError" + "$ref": "#/definitions/ginresp.apiError" } } } } }, - "/upgrade.php": { + "/api/upgrade.php": { "get": { "summary": "Upgrade a free account to a paid account", "operationId": "compat-upgrade", @@ -472,7 +318,125 @@ "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/ginresp.internAPIError" + "$ref": "#/definitions/ginresp.apiError" + } + } + } + } + }, + "/db-test": { + "get": { + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.DatabaseTest.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ginresp.apiError" + } + } + } + } + }, + "/health": { + "get": { + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.Health.response" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ginresp.apiError" + } + } + } + } + }, + "/ping": { + "get": { + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.pingResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ginresp.apiError" + } + } + } + }, + "put": { + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.pingResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ginresp.apiError" + } + } + } + }, + "post": { + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.pingResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ginresp.apiError" + } + } + } + }, + "delete": { + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.pingResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ginresp.apiError" + } + } + } + }, + "patch": { + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.pingResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/ginresp.apiError" } } } @@ -480,32 +444,7 @@ } }, "definitions": { - "ginresp.errBody": { - "type": "object", - "properties": { - "message": { - "type": "string" - }, - "success": { - "type": "boolean" - } - } - }, - "ginresp.internAPIError": { - "type": "object", - "properties": { - "errid": { - "type": "integer" - }, - "message": { - "type": "string" - }, - "success": { - "type": "boolean" - } - } - }, - "ginresp.sendAPIError": { + "ginresp.apiError": { "type": "object", "properties": { "errhighlight": { @@ -514,6 +453,7 @@ "error": { "type": "integer" }, + "errorObject": {}, "message": { "type": "string" }, @@ -539,6 +479,29 @@ } } }, + "handler.CreateUser.body": { + "type": "object", + "properties": { + "agentModel": { + "type": "string" + }, + "agentVersion": { + "type": "string" + }, + "clientType": { + "type": "string" + }, + "fcmtoken": { + "type": "string" + }, + "proToken": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, "handler.DatabaseTest.response": { "type": "object", "properties": { @@ -656,43 +619,6 @@ } } }, - "handler.Send.body": { - "type": "object", - "properties": { - "content": { - "type": "string" - }, - "msg_id": { - "type": "string" - }, - "priority": { - "type": "string" - }, - "timestamp": { - "type": "string" - }, - "title": { - "type": "string" - }, - "user_id": { - "type": "string" - }, - "user_key": { - "type": "string" - } - } - }, - "handler.Send.response": { - "type": "object", - "properties": { - "message": { - "type": "string" - }, - "success": { - "type": "string" - } - } - }, "handler.Update.response": { "type": "object", "properties": { @@ -818,6 +744,47 @@ "type": "string" } } + }, + "models.UserJSON": { + "type": "object", + "properties": { + "admin_key": { + "type": "string" + }, + "is_pro": { + "type": "boolean" + }, + "messages_sent": { + "type": "integer" + }, + "quota_day": { + "type": "string" + }, + "quota_today": { + "type": "integer" + }, + "read_key": { + "type": "string" + }, + "send_key": { + "type": "string" + }, + "timestamp_created": { + "type": "string" + }, + "timestamp_last_read": { + "type": "string" + }, + "timestamp_last_sent": { + "type": "string" + }, + "user_id": { + "type": "integer" + }, + "username": { + "type": "string" + } + } } } } \ No newline at end of file diff --git a/server/swagger/swagger.yaml b/server/swagger/swagger.yaml index 7f9a6ce..bd20c7b 100644 --- a/server/swagger/swagger.yaml +++ b/server/swagger/swagger.yaml @@ -1,27 +1,12 @@ -basePath: /api/ +basePath: / definitions: - ginresp.errBody: - properties: - message: - type: string - success: - type: boolean - type: object - ginresp.internAPIError: - properties: - errid: - type: integer - message: - type: string - success: - type: boolean - type: object - ginresp.sendAPIError: + ginresp.apiError: properties: errhighlight: type: integer error: type: integer + errorObject: {} message: type: string success: @@ -38,6 +23,21 @@ definitions: success: type: string type: object + handler.CreateUser.body: + properties: + agentModel: + type: string + agentVersion: + type: string + clientType: + type: string + fcmtoken: + type: string + proToken: + type: string + username: + type: string + type: object handler.DatabaseTest.response: properties: libVersion: @@ -114,30 +114,6 @@ definitions: success: type: string type: object - handler.Send.body: - properties: - content: - type: string - msg_id: - type: string - priority: - type: string - timestamp: - type: string - title: - type: string - user_id: - type: string - user_key: - type: string - type: object - handler.Send.response: - properties: - message: - type: string - success: - type: string - type: object handler.Update.response: properties: is_pro: @@ -220,6 +196,33 @@ definitions: usr_msg_id: type: string type: object + models.UserJSON: + properties: + admin_key: + type: string + is_pro: + type: boolean + messages_sent: + type: integer + quota_day: + type: string + quota_today: + type: integer + read_key: + type: string + send_key: + type: string + timestamp_created: + type: string + timestamp_last_read: + type: string + timestamp_last_sent: + type: string + user_id: + type: integer + username: + type: string + type: object host: scn.blackforestbytes.com info: contact: {} @@ -227,7 +230,30 @@ info: title: SimpleCloudNotifier API version: "2.0" paths: - /ack.php: + /api-v2/user/: + post: + operationId: api-user-create + parameters: + - description: ' ' + in: body + name: post_body + schema: + $ref: '#/definitions/handler.CreateUser.body' + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.UserJSON' + "400": + description: Bad Request + schema: + $ref: '#/definitions/ginresp.apiError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/ginresp.apiError' + summary: Create a new user + /api/ack.php: get: operationId: compat-ack parameters: @@ -254,20 +280,9 @@ paths: "500": description: Internal Server Error schema: - $ref: '#/definitions/ginresp.internAPIError' + $ref: '#/definitions/ginresp.apiError' summary: Acknowledge that a message was received - /db-test: - get: - responses: - "200": - description: OK - schema: - $ref: '#/definitions/handler.DatabaseTest.response' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/ginresp.errBody' - /expand.php: + /api/expand.php: get: operationId: compat-expand responses: @@ -278,20 +293,9 @@ paths: "500": description: Internal Server Error schema: - $ref: '#/definitions/ginresp.internAPIError' + $ref: '#/definitions/ginresp.apiError' summary: Get a whole (potentially truncated) message - /health: - get: - responses: - "200": - description: OK - schema: - $ref: '#/definitions/handler.Health.response' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/ginresp.errBody' - /info.php: + /api/info.php: get: operationId: compat-info parameters: @@ -313,60 +317,9 @@ paths: "500": description: Internal Server Error schema: - $ref: '#/definitions/ginresp.internAPIError' + $ref: '#/definitions/ginresp.apiError' summary: Get information about the current user - /ping: - delete: - responses: - "200": - description: OK - schema: - $ref: '#/definitions/handler.pingResponse' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/ginresp.errBody' - get: - responses: - "200": - description: OK - schema: - $ref: '#/definitions/handler.pingResponse' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/ginresp.errBody' - patch: - responses: - "200": - description: OK - schema: - $ref: '#/definitions/handler.pingResponse' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/ginresp.errBody' - post: - responses: - "200": - description: OK - schema: - $ref: '#/definitions/handler.pingResponse' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/ginresp.errBody' - put: - responses: - "200": - description: OK - schema: - $ref: '#/definitions/handler.pingResponse' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/ginresp.errBody' - /register.php: + /api/register.php: get: operationId: compat-register parameters: @@ -396,9 +349,9 @@ paths: "500": description: Internal Server Error schema: - $ref: '#/definitions/ginresp.internAPIError' + $ref: '#/definitions/ginresp.apiError' summary: Register a new account - /requery.php: + /api/requery.php: get: operationId: compat-requery parameters: @@ -420,55 +373,9 @@ paths: "500": description: Internal Server Error schema: - $ref: '#/definitions/ginresp.internAPIError' + $ref: '#/definitions/ginresp.apiError' summary: Return all not-acknowledged messages - /send.php: - post: - consumes: - - application/json - description: (all arguments can either be supplied in the query or in the json - body) - operationId: compat-send - parameters: - - in: query - name: content - type: string - - in: query - name: messageID - type: string - - in: query - name: priority - type: string - - in: query - name: timestamp - type: string - - in: query - name: title - type: string - - in: query - name: userID - type: string - - in: query - name: userKey - type: string - - description: ' ' - in: body - name: post_body - schema: - $ref: '#/definitions/handler.Send.body' - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/handler.Send.response' - "500": - description: Internal Server Error - schema: - $ref: '#/definitions/ginresp.sendAPIError' - summary: Send a message - /update.php: + /api/update.php: get: operationId: compat-update parameters: @@ -495,9 +402,9 @@ paths: "500": description: Internal Server Error schema: - $ref: '#/definitions/ginresp.internAPIError' + $ref: '#/definitions/ginresp.apiError' summary: Set the fcm-token (android) - /upgrade.php: + /api/upgrade.php: get: operationId: compat-upgrade parameters: @@ -532,6 +439,79 @@ paths: "500": description: Internal Server Error schema: - $ref: '#/definitions/ginresp.internAPIError' + $ref: '#/definitions/ginresp.apiError' summary: Upgrade a free account to a paid account + /db-test: + get: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.DatabaseTest.response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/ginresp.apiError' + /health: + get: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.Health.response' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/ginresp.apiError' + /ping: + delete: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.pingResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/ginresp.apiError' + get: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.pingResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/ginresp.apiError' + patch: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.pingResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/ginresp.apiError' + post: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.pingResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/ginresp.apiError' + put: + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.pingResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/ginresp.apiError' swagger: "2.0" diff --git a/server/website/api.html b/server/website/api.html new file mode 100644 index 0000000..8e3f4b8 --- /dev/null +++ b/server/website/api.html @@ -0,0 +1,47 @@ + + + + + + Simple Cloud Notifications - API + + + + + + + + + + + +
+ + Send + +

Simple Cloud Notifier

+ +

Get your user-id and user-key from the app and send notifications to your phone by performing a POST request against https://simplecloudnotifier.blackforestbytes.com/

+
curl                                          \
+    --data "user_id={userid}"                 \
+    --data "user_key={userkey}"               \
+    --data "title={message_title}"            \
+    --data "content={message_body}"           \
+    --data "priority={0|1|2}"                 \
+    --data "msg_id={unique_message_id}"       \
+    https://scn.blackforestbytes.com/
+

The content, priority and msg_id parameters are optional, you can also send message with only a title and the default priority

+
curl                                          \
+    --data "user_id={userid}"                 \
+    --data "user_key={userkey}"               \
+    --data "title={message_title}"            \
+    https://scn.blackforestbytes.com/
+ + More + +
+ + \ No newline at end of file diff --git a/server/website/api_more.html b/server/website/api_more.html new file mode 100644 index 0000000..f86c54a --- /dev/null +++ b/server/website/api_more.html @@ -0,0 +1,299 @@ + + + + + + Simple Cloud Notifications - API + + + + + + + + + + + +
+ + Send + +

Simple Cloud Notifier

+ +

Introduction

+
+

+ With this API you can send push notifications to your phone. +

+

+ To recieve them you will need to install the SimpleCloudNotifier app from the play store. + When you open the app you can click on the account tab to see you unique user_id and user_key. + These two values are used to identify and authenticate your device so that send messages can be routed to your phone. +

+

+ You can at any time generate a new user_key in the app and invalidate the old one. +

+

+ There is also a web interface for this API to manually send notifications to your phone or to test your setup. +

+
+ +

Quota

+
+

+ By default you can send up to 100 messages per day per device. + If you need more you can upgrade your account in the app to get 1000 messages per day, this has the additional benefit of removing ads and supporting the development of the app (and making sure I can pay the server costs). +

+
+ +

API Requests

+
+

+ To send a new notification you send a POST request to the URL https://scn.blackforestbytes.com/. + All Parameters can either directly be submitted as URL parameters or they can be put into the POST body. +

+

+ You need to supply a valid user_id - user_key pair and a title for your message, all other parameter are optional. +

+
+ +

API Response

+
+

+ If the operation was successful the API will respond with an HTTP statuscode 200 and an JSON payload indicating the send message and your remaining quota +

+
{
+    "success":true,
+    "message":"Message sent",
+    "response":
+    {
+        "multicast_id":8000000000000000006,
+        "success":1,
+        "failure":0,
+        "canonical_ids":0,
+        "results": [{"message_id":"0:10000000000000000000000000000000d"}]
+    },
+    "quota":17,
+    "quota_max":100
+}
+

+ If the operation is not successful the API will respond with an 4xx HTTP statuscode. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StatuscodeExplanation
200 (OK)Message sent
400 (Bad Request)The request is invalid (missing parameters or wrong values)
401 (Unauthorized)The user_id was not found or the user_key is wrong
403 (Forbidden)The user has exceeded its daily quota - wait 24 hours or upgrade your account
412 (Precondition Failed)There is no device connected with this account - open the app and press the refresh button in the account tab
500 (Internal Server Error)There was an internal error while sending your data - try again later
+

+ There is also always a JSON payload with additional information. + The success field is always there and in the error state you the message field to get a descritpion of the problem. +

+
{
+    "success":false,
+    "error":2101,
+    "errhighlight":-1,
+    "message":"Daily quota reached (100)"
+}
+
+ +

Message Content

+
+

+ Every message must have a title set. + But you also (optionally) add more content, while the title has a max length of 120 characters, the conntent can be up to 10.000 characters. + You can see the whole message with title and content in the app or when clicking on the notification. +

+

+ If needed the content can be supplied in the content parameter. +

+
curl                                          \
+    --data "user_id={userid}"                 \
+    --data "user_key={userkey}"               \
+    --data "title={message_title}"            \
+    --data "content={message_content}"        \
+    https://scn.blackforestbytes.com/
+
+ +

Message Priority

+
+

+ Currently you can send a message with three different priorities: 0 (low), 1 (normal) and 2 (high). + In the app you can then configure a different behaviour for different priorities, e.g. only playing a sound if the notification is high priority. +

+

+ Priorites are either 0, 1 or 2 and are supplied in the priority parameter. + If no priority is supplied the message will get the default priority of 1. +

+
curl                                          \
+    --data "user_id={userid}"                 \
+    --data "user_key={userkey}"               \
+    --data "title={message_title}"            \
+    --data "priority={0|1|2}"                 \
+    https://scn.blackforestbytes.com/s
+
+ +

Message Uniqueness

+
+

+ Sometimes your script can run in an environment with an unstable connection and you want to implement an automatic re-try mechanism to send a message again if the last try failed due to bad connectivity. +

+

+ To ensure that a message is only send once you can generate a unique id for your message (I would recommend a simple uuidgen). + If you send a message with an UUID that was already used in the near past the API still returns OK, but no new message is sent. +

+

+ The message_id is optional - but if you want to use it you need to supply it via the msg_id parameter. +

+
curl                                          \
+    --data "user_id={userid}"                 \
+    --data "user_key={userkey}"               \
+    --data "title={message_title}"            \
+    --data "msg_id={message_id}"              \
+    https://scn.blackforestbytes.com/
+

+ Be aware that the server only saves send messages for a short amount of time. Because of that you can only use this to prevent duplicates in a short time-frame, older messages with the same ID are probably already deleted and the message will be send again. +

+
+ +

Custom Time

+
+

+ You can modify the displayed timestamp of a message by sending the timestamp parameter. The format must be a valid UNIX timestamp (elapsed seconds since 1970-01-01 GMT) +

+

+ The custom timestamp must be within 48 hours of the current time. This parameter is only intended to supply a more precise value in case the message sending was delayed. +

+
curl                                          \
+    --data "user_id={userid}"                 \
+    --data "user_key={userkey}"               \
+    --data "title={message_title}"            \
+    --data "timestamp={unix_timestamp}"       \
+    https://scn.blackforestbytes.com/
+
+ +

Bash script example

+
+

+ Depending on your use case it can be useful to create a bash script that handles things like resending messages if you have connection problems or waiting if there is no quota left.
+ Here is an example how such a scrippt could look like, you can put it into /usr/local/sbin and call it with scn_send "title" "content" +

+
#!/usr/bin/env bash
+
+#
+# Call with   `scn_send title`
+#        or   `scn_send title content`
+#        or   `scn_send title content priority`
+#
+#
+
+if [ "$#" -lt 1 ]; then
+    echo "no title supplied via parameter"
+    exit 1
+fi
+
+################################################################################
+# INSERT YOUR DATA HERE                                                        #
+################################################################################
+user_id=999
+user_key="????????????????????????????????????????????????????????????????"
+################################################################################
+
+title=$1
+content=""
+sendtime=$(date +%s)
+
+if [ "$#" -gt 1 ]; then
+    content=$2
+fi
+
+priority=1
+
+if [ "$#" -gt 2 ]; then
+    priority=$3
+fi
+
+usr_msg_id=$(uuidgen)
+
+while true ; do
+
+    curlresp=$(curl -s -o /dev/null -w "%{http_code}" \
+                    -d "user_id=$user_id" -d "user_key=$user_key" -d "title=$title" -d "timestamp=$sendtime" \
+                    -d "content=$content" -d "priority=$priority" -d "msg_id=$usr_msg_id" \
+                    https://scn.blackforestbytes.com/)
+
+    if [ "$curlresp" == 200 ] ; then
+        echo "Successfully send"
+        exit 0
+    fi
+
+    if [ "$curlresp" == 400 ] ; then
+        echo "Bad request - something went wrong"
+        exit 1
+    fi
+
+    if [ "$curlresp" == 401 ] ; then
+        echo "Unauthorized - wrong userid/userkey"
+        exit 1
+    fi
+
+    if [ "$curlresp" == 403 ] ; then
+        echo "Quota exceeded - wait one hour before re-try"
+        sleep 3600
+    fi
+
+    if [ "$curlresp" == 412 ] ; then
+        echo "Precondition Failed - No device linked"
+        exit 1
+    fi
+
+    if [ "$curlresp" == 500 ] ; then
+        echo "Internal server error - waiting for better times"
+        sleep 60
+    fi
+
+    # if none of the above matched we probably hav no network ...
+    echo "Send failed (response code $curlresp) ... try again in 5s"
+    sleep 5
+done
+
+

+ Be aware that the server only saves send messages for a short amount of time. Because of that you can only use this to prevent duplicates in a short time-frame, older messages with the same ID are probably already deleted and the message will be send again. +

+
+
+ + + \ No newline at end of file diff --git a/server/website/css/mini-dark.min.css b/server/website/css/mini-dark.min.css new file mode 100644 index 0000000..3877560 --- /dev/null +++ b/server/website/css/mini-dark.min.css @@ -0,0 +1 @@ +:root{--fore-color:#fdfdfd;--secondary-fore-color:#f0f0f0;--back-color:#111;--secondary-back-color:#222;--blockquote-color:#f57c00;--pre-color:#1565c0;--border-color:#ddd;--secondary-border-color:#aaa;--heading-ratio:1.19;--universal-margin:.5rem;--universal-padding:.5rem;--universal-border-radius:.125rem;--a-link-color:#0277bd;--a-visited-color:#01579b}html{font-size:16px}a,b,del,em,i,ins,q,span,strong,u{font-size:1em}html,*{font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", Helvetica, sans-serif;line-height:1.5;-webkit-text-size-adjust:100%}*{font-size:1rem}body{margin:0;color:var(--fore-color);background:var(--back-color)}details{display:block}summary{display:list-item}abbr[title]{border-bottom:none;text-decoration:underline dotted}input{overflow:visible}img{max-width:100%;height:auto}h1,h2,h3,h4,h5,h6{line-height:1.2;margin:calc(1.5 * var(--universal-margin)) var(--universal-margin);font-weight:500}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:var(--secondary-fore-color);display:block;margin-top:-.25rem}h1{font-size:calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio))}h2{font-size:calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio))}h3{font-size:calc(1rem * var(--heading-ratio) * var(--heading-ratio))}h4{font-size:calc(1rem * var(--heading-ratio))}h5{font-size:1rem}h6{font-size:calc(1rem / var(--heading-ratio))}p{margin:var(--universal-margin)}ol,ul{margin:var(--universal-margin);padding-left:calc(2 * var(--universal-margin))}b,strong{font-weight:700}hr{box-sizing:content-box;border:0;line-height:1.25em;margin:var(--universal-margin);height:.0625rem;background:linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent)}blockquote{display:block;position:relative;font-style:italic;color:var(--secondary-fore-color);margin:var(--universal-margin);padding:calc(3 * var(--universal-padding));border:.0625rem solid var(--secondary-border-color);border-left:.375rem solid var(--blockquote-color);border-radius:0 var(--universal-border-radius) var(--universal-border-radius) 0}blockquote:before{position:absolute;top:calc(0rem - var(--universal-padding));left:0;font-family:sans-serif;font-size:3rem;font-weight:700;content:"\201c";color:var(--blockquote-color)}blockquote[cite]:after{font-style:normal;font-size:.75em;font-weight:700;content:"\a— " attr(cite);white-space:pre}code,kbd,pre,samp{font-family:Menlo, Consolas, monospace;font-size:.85em}code{background:var(--secondary-back-color);border-radius:var(--universal-border-radius);padding:calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2)}kbd{background:var(--fore-color);color:var(--back-color);border-radius:var(--universal-border-radius);padding:calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2)}pre{overflow:auto;background:var(--secondary-back-color);padding:calc(1.5 * var(--universal-padding));margin:var(--universal-margin);border:.0625rem solid var(--secondary-border-color);border-left:.25rem solid var(--pre-color);border-radius:0 var(--universal-border-radius) var(--universal-border-radius) 0}sup,sub,code,kbd{line-height:0;position:relative;vertical-align:baseline}small,sup,sub,figcaption{font-size:.75em}sup{top:-.5em}sub{bottom:-.25em}figure{margin:var(--universal-margin)}figcaption{color:var(--secondary-fore-color)}a{text-decoration:none}a:link{color:var(--a-link-color)}a:visited{color:var(--a-visited-color)}a:hover,a:focus{text-decoration:underline}.container{margin:0 auto;padding:0 calc(1.5 * var(--universal-padding))}.row{box-sizing:border-box;display:flex;flex:0 1 auto;flex-flow:row wrap}.col-sm,[class^='col-sm-'],[class^='col-sm-offset-'],.row[class*='cols-sm-']>*{box-sizing:border-box;flex:0 0 auto;padding:0 calc(var(--universal-padding) / 2)}.col-sm,.row.cols-sm>*{max-width:100%;flex-grow:1;flex-basis:0}.col-sm-1,.row.cols-sm-1>*{max-width:8.33333%;flex-basis:8.33333%}.col-sm-offset-0{margin-left:0}.col-sm-2,.row.cols-sm-2>*{max-width:16.66667%;flex-basis:16.66667%}.col-sm-offset-1{margin-left:8.33333%}.col-sm-3,.row.cols-sm-3>*{max-width:25%;flex-basis:25%}.col-sm-offset-2{margin-left:16.66667%}.col-sm-4,.row.cols-sm-4>*{max-width:33.33333%;flex-basis:33.33333%}.col-sm-offset-3{margin-left:25%}.col-sm-5,.row.cols-sm-5>*{max-width:41.66667%;flex-basis:41.66667%}.col-sm-offset-4{margin-left:33.33333%}.col-sm-6,.row.cols-sm-6>*{max-width:50%;flex-basis:50%}.col-sm-offset-5{margin-left:41.66667%}.col-sm-7,.row.cols-sm-7>*{max-width:58.33333%;flex-basis:58.33333%}.col-sm-offset-6{margin-left:50%}.col-sm-8,.row.cols-sm-8>*{max-width:66.66667%;flex-basis:66.66667%}.col-sm-offset-7{margin-left:58.33333%}.col-sm-9,.row.cols-sm-9>*{max-width:75%;flex-basis:75%}.col-sm-offset-8{margin-left:66.66667%}.col-sm-10,.row.cols-sm-10>*{max-width:83.33333%;flex-basis:83.33333%}.col-sm-offset-9{margin-left:75%}.col-sm-11,.row.cols-sm-11>*{max-width:91.66667%;flex-basis:91.66667%}.col-sm-offset-10{margin-left:83.33333%}.col-sm-12,.row.cols-sm-12>*{max-width:100%;flex-basis:100%}.col-sm-offset-11{margin-left:91.66667%}.col-sm-normal{order:initial}.col-sm-first{order:-999}.col-sm-last{order:999}@media screen and (min-width: 768px){.col-md,[class^='col-md-'],[class^='col-md-offset-'],.row[class*='cols-md-']>*{box-sizing:border-box;flex:0 0 auto;padding:0 calc(var(--universal-padding) / 2)}.col-md,.row.cols-md>*{max-width:100%;flex-grow:1;flex-basis:0}.col-md-1,.row.cols-md-1>*{max-width:8.33333%;flex-basis:8.33333%}.col-md-offset-0{margin-left:0}.col-md-2,.row.cols-md-2>*{max-width:16.66667%;flex-basis:16.66667%}.col-md-offset-1{margin-left:8.33333%}.col-md-3,.row.cols-md-3>*{max-width:25%;flex-basis:25%}.col-md-offset-2{margin-left:16.66667%}.col-md-4,.row.cols-md-4>*{max-width:33.33333%;flex-basis:33.33333%}.col-md-offset-3{margin-left:25%}.col-md-5,.row.cols-md-5>*{max-width:41.66667%;flex-basis:41.66667%}.col-md-offset-4{margin-left:33.33333%}.col-md-6,.row.cols-md-6>*{max-width:50%;flex-basis:50%}.col-md-offset-5{margin-left:41.66667%}.col-md-7,.row.cols-md-7>*{max-width:58.33333%;flex-basis:58.33333%}.col-md-offset-6{margin-left:50%}.col-md-8,.row.cols-md-8>*{max-width:66.66667%;flex-basis:66.66667%}.col-md-offset-7{margin-left:58.33333%}.col-md-9,.row.cols-md-9>*{max-width:75%;flex-basis:75%}.col-md-offset-8{margin-left:66.66667%}.col-md-10,.row.cols-md-10>*{max-width:83.33333%;flex-basis:83.33333%}.col-md-offset-9{margin-left:75%}.col-md-11,.row.cols-md-11>*{max-width:91.66667%;flex-basis:91.66667%}.col-md-offset-10{margin-left:83.33333%}.col-md-12,.row.cols-md-12>*{max-width:100%;flex-basis:100%}.col-md-offset-11{margin-left:91.66667%}.col-md-normal{order:initial}.col-md-first{order:-999}.col-md-last{order:999}}@media screen and (min-width: 1280px){.col-lg,[class^='col-lg-'],[class^='col-lg-offset-'],.row[class*='cols-lg-']>*{box-sizing:border-box;flex:0 0 auto;padding:0 calc(var(--universal-padding) / 2)}.col-lg,.row.cols-lg>*{max-width:100%;flex-grow:1;flex-basis:0}.col-lg-1,.row.cols-lg-1>*{max-width:8.33333%;flex-basis:8.33333%}.col-lg-offset-0{margin-left:0}.col-lg-2,.row.cols-lg-2>*{max-width:16.66667%;flex-basis:16.66667%}.col-lg-offset-1{margin-left:8.33333%}.col-lg-3,.row.cols-lg-3>*{max-width:25%;flex-basis:25%}.col-lg-offset-2{margin-left:16.66667%}.col-lg-4,.row.cols-lg-4>*{max-width:33.33333%;flex-basis:33.33333%}.col-lg-offset-3{margin-left:25%}.col-lg-5,.row.cols-lg-5>*{max-width:41.66667%;flex-basis:41.66667%}.col-lg-offset-4{margin-left:33.33333%}.col-lg-6,.row.cols-lg-6>*{max-width:50%;flex-basis:50%}.col-lg-offset-5{margin-left:41.66667%}.col-lg-7,.row.cols-lg-7>*{max-width:58.33333%;flex-basis:58.33333%}.col-lg-offset-6{margin-left:50%}.col-lg-8,.row.cols-lg-8>*{max-width:66.66667%;flex-basis:66.66667%}.col-lg-offset-7{margin-left:58.33333%}.col-lg-9,.row.cols-lg-9>*{max-width:75%;flex-basis:75%}.col-lg-offset-8{margin-left:66.66667%}.col-lg-10,.row.cols-lg-10>*{max-width:83.33333%;flex-basis:83.33333%}.col-lg-offset-9{margin-left:75%}.col-lg-11,.row.cols-lg-11>*{max-width:91.66667%;flex-basis:91.66667%}.col-lg-offset-10{margin-left:83.33333%}.col-lg-12,.row.cols-lg-12>*{max-width:100%;flex-basis:100%}.col-lg-offset-11{margin-left:91.66667%}.col-lg-normal{order:initial}.col-lg-first{order:-999}.col-lg-last{order:999}}:root{--card-back-color:#111;--card-fore-color:#fdfdfd;--card-border-color:#aaa}.card{display:flex;flex-direction:column;justify-content:space-between;align-self:center;position:relative;width:100%;background:var(--card-back-color);color:var(--card-fore-color);border:.0625rem solid var(--card-border-color);border-radius:var(--universal-border-radius);margin:var(--universal-margin);overflow:hidden}@media screen and (min-width: 320px){.card{max-width:320px}}.card>.section{background:var(--card-back-color);color:var(--card-fore-color);box-sizing:border-box;margin:0;border:0;border-radius:0;border-bottom:.0625rem solid var(--card-border-color);padding:var(--universal-padding);width:100%}.card>.section.media{height:200px;padding:0;-o-object-fit:cover;object-fit:cover}.card>.section:last-child{border-bottom:0}@media screen and (min-width: 240px){.card.small{max-width:240px}}@media screen and (min-width: 480px){.card.large{max-width:480px}}.card.fluid{max-width:100%;width:auto}.card.warning{--card-back-color:#ffca28;--card-fore-color:#111;--card-border-color:#e8b825}.card.error{--card-back-color:#b71c1c;--card-fore-color:#f8f8f8;--card-border-color:#a71a1a}.card>.section.dark{--card-back-color:#e0e0e0;--card-fore-color:#111}.card>.section.double-padded{padding:calc(1.5 * var(--universal-padding))}:root{--form-back-color:#222;--form-fore-color:#fdfdfd;--form-border-color:#aaa;--input-back-color:#111;--input-fore-color:#fdfdfd;--input-border-color:#aaa;--input-focus-color:#0288d1;--input-invalid-color:#d32f2f;--button-back-color:#212121;--button-hover-back-color:#444;--button-fore-color:#e2e2e2;--button-border-color:transparent;--button-hover-border-color:transparent;--button-group-border-color:rgba(124,124,124,0.54)}form{background:var(--form-back-color);color:var(--form-fore-color);border:.0625rem solid var(--form-border-color);border-radius:var(--universal-border-radius);margin:var(--universal-margin);padding:calc(2 * var(--universal-padding)) var(--universal-padding)}fieldset{border:.0625rem solid var(--form-border-color);border-radius:var(--universal-border-radius);margin:calc(var(--universal-margin) / 4);padding:var(--universal-padding)}legend{box-sizing:border-box;display:table;max-width:100%;white-space:normal;font-weight:700;padding:calc(var(--universal-padding) / 2)}label{padding:calc(var(--universal-padding) / 2) var(--universal-padding)}.input-group{display:inline-block}.input-group.fluid{display:flex;align-items:center;justify-content:center}.input-group.fluid>input{max-width:100%;flex-grow:1;flex-basis:0px}@media screen and (max-width: 767px){.input-group.fluid{align-items:stretch;flex-direction:column}}.input-group.vertical{display:flex;align-items:stretch;flex-direction:column}.input-group.vertical>input{max-width:100%;flex-grow:1;flex-basis:0px}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input:not([type]),[type="text"],[type="email"],[type="number"],[type="search"],[type="password"],[type="url"],[type="tel"],[type="checkbox"],[type="radio"],textarea,select{box-sizing:border-box;background:var(--input-back-color);color:var(--input-fore-color);border:.0625rem solid var(--input-border-color);border-radius:var(--universal-border-radius);margin:calc(var(--universal-margin) / 2);padding:var(--universal-padding) calc(1.5 * var(--universal-padding))}input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover,input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus,textarea:hover,textarea:focus,select:hover,select:focus{border-color:var(--input-focus-color);box-shadow:none}input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid,input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid,textarea:invalid,textarea:focus:invalid,select:invalid,select:focus:invalid{border-color:var(--input-invalid-color);box-shadow:none}input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly],textarea[readonly],select[readonly]{background:var(--secondary-back-color)}select{max-width:100%}option{overflow:hidden;text-overflow:ellipsis}[type="checkbox"],[type="radio"]{-webkit-appearance:none;-moz-appearance:none;appearance:none;position:relative;height:calc(1rem + var(--universal-padding) / 2);width:calc(1rem + var(--universal-padding) / 2);vertical-align:text-bottom;padding:0;flex-basis:calc(1rem + var(--universal-padding) / 2) !important;flex-grow:0 !important}[type="checkbox"]:checked:before,[type="radio"]:checked:before{position:absolute}[type="checkbox"]:checked:before{content:'\2713';font-family:sans-serif;font-size:calc(1rem + var(--universal-padding) / 2);top:calc(0rem - var(--universal-padding));left:calc(var(--universal-padding) / 4)}[type="radio"]{border-radius:100%}[type="radio"]:checked:before{border-radius:100%;content:'';top:calc(.0625rem + var(--universal-padding) / 2);left:calc(.0625rem + var(--universal-padding) / 2);background:var(--input-fore-color);width:0.5rem;height:0.5rem}:placeholder-shown{color:var(--input-fore-color)}::-ms-placeholder{color:var(--input-fore-color);opacity:0.54}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button{overflow:visible;text-transform:none}button,[type="button"],[type="submit"],[type="reset"],a.button,label.button,.button,a[role="button"],label[role="button"],[role="button"]{display:inline-block;background:var(--button-back-color);color:var(--button-fore-color);border:.0625rem solid var(--button-border-color);border-radius:var(--universal-border-radius);padding:var(--universal-padding) calc(1.5 * var(--universal-padding));margin:var(--universal-margin);text-decoration:none;cursor:pointer;transition:background 0.3s}button:hover,button:focus,[type="button"]:hover,[type="button"]:focus,[type="submit"]:hover,[type="submit"]:focus,[type="reset"]:hover,[type="reset"]:focus,a.button:hover,a.button:focus,label.button:hover,label.button:focus,.button:hover,.button:focus,a[role="button"]:hover,a[role="button"]:focus,label[role="button"]:hover,label[role="button"]:focus,[role="button"]:hover,[role="button"]:focus{background:var(--button-hover-back-color);border-color:var(--button-hover-border-color)}input:disabled,input[disabled],textarea:disabled,textarea[disabled],select:disabled,select[disabled],button:disabled,button[disabled],.button:disabled,.button[disabled],[role="button"]:disabled,[role="button"][disabled]{cursor:not-allowed;opacity:.75}.button-group{display:flex;border:.0625rem solid var(--button-group-border-color);border-radius:var(--universal-border-radius);margin:var(--universal-margin)}.button-group>button,.button-group [type="button"],.button-group>[type="submit"],.button-group>[type="reset"],.button-group>.button,.button-group>[role="button"]{margin:0;max-width:100%;flex:1 1 auto;text-align:center;border:0;border-radius:0;box-shadow:none}.button-group>:not(:first-child){border-left:.0625rem solid var(--button-group-border-color)}@media screen and (max-width: 767px){.button-group{flex-direction:column}.button-group>:not(:first-child){border:0;border-top:.0625rem solid var(--button-group-border-color)}}button.primary,[type="button"].primary,[type="submit"].primary,[type="reset"].primary,.button.primary,[role="button"].primary{--button-back-color:#1976d2;--button-fore-color:#f8f8f8}button.primary:hover,button.primary:focus,[type="button"].primary:hover,[type="button"].primary:focus,[type="submit"].primary:hover,[type="submit"].primary:focus,[type="reset"].primary:hover,[type="reset"].primary:focus,.button.primary:hover,.button.primary:focus,[role="button"].primary:hover,[role="button"].primary:focus{--button-hover-back-color:#1565c0}button.secondary,[type="button"].secondary,[type="submit"].secondary,[type="reset"].secondary,.button.secondary,[role="button"].secondary{--button-back-color:#d32f2f;--button-fore-color:#f8f8f8}button.secondary:hover,button.secondary:focus,[type="button"].secondary:hover,[type="button"].secondary:focus,[type="submit"].secondary:hover,[type="submit"].secondary:focus,[type="reset"].secondary:hover,[type="reset"].secondary:focus,.button.secondary:hover,.button.secondary:focus,[role="button"].secondary:hover,[role="button"].secondary:focus{--button-hover-back-color:#c62828}button.tertiary,[type="button"].tertiary,[type="submit"].tertiary,[type="reset"].tertiary,.button.tertiary,[role="button"].tertiary{--button-back-color:#308732;--button-fore-color:#f8f8f8}button.tertiary:hover,button.tertiary:focus,[type="button"].tertiary:hover,[type="button"].tertiary:focus,[type="submit"].tertiary:hover,[type="submit"].tertiary:focus,[type="reset"].tertiary:hover,[type="reset"].tertiary:focus,.button.tertiary:hover,.button.tertiary:focus,[role="button"].tertiary:hover,[role="button"].tertiary:focus{--button-hover-back-color:#277529}button.inverse,[type="button"].inverse,[type="submit"].inverse,[type="reset"].inverse,.button.inverse,[role="button"].inverse{--button-back-color:#f8f8f8;--button-fore-color:#212121}button.inverse:hover,button.inverse:focus,[type="button"].inverse:hover,[type="button"].inverse:focus,[type="submit"].inverse:hover,[type="submit"].inverse:focus,[type="reset"].inverse:hover,[type="reset"].inverse:focus,.button.inverse:hover,.button.inverse:focus,[role="button"].inverse:hover,[role="button"].inverse:focus{--button-hover-back-color:#f0f0f0}button.small,[type="button"].small,[type="submit"].small,[type="reset"].small,.button.small,[role="button"].small{padding:calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding));margin:var(--universal-margin)}button.large,[type="button"].large,[type="submit"].large,[type="reset"].large,.button.large,[role="button"].large{padding:calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding));margin:var(--universal-margin)}:root{--header-back-color:#111;--header-hover-back-color:#222;--header-fore-color:#f0f0f0;--header-border-color:#aaa;--nav-back-color:#111;--nav-hover-back-color:#222;--nav-fore-color:#f0f0f0;--nav-border-color:#aaa;--nav-link-color:#0277bd;--footer-fore-color:#f0f0f0;--footer-back-color:#111;--footer-border-color:#aaa;--footer-link-color:#0277bd;--drawer-back-color:#111;--drawer-hover-back-color:#222;--drawer-border-color:#aaa;--drawer-close-color:#f0f0f0}header{height:3.1875rem;background:var(--header-back-color);color:var(--header-fore-color);border-bottom:.0625rem solid var(--header-border-color);padding:calc(var(--universal-padding) / 4) 0;white-space:nowrap;overflow-x:auto;overflow-y:hidden}header.row{box-sizing:content-box}header .logo{color:var(--header-fore-color);font-size:1.75rem;padding:var(--universal-padding) calc(2 * var(--universal-padding));text-decoration:none}header button,header [type="button"],header .button,header [role="button"]{box-sizing:border-box;position:relative;top:calc(0rem - var(--universal-padding) / 4);height:calc(3.1875rem + var(--universal-padding) / 2);background:var(--header-back-color);line-height:calc(3.1875rem - var(--universal-padding) * 1.5);text-align:center;color:var(--header-fore-color);border:0;border-radius:0;margin:0;text-transform:uppercase}header button:hover,header button:focus,header [type="button"]:hover,header [type="button"]:focus,header .button:hover,header .button:focus,header [role="button"]:hover,header [role="button"]:focus{background:var(--header-hover-back-color)}nav{background:var(--nav-back-color);color:var(--nav-fore-color);border:.0625rem solid var(--nav-border-color);border-radius:var(--universal-border-radius);margin:var(--universal-margin)}nav *{padding:var(--universal-padding) calc(1.5 * var(--universal-padding))}nav a,nav a:visited{display:block;color:var(--nav-link-color);border-radius:var(--universal-border-radius);transition:background 0.3s}nav a:hover,nav a:focus,nav a:visited:hover,nav a:visited:focus{text-decoration:none;background:var(--nav-hover-back-color)}nav .sublink-1{position:relative;margin-left:calc(2 * var(--universal-padding))}nav .sublink-1:before{position:absolute;left:calc(var(--universal-padding) - 1 * var(--universal-padding));top:-.0625rem;content:'';height:100%;border:.0625rem solid var(--nav-border-color);border-left:0}nav .sublink-2{position:relative;margin-left:calc(4 * var(--universal-padding))}nav .sublink-2:before{position:absolute;left:calc(var(--universal-padding) - 3 * var(--universal-padding));top:-.0625rem;content:'';height:100%;border:.0625rem solid var(--nav-border-color);border-left:0}footer{background:var(--footer-back-color);color:var(--footer-fore-color);border-top:.0625rem solid var(--footer-border-color);padding:calc(2 * var(--universal-padding)) var(--universal-padding);font-size:.875rem}footer a,footer a:visited{color:var(--footer-link-color)}header.sticky{position:-webkit-sticky;position:sticky;z-index:1101;top:0}footer.sticky{position:-webkit-sticky;position:sticky;z-index:1101;bottom:0}.drawer-toggle:before{display:inline-block;position:relative;vertical-align:bottom;content:'\00a0\2261\00a0';font-family:sans-serif;font-size:1.5em}@media screen and (min-width: 768px){.drawer-toggle:not(.persistent){display:none}}[type="checkbox"].drawer{height:1px;width:1px;margin:-1px;overflow:hidden;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%)}[type="checkbox"].drawer+*{display:block;box-sizing:border-box;position:fixed;top:0;width:320px;height:100vh;overflow-y:auto;background:var(--drawer-back-color);border:.0625rem solid var(--drawer-border-color);border-radius:0;margin:0;z-index:1110;right:-320px;transition:right 0.3s}[type="checkbox"].drawer+* .drawer-close{position:absolute;top:var(--universal-margin);right:var(--universal-margin);z-index:1111;width:2rem;height:2rem;border-radius:var(--universal-border-radius);padding:var(--universal-padding);margin:0;cursor:pointer;transition:background 0.3s}[type="checkbox"].drawer+* .drawer-close:before{display:block;content:'\00D7';color:var(--drawer-close-color);position:relative;font-family:sans-serif;font-size:2rem;line-height:1;text-align:center}[type="checkbox"].drawer+* .drawer-close:hover,[type="checkbox"].drawer+* .drawer-close:focus{background:var(--drawer-hover-back-color)}@media screen and (max-width: 320px){[type="checkbox"].drawer+*{width:100%}}[type="checkbox"].drawer:checked+*{right:0}@media screen and (min-width: 768px){[type="checkbox"].drawer:not(.persistent)+*{position:static;height:100%;z-index:1100}[type="checkbox"].drawer:not(.persistent)+* .drawer-close{display:none}}:root{--table-border-color:#ddd;--table-border-separator-color:#666;--table-head-back-color:#212121;--table-head-fore-color:#fdfdfd;--table-body-back-color:#111;--table-body-fore-color:#fdfdfd;--table-body-alt-back-color:#444}table{border-collapse:separate;border-spacing:0;margin:0;display:flex;flex:0 1 auto;flex-flow:row wrap;padding:var(--universal-padding);padding-top:0}table caption{font-size:1.5rem;margin:calc(2 * var(--universal-margin)) 0;max-width:100%;flex:0 0 100%}table thead,table tbody{display:flex;flex-flow:row wrap;border:.0625rem solid var(--table-border-color)}table thead{z-index:999;border-radius:var(--universal-border-radius) var(--universal-border-radius) 0 0;border-bottom:.0625rem solid var(--table-border-separator-color)}table tbody{border-top:0;margin-top:calc(0 - var(--universal-margin));border-radius:0 0 var(--universal-border-radius) var(--universal-border-radius)}table tr{display:flex;padding:0}table th,table td{padding:calc(2 * var(--universal-padding))}table th{text-align:left;background:var(--table-head-back-color);color:var(--table-head-fore-color)}table td{background:var(--table-body-back-color);color:var(--table-body-fore-color);border-top:.0625rem solid var(--table-border-color)}table:not(.horizontal){overflow:auto;max-height:400px}table:not(.horizontal) thead,table:not(.horizontal) tbody{max-width:100%;flex:0 0 100%}table:not(.horizontal) tr{flex-flow:row wrap;flex:0 0 100%}table:not(.horizontal) th,table:not(.horizontal) td{flex:1 0 0%;overflow:hidden;text-overflow:ellipsis}table:not(.horizontal) thead{position:sticky;top:0}table:not(.horizontal) tbody tr:first-child td{border-top:0}table.horizontal{border:0}table.horizontal thead,table.horizontal tbody{border:0;flex-flow:row nowrap}table.horizontal tbody{overflow:auto;justify-content:space-between;flex:1 0 0;margin-left:calc( 4 * var(--universal-margin));padding-bottom:calc(var(--universal-padding) / 4)}table.horizontal tr{flex-direction:column;flex:1 0 auto}table.horizontal th,table.horizontal td{width:100%;border:0;border-bottom:.0625rem solid var(--table-border-color)}table.horizontal th:not(:first-child),table.horizontal td:not(:first-child){border-top:0}table.horizontal th{text-align:right;border-left:.0625rem solid var(--table-border-color);border-right:.0625rem solid var(--table-border-separator-color)}table.horizontal thead tr:first-child{padding-left:0}table.horizontal th:first-child,table.horizontal td:first-child{border-top:.0625rem solid var(--table-border-color)}table.horizontal tbody tr:last-child td{border-right:.0625rem solid var(--table-border-color)}table.horizontal tbody tr:last-child td:first-child{border-top-right-radius:0.25rem}table.horizontal tbody tr:last-child td:last-child{border-bottom-right-radius:0.25rem}table.horizontal thead tr:first-child th:first-child{border-top-left-radius:0.25rem}table.horizontal thead tr:first-child th:last-child{border-bottom-left-radius:0.25rem}@media screen and (max-width: 767px){table,table.horizontal{border-collapse:collapse;border:0;width:100%;display:table}table thead,table th,table.horizontal thead,table.horizontal th{border:0;height:1px;width:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%)}table tbody,table.horizontal tbody{border:0;display:table-row-group}table tr,table.horizontal tr{display:block;border:.0625rem solid var(--table-border-color);border-radius:var(--universal-border-radius);background:#fafafa;padding:var(--universal-padding);margin:var(--universal-margin);margin-bottom:calc(2 * var(--universal-margin))}table th,table td,table.horizontal th,table.horizontal td{width:auto}table td,table.horizontal td{display:block;border:0;text-align:right}table td:before,table.horizontal td:before{content:attr(data-label);float:left;font-weight:600}table th:first-child,table td:first-child,table.horizontal th:first-child,table.horizontal td:first-child{border-top:0}table tbody tr:last-child td,table.horizontal tbody tr:last-child td{border-right:0}}:root{--table-body-alt-back-color:#444}table.striped tr:nth-of-type(2n)>td{background:var(--table-body-alt-back-color)}@media screen and (max-width: 768px){table.striped tr:nth-of-type(2n){background:var(--table-body-alt-back-color)}}:root{--table-body-hover-back-color:#5c819f}table.hoverable tr:hover,table.hoverable tr:hover>td,table.hoverable tr:focus,table.hoverable tr:focus>td{background:var(--table-body-hover-back-color)}@media screen and (max-width: 768px){table.hoverable tr:hover,table.hoverable tr:hover>td,table.hoverable tr:focus,table.hoverable tr:focus>td{background:var(--table-body-hover-back-color)}}:root{--mark-back-color:#0277bd;--mark-fore-color:#fafafa}mark{background:var(--mark-back-color);color:var(--mark-fore-color);font-size:.95em;line-height:1em;border-radius:var(--universal-border-radius);padding:calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2)}mark.inline-block{display:inline-block;font-size:1em;line-height:1.5;padding:calc(var(--universal-padding) / 2) var(--universal-padding)}:root{--toast-back-color:#424242;--toast-fore-color:#fafafa}.toast{position:fixed;bottom:calc(var(--universal-margin) * 3);left:50%;transform:translate(-50%, -50%);z-index:1111;color:var(--toast-fore-color);background:var(--toast-back-color);border-radius:calc(var(--universal-border-radius) * 16);padding:var(--universal-padding) calc(var(--universal-padding) * 3)}:root{--tooltip-back-color:#fafafa;--tooltip-fore-color:#212121}.tooltip{position:relative;display:inline-block}.tooltip:before,.tooltip:after{position:absolute;opacity:0;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%);transition:all 0.3s;z-index:1010;left:50%}.tooltip:not(.bottom):before,.tooltip:not(.bottom):after{bottom:75%}.tooltip.bottom:before,.tooltip.bottom:after{top:75%}.tooltip:hover:before,.tooltip:hover:after,.tooltip:focus:before,.tooltip:focus:after{opacity:1;clip:auto;-webkit-clip-path:inset(0%);clip-path:inset(0%)}.tooltip:before{content:'';background:transparent;border:var(--universal-margin) solid transparent;left:calc(50% - var(--universal-margin))}.tooltip:not(.bottom):before{border-top-color:#fafafa}.tooltip.bottom:before{border-bottom-color:#fafafa}.tooltip:after{content:attr(aria-label);color:var(--tooltip-fore-color);background:var(--tooltip-back-color);border-radius:var(--universal-border-radius);padding:var(--universal-padding);white-space:nowrap;transform:translateX(-50%)}.tooltip:not(.bottom):after{margin-bottom:calc(2 * var(--universal-margin))}.tooltip.bottom:after{margin-top:calc(2 * var(--universal-margin))}:root{--modal-overlay-color:rgba(0,0,0,0.45);--modal-close-color:#f0f0f0;--modal-close-hover-color:#222}[type="checkbox"].modal{height:1px;width:1px;margin:-1px;overflow:hidden;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%)}[type="checkbox"].modal+div{position:fixed;top:0;left:0;display:none;width:100vw;height:100vh;background:var(--modal-overlay-color)}[type="checkbox"].modal+div .card{margin:0 auto;max-height:50vh;overflow:auto}[type="checkbox"].modal+div .card .modal-close{position:absolute;top:0;right:0;width:1.75rem;height:1.75rem;border-radius:var(--universal-border-radius);padding:var(--universal-padding);margin:0;cursor:pointer;transition:background 0.3s}[type="checkbox"].modal+div .card .modal-close:before{display:block;content:'\00D7';color:var(--modal-close-color);position:relative;font-family:sans-serif;font-size:1.75rem;line-height:1;text-align:center}[type="checkbox"].modal+div .card .modal-close:hover,[type="checkbox"].modal+div .card .modal-close:focus{background:var(--modal-close-hover-color)}[type="checkbox"].modal:checked+div{display:flex;flex:0 1 auto;z-index:1200}[type="checkbox"].modal:checked+div .card .modal-close{z-index:1211}:root{--collapse-label-back-color:#111;--collapse-label-fore-color:#fafafa;--collapse-label-hover-back-color:#222;--collapse-selected-label-back-color:#444;--collapse-border-color:#aaa;--collapse-content-back-color:#212121;--collapse-selected-label-border-color:#0277bd}.collapse{width:calc(100% - 2 * var(--universal-margin));opacity:1;display:flex;flex-direction:column;margin:var(--universal-margin);border-radius:var(--universal-border-radius)}.collapse>[type="radio"],.collapse>[type="checkbox"]{height:1px;width:1px;margin:-1px;overflow:hidden;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%)}.collapse>label{flex-grow:1;display:inline-block;height:1.5rem;cursor:pointer;transition:background 0.3s;color:var(--collapse-label-fore-color);background:var(--collapse-label-back-color);border:.0625rem solid var(--collapse-border-color);padding:calc(1.5 * var(--universal-padding))}.collapse>label:hover,.collapse>label:focus{background:var(--collapse-label-hover-back-color)}.collapse>label+div{flex-basis:auto;height:1px;width:1px;margin:-1px;overflow:hidden;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%);transition:max-height 0.3s;max-height:1px}.collapse>:checked+label{background:var(--collapse-selected-label-back-color);border-bottom-color:var(--collapse-selected-label-border-color)}.collapse>:checked+label+div{box-sizing:border-box;position:relative;width:100%;height:auto;overflow:auto;margin:0;background:var(--collapse-content-back-color);border:.0625rem solid var(--collapse-border-color);border-top:0;padding:var(--universal-padding);clip:auto;-webkit-clip-path:inset(0%);clip-path:inset(0%);max-height:400px}.collapse>label:not(:first-of-type){border-top:0}.collapse>label:first-of-type{border-radius:var(--universal-border-radius) var(--universal-border-radius) 0 0}.collapse>label:last-of-type:not(:first-of-type){border-radius:0 0 var(--universal-border-radius) var(--universal-border-radius)}.collapse>label:last-of-type:first-of-type{border-radius:var(--universal-border-radius)}.collapse>:checked:last-of-type:not(:first-of-type)+label{border-radius:0}.collapse>:checked:last-of-type+label+div{border-radius:0 0 var(--universal-border-radius) var(--universal-border-radius)}mark.secondary{--mark-back-color:#d32f2f}mark.tertiary{--mark-back-color:#308732}mark.tag{padding:calc(var(--universal-padding)/2) var(--universal-padding);border-radius:1em}:root{--progress-back-color:#aaa;--progress-fore-color:#555}progress{display:block;vertical-align:baseline;-webkit-appearance:none;-moz-appearance:none;appearance:none;height:.75rem;width:calc(100% - 2 * var(--universal-margin));margin:var(--universal-margin);border:0;border-radius:calc(2 * var(--universal-border-radius));background:var(--progress-back-color);color:var(--progress-fore-color)}progress::-webkit-progress-value{background:var(--progress-fore-color);border-top-left-radius:calc(2 * var(--universal-border-radius));border-bottom-left-radius:calc(2 * var(--universal-border-radius))}progress::-webkit-progress-bar{background:var(#aaa)}progress::-moz-progress-bar{background:var(--progress-fore-color);border-top-left-radius:calc(2 * var(--universal-border-radius));border-bottom-left-radius:calc(2 * var(--universal-border-radius))}progress[value="1000"]::-webkit-progress-value{border-radius:calc(2 * var(--universal-border-radius))}progress[value="1000"]::-moz-progress-bar{border-radius:calc(2 * var(--universal-border-radius))}progress.inline{display:inline-block;vertical-align:middle;width:60%}:root{--spinner-back-color:#ddd;--spinner-fore-color:#555}@keyframes spinner-donut-anim{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.spinner{display:inline-block;margin:var(--universal-margin);border:.25rem solid var(--spinner-back-color);border-left:.25rem solid var(--spinner-fore-color);border-radius:50%;width:1.25rem;height:1.25rem;animation:spinner-donut-anim 1.2s linear infinite}progress.primary{--progress-fore-color:#1976d2}progress.secondary{--progress-fore-color:#d32f2f}progress.tertiary{--progress-fore-color:#308732}.spinner.primary{--spinner-fore-color:#1976d2}.spinner.secondary{--spinner-fore-color:#d32f2f}.spinner.tertiary{--spinner-fore-color:#308732}span[class^='icon-']{display:inline-block;height:1em;width:1em;vertical-align:-0.125em;background-size:contain;margin:0 calc(var(--universal-margin) / 4)}span[class^='icon-'].secondary{-webkit-filter:invert(25%);filter:invert(25%)}span[class^='icon-'].inverse{-webkit-filter:invert(100%);filter:invert(100%)}span.icon-alert{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E")}span.icon-bookmark{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E")}span.icon-calendar{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E")}span.icon-credit{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E")}span.icon-edit{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E")}span.icon-link{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E")}span.icon-help{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E")}span.icon-home{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E")}span.icon-info{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E")}span.icon-lock{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E")}span.icon-mail{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E")}span.icon-location{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E")}span.icon-phone{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E")}span.icon-rss{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E")}span.icon-search{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E")}span.icon-settings{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E")}span.icon-share{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E")}span.icon-cart{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E")}span.icon-upload{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E")}span.icon-user{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23fdfdfd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E")}:root{--generic-border-color:rgba(0,0,0,0.3);--generic-box-shadow:0 .25rem .25rem 0 rgba(0,0,0,0.125),0 .125rem .125rem -.125rem rgba(0,0,0,0.125)}.hidden{display:none !important}.visually-hidden{position:absolute !important;width:1px !important;height:1px !important;margin:-1px !important;border:0 !important;padding:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(100%) !important;clip-path:inset(100%) !important;overflow:hidden !important}.bordered{border:.0625rem solid var(--generic-border-color) !important}.rounded{border-radius:var(--universal-border-radius) !important}.circular{border-radius:50% !important}.shadowed{box-shadow:var(--generic-box-shadow) !important}.responsive-margin{margin:calc(var(--universal-margin) / 4) !important}@media screen and (min-width: 768px){.responsive-margin{margin:calc(var(--universal-margin) / 2) !important}}@media screen and (min-width: 1280px){.responsive-margin{margin:var(--universal-margin) !important}}.responsive-padding{padding:calc(var(--universal-padding) / 4) !important}@media screen and (min-width: 768px){.responsive-padding{padding:calc(var(--universal-padding) / 2) !important}}@media screen and (min-width: 1280px){.responsive-padding{padding:var(--universal-padding) !important}}@media screen and (max-width: 767px){.hidden-sm{display:none !important}}@media screen and (min-width: 768px) and (max-width: 1279px){.hidden-md{display:none !important}}@media screen and (min-width: 1280px){.hidden-lg{display:none !important}}@media screen and (max-width: 767px){.visually-hidden-sm{position:absolute !important;width:1px !important;height:1px !important;margin:-1px !important;border:0 !important;padding:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(100%) !important;clip-path:inset(100%) !important;overflow:hidden !important}}@media screen and (min-width: 768px) and (max-width: 1279px){.visually-hidden-md{position:absolute !important;width:1px !important;height:1px !important;margin:-1px !important;border:0 !important;padding:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(100%) !important;clip-path:inset(100%) !important;overflow:hidden !important}}@media screen and (min-width: 1280px){.visually-hidden-lg{position:absolute !important;width:1px !important;height:1px !important;margin:-1px !important;border:0 !important;padding:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(100%) !important;clip-path:inset(100%) !important;overflow:hidden !important}} diff --git a/server/website/css/mini-default.min.css b/server/website/css/mini-default.min.css new file mode 100644 index 0000000..bc8c5bc --- /dev/null +++ b/server/website/css/mini-default.min.css @@ -0,0 +1 @@ +:root{--fore-color:#111;--secondary-fore-color:#444;--back-color:#f8f8f8;--secondary-back-color:#f0f0f0;--blockquote-color:#f57c00;--pre-color:#1565c0;--border-color:#aaa;--secondary-border-color:#ddd;--heading-ratio:1.19;--universal-margin:.5rem;--universal-padding:.5rem;--universal-border-radius:.125rem;--a-link-color:#0277bd;--a-visited-color:#01579b}html{font-size:16px}a,b,del,em,i,ins,q,span,strong,u{font-size:1em}html,*{font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", Helvetica, sans-serif;line-height:1.5;-webkit-text-size-adjust:100%}*{font-size:1rem}body{margin:0;color:var(--fore-color);background:var(--back-color)}details{display:block}summary{display:list-item}abbr[title]{border-bottom:none;text-decoration:underline dotted}input{overflow:visible}img{max-width:100%;height:auto}h1,h2,h3,h4,h5,h6{line-height:1.2;margin:calc(1.5 * var(--universal-margin)) var(--universal-margin);font-weight:500}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:var(--secondary-fore-color);display:block;margin-top:-.25rem}h1{font-size:calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio))}h2{font-size:calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio))}h3{font-size:calc(1rem * var(--heading-ratio) * var(--heading-ratio))}h4{font-size:calc(1rem * var(--heading-ratio))}h5{font-size:1rem}h6{font-size:calc(1rem / var(--heading-ratio))}p{margin:var(--universal-margin)}ol,ul{margin:var(--universal-margin);padding-left:calc(2 * var(--universal-margin))}b,strong{font-weight:700}hr{box-sizing:content-box;border:0;line-height:1.25em;margin:var(--universal-margin);height:.0625rem;background:linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent)}blockquote{display:block;position:relative;font-style:italic;color:var(--secondary-fore-color);margin:var(--universal-margin);padding:calc(3 * var(--universal-padding));border:.0625rem solid var(--secondary-border-color);border-left:.375rem solid var(--blockquote-color);border-radius:0 var(--universal-border-radius) var(--universal-border-radius) 0}blockquote:before{position:absolute;top:calc(0rem - var(--universal-padding));left:0;font-family:sans-serif;font-size:3rem;font-weight:700;content:"\201c";color:var(--blockquote-color)}blockquote[cite]:after{font-style:normal;font-size:.75em;font-weight:700;content:"\a— " attr(cite);white-space:pre}code,kbd,pre,samp{font-family:Menlo, Consolas, monospace;font-size:.85em}code{background:var(--secondary-back-color);border-radius:var(--universal-border-radius);padding:calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2)}kbd{background:var(--fore-color);color:var(--back-color);border-radius:var(--universal-border-radius);padding:calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2)}pre{overflow:auto;background:var(--secondary-back-color);padding:calc(1.5 * var(--universal-padding));margin:var(--universal-margin);border:.0625rem solid var(--secondary-border-color);border-left:.25rem solid var(--pre-color);border-radius:0 var(--universal-border-radius) var(--universal-border-radius) 0}sup,sub,code,kbd{line-height:0;position:relative;vertical-align:baseline}small,sup,sub,figcaption{font-size:.75em}sup{top:-.5em}sub{bottom:-.25em}figure{margin:var(--universal-margin)}figcaption{color:var(--secondary-fore-color)}a{text-decoration:none}a:link{color:var(--a-link-color)}a:visited{color:var(--a-visited-color)}a:hover,a:focus{text-decoration:underline}.container{margin:0 auto;padding:0 calc(1.5 * var(--universal-padding))}.row{box-sizing:border-box;display:flex;flex:0 1 auto;flex-flow:row wrap}.col-sm,[class^='col-sm-'],[class^='col-sm-offset-'],.row[class*='cols-sm-']>*{box-sizing:border-box;flex:0 0 auto;padding:0 calc(var(--universal-padding) / 2)}.col-sm,.row.cols-sm>*{max-width:100%;flex-grow:1;flex-basis:0}.col-sm-1,.row.cols-sm-1>*{max-width:8.33333%;flex-basis:8.33333%}.col-sm-offset-0{margin-left:0}.col-sm-2,.row.cols-sm-2>*{max-width:16.66667%;flex-basis:16.66667%}.col-sm-offset-1{margin-left:8.33333%}.col-sm-3,.row.cols-sm-3>*{max-width:25%;flex-basis:25%}.col-sm-offset-2{margin-left:16.66667%}.col-sm-4,.row.cols-sm-4>*{max-width:33.33333%;flex-basis:33.33333%}.col-sm-offset-3{margin-left:25%}.col-sm-5,.row.cols-sm-5>*{max-width:41.66667%;flex-basis:41.66667%}.col-sm-offset-4{margin-left:33.33333%}.col-sm-6,.row.cols-sm-6>*{max-width:50%;flex-basis:50%}.col-sm-offset-5{margin-left:41.66667%}.col-sm-7,.row.cols-sm-7>*{max-width:58.33333%;flex-basis:58.33333%}.col-sm-offset-6{margin-left:50%}.col-sm-8,.row.cols-sm-8>*{max-width:66.66667%;flex-basis:66.66667%}.col-sm-offset-7{margin-left:58.33333%}.col-sm-9,.row.cols-sm-9>*{max-width:75%;flex-basis:75%}.col-sm-offset-8{margin-left:66.66667%}.col-sm-10,.row.cols-sm-10>*{max-width:83.33333%;flex-basis:83.33333%}.col-sm-offset-9{margin-left:75%}.col-sm-11,.row.cols-sm-11>*{max-width:91.66667%;flex-basis:91.66667%}.col-sm-offset-10{margin-left:83.33333%}.col-sm-12,.row.cols-sm-12>*{max-width:100%;flex-basis:100%}.col-sm-offset-11{margin-left:91.66667%}.col-sm-normal{order:initial}.col-sm-first{order:-999}.col-sm-last{order:999}@media screen and (min-width: 768px){.col-md,[class^='col-md-'],[class^='col-md-offset-'],.row[class*='cols-md-']>*{box-sizing:border-box;flex:0 0 auto;padding:0 calc(var(--universal-padding) / 2)}.col-md,.row.cols-md>*{max-width:100%;flex-grow:1;flex-basis:0}.col-md-1,.row.cols-md-1>*{max-width:8.33333%;flex-basis:8.33333%}.col-md-offset-0{margin-left:0}.col-md-2,.row.cols-md-2>*{max-width:16.66667%;flex-basis:16.66667%}.col-md-offset-1{margin-left:8.33333%}.col-md-3,.row.cols-md-3>*{max-width:25%;flex-basis:25%}.col-md-offset-2{margin-left:16.66667%}.col-md-4,.row.cols-md-4>*{max-width:33.33333%;flex-basis:33.33333%}.col-md-offset-3{margin-left:25%}.col-md-5,.row.cols-md-5>*{max-width:41.66667%;flex-basis:41.66667%}.col-md-offset-4{margin-left:33.33333%}.col-md-6,.row.cols-md-6>*{max-width:50%;flex-basis:50%}.col-md-offset-5{margin-left:41.66667%}.col-md-7,.row.cols-md-7>*{max-width:58.33333%;flex-basis:58.33333%}.col-md-offset-6{margin-left:50%}.col-md-8,.row.cols-md-8>*{max-width:66.66667%;flex-basis:66.66667%}.col-md-offset-7{margin-left:58.33333%}.col-md-9,.row.cols-md-9>*{max-width:75%;flex-basis:75%}.col-md-offset-8{margin-left:66.66667%}.col-md-10,.row.cols-md-10>*{max-width:83.33333%;flex-basis:83.33333%}.col-md-offset-9{margin-left:75%}.col-md-11,.row.cols-md-11>*{max-width:91.66667%;flex-basis:91.66667%}.col-md-offset-10{margin-left:83.33333%}.col-md-12,.row.cols-md-12>*{max-width:100%;flex-basis:100%}.col-md-offset-11{margin-left:91.66667%}.col-md-normal{order:initial}.col-md-first{order:-999}.col-md-last{order:999}}@media screen and (min-width: 1280px){.col-lg,[class^='col-lg-'],[class^='col-lg-offset-'],.row[class*='cols-lg-']>*{box-sizing:border-box;flex:0 0 auto;padding:0 calc(var(--universal-padding) / 2)}.col-lg,.row.cols-lg>*{max-width:100%;flex-grow:1;flex-basis:0}.col-lg-1,.row.cols-lg-1>*{max-width:8.33333%;flex-basis:8.33333%}.col-lg-offset-0{margin-left:0}.col-lg-2,.row.cols-lg-2>*{max-width:16.66667%;flex-basis:16.66667%}.col-lg-offset-1{margin-left:8.33333%}.col-lg-3,.row.cols-lg-3>*{max-width:25%;flex-basis:25%}.col-lg-offset-2{margin-left:16.66667%}.col-lg-4,.row.cols-lg-4>*{max-width:33.33333%;flex-basis:33.33333%}.col-lg-offset-3{margin-left:25%}.col-lg-5,.row.cols-lg-5>*{max-width:41.66667%;flex-basis:41.66667%}.col-lg-offset-4{margin-left:33.33333%}.col-lg-6,.row.cols-lg-6>*{max-width:50%;flex-basis:50%}.col-lg-offset-5{margin-left:41.66667%}.col-lg-7,.row.cols-lg-7>*{max-width:58.33333%;flex-basis:58.33333%}.col-lg-offset-6{margin-left:50%}.col-lg-8,.row.cols-lg-8>*{max-width:66.66667%;flex-basis:66.66667%}.col-lg-offset-7{margin-left:58.33333%}.col-lg-9,.row.cols-lg-9>*{max-width:75%;flex-basis:75%}.col-lg-offset-8{margin-left:66.66667%}.col-lg-10,.row.cols-lg-10>*{max-width:83.33333%;flex-basis:83.33333%}.col-lg-offset-9{margin-left:75%}.col-lg-11,.row.cols-lg-11>*{max-width:91.66667%;flex-basis:91.66667%}.col-lg-offset-10{margin-left:83.33333%}.col-lg-12,.row.cols-lg-12>*{max-width:100%;flex-basis:100%}.col-lg-offset-11{margin-left:91.66667%}.col-lg-normal{order:initial}.col-lg-first{order:-999}.col-lg-last{order:999}}:root{--card-back-color:#f8f8f8;--card-fore-color:#111;--card-border-color:#ddd}.card{display:flex;flex-direction:column;justify-content:space-between;align-self:center;position:relative;width:100%;background:var(--card-back-color);color:var(--card-fore-color);border:.0625rem solid var(--card-border-color);border-radius:var(--universal-border-radius);margin:var(--universal-margin);overflow:hidden}@media screen and (min-width: 320px){.card{max-width:320px}}.card>.section{background:var(--card-back-color);color:var(--card-fore-color);box-sizing:border-box;margin:0;border:0;border-radius:0;border-bottom:.0625rem solid var(--card-border-color);padding:var(--universal-padding);width:100%}.card>.section.media{height:200px;padding:0;-o-object-fit:cover;object-fit:cover}.card>.section:last-child{border-bottom:0}@media screen and (min-width: 240px){.card.small{max-width:240px}}@media screen and (min-width: 480px){.card.large{max-width:480px}}.card.fluid{max-width:100%;width:auto}.card.warning{--card-back-color:#ffca28;--card-border-color:#e8b825}.card.error{--card-back-color:#b71c1c;--card-fore-color:#f8f8f8;--card-border-color:#a71a1a}.card>.section.dark{--card-back-color:#e0e0e0}.card>.section.double-padded{padding:calc(1.5 * var(--universal-padding))}:root{--form-back-color:#f0f0f0;--form-fore-color:#111;--form-border-color:#ddd;--input-back-color:#f8f8f8;--input-fore-color:#111;--input-border-color:#ddd;--input-focus-color:#0288d1;--input-invalid-color:#d32f2f;--button-back-color:#e2e2e2;--button-hover-back-color:#dcdcdc;--button-fore-color:#212121;--button-border-color:transparent;--button-hover-border-color:transparent;--button-group-border-color:rgba(124,124,124,0.54)}form{background:var(--form-back-color);color:var(--form-fore-color);border:.0625rem solid var(--form-border-color);border-radius:var(--universal-border-radius);margin:var(--universal-margin);padding:calc(2 * var(--universal-padding)) var(--universal-padding)}fieldset{border:.0625rem solid var(--form-border-color);border-radius:var(--universal-border-radius);margin:calc(var(--universal-margin) / 4);padding:var(--universal-padding)}legend{box-sizing:border-box;display:table;max-width:100%;white-space:normal;font-weight:700;padding:calc(var(--universal-padding) / 2)}label{padding:calc(var(--universal-padding) / 2) var(--universal-padding)}.input-group{display:inline-block}.input-group.fluid{display:flex;align-items:center;justify-content:center}.input-group.fluid>input{max-width:100%;flex-grow:1;flex-basis:0px}@media screen and (max-width: 767px){.input-group.fluid{align-items:stretch;flex-direction:column}}.input-group.vertical{display:flex;align-items:stretch;flex-direction:column}.input-group.vertical>input{max-width:100%;flex-grow:1;flex-basis:0px}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input:not([type]),[type="text"],[type="email"],[type="number"],[type="search"],[type="password"],[type="url"],[type="tel"],[type="checkbox"],[type="radio"],textarea,select{box-sizing:border-box;background:var(--input-back-color);color:var(--input-fore-color);border:.0625rem solid var(--input-border-color);border-radius:var(--universal-border-radius);margin:calc(var(--universal-margin) / 2);padding:var(--universal-padding) calc(1.5 * var(--universal-padding))}input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover,input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus,textarea:hover,textarea:focus,select:hover,select:focus{border-color:var(--input-focus-color);box-shadow:none}input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid,input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid,textarea:invalid,textarea:focus:invalid,select:invalid,select:focus:invalid{border-color:var(--input-invalid-color);box-shadow:none}input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly],textarea[readonly],select[readonly]{background:var(--secondary-back-color)}select{max-width:100%}option{overflow:hidden;text-overflow:ellipsis}[type="checkbox"],[type="radio"]{-webkit-appearance:none;-moz-appearance:none;appearance:none;position:relative;height:calc(1rem + var(--universal-padding) / 2);width:calc(1rem + var(--universal-padding) / 2);vertical-align:text-bottom;padding:0;flex-basis:calc(1rem + var(--universal-padding) / 2) !important;flex-grow:0 !important}[type="checkbox"]:checked:before,[type="radio"]:checked:before{position:absolute}[type="checkbox"]:checked:before{content:'\2713';font-family:sans-serif;font-size:calc(1rem + var(--universal-padding) / 2);top:calc(0rem - var(--universal-padding));left:calc(var(--universal-padding) / 4)}[type="radio"]{border-radius:100%}[type="radio"]:checked:before{border-radius:100%;content:'';top:calc(.0625rem + var(--universal-padding) / 2);left:calc(.0625rem + var(--universal-padding) / 2);background:var(--input-fore-color);width:0.5rem;height:0.5rem}:placeholder-shown{color:var(--input-fore-color)}::-ms-placeholder{color:var(--input-fore-color);opacity:0.54}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button{overflow:visible;text-transform:none}button,[type="button"],[type="submit"],[type="reset"],a.button,label.button,.button,a[role="button"],label[role="button"],[role="button"]{display:inline-block;background:var(--button-back-color);color:var(--button-fore-color);border:.0625rem solid var(--button-border-color);border-radius:var(--universal-border-radius);padding:var(--universal-padding) calc(1.5 * var(--universal-padding));margin:var(--universal-margin);text-decoration:none;cursor:pointer;transition:background 0.3s}button:hover,button:focus,[type="button"]:hover,[type="button"]:focus,[type="submit"]:hover,[type="submit"]:focus,[type="reset"]:hover,[type="reset"]:focus,a.button:hover,a.button:focus,label.button:hover,label.button:focus,.button:hover,.button:focus,a[role="button"]:hover,a[role="button"]:focus,label[role="button"]:hover,label[role="button"]:focus,[role="button"]:hover,[role="button"]:focus{background:var(--button-hover-back-color);border-color:var(--button-hover-border-color)}input:disabled,input[disabled],textarea:disabled,textarea[disabled],select:disabled,select[disabled],button:disabled,button[disabled],.button:disabled,.button[disabled],[role="button"]:disabled,[role="button"][disabled]{cursor:not-allowed;opacity:.75}.button-group{display:flex;border:.0625rem solid var(--button-group-border-color);border-radius:var(--universal-border-radius);margin:var(--universal-margin)}.button-group>button,.button-group [type="button"],.button-group>[type="submit"],.button-group>[type="reset"],.button-group>.button,.button-group>[role="button"]{margin:0;max-width:100%;flex:1 1 auto;text-align:center;border:0;border-radius:0;box-shadow:none}.button-group>:not(:first-child){border-left:.0625rem solid var(--button-group-border-color)}@media screen and (max-width: 767px){.button-group{flex-direction:column}.button-group>:not(:first-child){border:0;border-top:.0625rem solid var(--button-group-border-color)}}button.primary,[type="button"].primary,[type="submit"].primary,[type="reset"].primary,.button.primary,[role="button"].primary{--button-back-color:#1976d2;--button-fore-color:#f8f8f8}button.primary:hover,button.primary:focus,[type="button"].primary:hover,[type="button"].primary:focus,[type="submit"].primary:hover,[type="submit"].primary:focus,[type="reset"].primary:hover,[type="reset"].primary:focus,.button.primary:hover,.button.primary:focus,[role="button"].primary:hover,[role="button"].primary:focus{--button-hover-back-color:#1565c0}button.secondary,[type="button"].secondary,[type="submit"].secondary,[type="reset"].secondary,.button.secondary,[role="button"].secondary{--button-back-color:#d32f2f;--button-fore-color:#f8f8f8}button.secondary:hover,button.secondary:focus,[type="button"].secondary:hover,[type="button"].secondary:focus,[type="submit"].secondary:hover,[type="submit"].secondary:focus,[type="reset"].secondary:hover,[type="reset"].secondary:focus,.button.secondary:hover,.button.secondary:focus,[role="button"].secondary:hover,[role="button"].secondary:focus{--button-hover-back-color:#c62828}button.tertiary,[type="button"].tertiary,[type="submit"].tertiary,[type="reset"].tertiary,.button.tertiary,[role="button"].tertiary{--button-back-color:#308732;--button-fore-color:#f8f8f8}button.tertiary:hover,button.tertiary:focus,[type="button"].tertiary:hover,[type="button"].tertiary:focus,[type="submit"].tertiary:hover,[type="submit"].tertiary:focus,[type="reset"].tertiary:hover,[type="reset"].tertiary:focus,.button.tertiary:hover,.button.tertiary:focus,[role="button"].tertiary:hover,[role="button"].tertiary:focus{--button-hover-back-color:#277529}button.inverse,[type="button"].inverse,[type="submit"].inverse,[type="reset"].inverse,.button.inverse,[role="button"].inverse{--button-back-color:#212121;--button-fore-color:#f8f8f8}button.inverse:hover,button.inverse:focus,[type="button"].inverse:hover,[type="button"].inverse:focus,[type="submit"].inverse:hover,[type="submit"].inverse:focus,[type="reset"].inverse:hover,[type="reset"].inverse:focus,.button.inverse:hover,.button.inverse:focus,[role="button"].inverse:hover,[role="button"].inverse:focus{--button-hover-back-color:#111}button.small,[type="button"].small,[type="submit"].small,[type="reset"].small,.button.small,[role="button"].small{padding:calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding));margin:var(--universal-margin)}button.large,[type="button"].large,[type="submit"].large,[type="reset"].large,.button.large,[role="button"].large{padding:calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding));margin:var(--universal-margin)}:root{--header-back-color:#f8f8f8;--header-hover-back-color:#f0f0f0;--header-fore-color:#444;--header-border-color:#ddd;--nav-back-color:#f8f8f8;--nav-hover-back-color:#f0f0f0;--nav-fore-color:#444;--nav-border-color:#ddd;--nav-link-color:#0277bd;--footer-fore-color:#444;--footer-back-color:#f8f8f8;--footer-border-color:#ddd;--footer-link-color:#0277bd;--drawer-back-color:#f8f8f8;--drawer-hover-back-color:#f0f0f0;--drawer-border-color:#ddd;--drawer-close-color:#444}header{height:3.1875rem;background:var(--header-back-color);color:var(--header-fore-color);border-bottom:.0625rem solid var(--header-border-color);padding:calc(var(--universal-padding) / 4) 0;white-space:nowrap;overflow-x:auto;overflow-y:hidden}header.row{box-sizing:content-box}header .logo{color:var(--header-fore-color);font-size:1.75rem;padding:var(--universal-padding) calc(2 * var(--universal-padding));text-decoration:none}header button,header [type="button"],header .button,header [role="button"]{box-sizing:border-box;position:relative;top:calc(0rem - var(--universal-padding) / 4);height:calc(3.1875rem + var(--universal-padding) / 2);background:var(--header-back-color);line-height:calc(3.1875rem - var(--universal-padding) * 1.5);text-align:center;color:var(--header-fore-color);border:0;border-radius:0;margin:0;text-transform:uppercase}header button:hover,header button:focus,header [type="button"]:hover,header [type="button"]:focus,header .button:hover,header .button:focus,header [role="button"]:hover,header [role="button"]:focus{background:var(--header-hover-back-color)}nav{background:var(--nav-back-color);color:var(--nav-fore-color);border:.0625rem solid var(--nav-border-color);border-radius:var(--universal-border-radius);margin:var(--universal-margin)}nav *{padding:var(--universal-padding) calc(1.5 * var(--universal-padding))}nav a,nav a:visited{display:block;color:var(--nav-link-color);border-radius:var(--universal-border-radius);transition:background 0.3s}nav a:hover,nav a:focus,nav a:visited:hover,nav a:visited:focus{text-decoration:none;background:var(--nav-hover-back-color)}nav .sublink-1{position:relative;margin-left:calc(2 * var(--universal-padding))}nav .sublink-1:before{position:absolute;left:calc(var(--universal-padding) - 1 * var(--universal-padding));top:-.0625rem;content:'';height:100%;border:.0625rem solid var(--nav-border-color);border-left:0}nav .sublink-2{position:relative;margin-left:calc(4 * var(--universal-padding))}nav .sublink-2:before{position:absolute;left:calc(var(--universal-padding) - 3 * var(--universal-padding));top:-.0625rem;content:'';height:100%;border:.0625rem solid var(--nav-border-color);border-left:0}footer{background:var(--footer-back-color);color:var(--footer-fore-color);border-top:.0625rem solid var(--footer-border-color);padding:calc(2 * var(--universal-padding)) var(--universal-padding);font-size:.875rem}footer a,footer a:visited{color:var(--footer-link-color)}header.sticky{position:-webkit-sticky;position:sticky;z-index:1101;top:0}footer.sticky{position:-webkit-sticky;position:sticky;z-index:1101;bottom:0}.drawer-toggle:before{display:inline-block;position:relative;vertical-align:bottom;content:'\00a0\2261\00a0';font-family:sans-serif;font-size:1.5em}@media screen and (min-width: 768px){.drawer-toggle:not(.persistent){display:none}}[type="checkbox"].drawer{height:1px;width:1px;margin:-1px;overflow:hidden;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%)}[type="checkbox"].drawer+*{display:block;box-sizing:border-box;position:fixed;top:0;width:320px;height:100vh;overflow-y:auto;background:var(--drawer-back-color);border:.0625rem solid var(--drawer-border-color);border-radius:0;margin:0;z-index:1110;right:-320px;transition:right 0.3s}[type="checkbox"].drawer+* .drawer-close{position:absolute;top:var(--universal-margin);right:var(--universal-margin);z-index:1111;width:2rem;height:2rem;border-radius:var(--universal-border-radius);padding:var(--universal-padding);margin:0;cursor:pointer;transition:background 0.3s}[type="checkbox"].drawer+* .drawer-close:before{display:block;content:'\00D7';color:var(--drawer-close-color);position:relative;font-family:sans-serif;font-size:2rem;line-height:1;text-align:center}[type="checkbox"].drawer+* .drawer-close:hover,[type="checkbox"].drawer+* .drawer-close:focus{background:var(--drawer-hover-back-color)}@media screen and (max-width: 320px){[type="checkbox"].drawer+*{width:100%}}[type="checkbox"].drawer:checked+*{right:0}@media screen and (min-width: 768px){[type="checkbox"].drawer:not(.persistent)+*{position:static;height:100%;z-index:1100}[type="checkbox"].drawer:not(.persistent)+* .drawer-close{display:none}}:root{--table-border-color:#aaa;--table-border-separator-color:#666;--table-head-back-color:#e6e6e6;--table-head-fore-color:#111;--table-body-back-color:#f8f8f8;--table-body-fore-color:#111;--table-body-alt-back-color:#eee}table{border-collapse:separate;border-spacing:0;margin:0;display:flex;flex:0 1 auto;flex-flow:row wrap;padding:var(--universal-padding);padding-top:0}table caption{font-size:1.5rem;margin:calc(2 * var(--universal-margin)) 0;max-width:100%;flex:0 0 100%}table thead,table tbody{display:flex;flex-flow:row wrap;border:.0625rem solid var(--table-border-color)}table thead{z-index:999;border-radius:var(--universal-border-radius) var(--universal-border-radius) 0 0;border-bottom:.0625rem solid var(--table-border-separator-color)}table tbody{border-top:0;margin-top:calc(0 - var(--universal-margin));border-radius:0 0 var(--universal-border-radius) var(--universal-border-radius)}table tr{display:flex;padding:0}table th,table td{padding:calc(2 * var(--universal-padding))}table th{text-align:left;background:var(--table-head-back-color);color:var(--table-head-fore-color)}table td{background:var(--table-body-back-color);color:var(--table-body-fore-color);border-top:.0625rem solid var(--table-border-color)}table:not(.horizontal){overflow:auto;max-height:400px}table:not(.horizontal) thead,table:not(.horizontal) tbody{max-width:100%;flex:0 0 100%}table:not(.horizontal) tr{flex-flow:row wrap;flex:0 0 100%}table:not(.horizontal) th,table:not(.horizontal) td{flex:1 0 0%;overflow:hidden;text-overflow:ellipsis}table:not(.horizontal) thead{position:sticky;top:0}table:not(.horizontal) tbody tr:first-child td{border-top:0}table.horizontal{border:0}table.horizontal thead,table.horizontal tbody{border:0;flex-flow:row nowrap}table.horizontal tbody{overflow:auto;justify-content:space-between;flex:1 0 0;margin-left:calc( 4 * var(--universal-margin));padding-bottom:calc(var(--universal-padding) / 4)}table.horizontal tr{flex-direction:column;flex:1 0 auto}table.horizontal th,table.horizontal td{width:100%;border:0;border-bottom:.0625rem solid var(--table-border-color)}table.horizontal th:not(:first-child),table.horizontal td:not(:first-child){border-top:0}table.horizontal th{text-align:right;border-left:.0625rem solid var(--table-border-color);border-right:.0625rem solid var(--table-border-separator-color)}table.horizontal thead tr:first-child{padding-left:0}table.horizontal th:first-child,table.horizontal td:first-child{border-top:.0625rem solid var(--table-border-color)}table.horizontal tbody tr:last-child td{border-right:.0625rem solid var(--table-border-color)}table.horizontal tbody tr:last-child td:first-child{border-top-right-radius:0.25rem}table.horizontal tbody tr:last-child td:last-child{border-bottom-right-radius:0.25rem}table.horizontal thead tr:first-child th:first-child{border-top-left-radius:0.25rem}table.horizontal thead tr:first-child th:last-child{border-bottom-left-radius:0.25rem}@media screen and (max-width: 767px){table,table.horizontal{border-collapse:collapse;border:0;width:100%;display:table}table thead,table th,table.horizontal thead,table.horizontal th{border:0;height:1px;width:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%)}table tbody,table.horizontal tbody{border:0;display:table-row-group}table tr,table.horizontal tr{display:block;border:.0625rem solid var(--table-border-color);border-radius:var(--universal-border-radius);background:#fafafa;padding:var(--universal-padding);margin:var(--universal-margin);margin-bottom:calc(2 * var(--universal-margin))}table th,table td,table.horizontal th,table.horizontal td{width:auto}table td,table.horizontal td{display:block;border:0;text-align:right}table td:before,table.horizontal td:before{content:attr(data-label);float:left;font-weight:600}table th:first-child,table td:first-child,table.horizontal th:first-child,table.horizontal td:first-child{border-top:0}table tbody tr:last-child td,table.horizontal tbody tr:last-child td{border-right:0}}:root{--table-body-alt-back-color:#eee}table.striped tr:nth-of-type(2n)>td{background:var(--table-body-alt-back-color)}@media screen and (max-width: 768px){table.striped tr:nth-of-type(2n){background:var(--table-body-alt-back-color)}}:root{--table-body-hover-back-color:#90caf9}table.hoverable tr:hover,table.hoverable tr:hover>td,table.hoverable tr:focus,table.hoverable tr:focus>td{background:var(--table-body-hover-back-color)}@media screen and (max-width: 768px){table.hoverable tr:hover,table.hoverable tr:hover>td,table.hoverable tr:focus,table.hoverable tr:focus>td{background:var(--table-body-hover-back-color)}}:root{--mark-back-color:#0277bd;--mark-fore-color:#fafafa}mark{background:var(--mark-back-color);color:var(--mark-fore-color);font-size:.95em;line-height:1em;border-radius:var(--universal-border-radius);padding:calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2)}mark.inline-block{display:inline-block;font-size:1em;line-height:1.5;padding:calc(var(--universal-padding) / 2) var(--universal-padding)}:root{--toast-back-color:#424242;--toast-fore-color:#fafafa}.toast{position:fixed;bottom:calc(var(--universal-margin) * 3);left:50%;transform:translate(-50%, -50%);z-index:1111;color:var(--toast-fore-color);background:var(--toast-back-color);border-radius:calc(var(--universal-border-radius) * 16);padding:var(--universal-padding) calc(var(--universal-padding) * 3)}:root{--tooltip-back-color:#212121;--tooltip-fore-color:#fafafa}.tooltip{position:relative;display:inline-block}.tooltip:before,.tooltip:after{position:absolute;opacity:0;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%);transition:all 0.3s;z-index:1010;left:50%}.tooltip:not(.bottom):before,.tooltip:not(.bottom):after{bottom:75%}.tooltip.bottom:before,.tooltip.bottom:after{top:75%}.tooltip:hover:before,.tooltip:hover:after,.tooltip:focus:before,.tooltip:focus:after{opacity:1;clip:auto;-webkit-clip-path:inset(0%);clip-path:inset(0%)}.tooltip:before{content:'';background:transparent;border:var(--universal-margin) solid transparent;left:calc(50% - var(--universal-margin))}.tooltip:not(.bottom):before{border-top-color:#212121}.tooltip.bottom:before{border-bottom-color:#212121}.tooltip:after{content:attr(aria-label);color:var(--tooltip-fore-color);background:var(--tooltip-back-color);border-radius:var(--universal-border-radius);padding:var(--universal-padding);white-space:nowrap;transform:translateX(-50%)}.tooltip:not(.bottom):after{margin-bottom:calc(2 * var(--universal-margin))}.tooltip.bottom:after{margin-top:calc(2 * var(--universal-margin))}:root{--modal-overlay-color:rgba(0,0,0,0.45);--modal-close-color:#444;--modal-close-hover-color:#f0f0f0}[type="checkbox"].modal{height:1px;width:1px;margin:-1px;overflow:hidden;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%)}[type="checkbox"].modal+div{position:fixed;top:0;left:0;display:none;width:100vw;height:100vh;background:var(--modal-overlay-color)}[type="checkbox"].modal+div .card{margin:0 auto;max-height:50vh;overflow:auto}[type="checkbox"].modal+div .card .modal-close{position:absolute;top:0;right:0;width:1.75rem;height:1.75rem;border-radius:var(--universal-border-radius);padding:var(--universal-padding);margin:0;cursor:pointer;transition:background 0.3s}[type="checkbox"].modal+div .card .modal-close:before{display:block;content:'\00D7';color:var(--modal-close-color);position:relative;font-family:sans-serif;font-size:1.75rem;line-height:1;text-align:center}[type="checkbox"].modal+div .card .modal-close:hover,[type="checkbox"].modal+div .card .modal-close:focus{background:var(--modal-close-hover-color)}[type="checkbox"].modal:checked+div{display:flex;flex:0 1 auto;z-index:1200}[type="checkbox"].modal:checked+div .card .modal-close{z-index:1211}:root{--collapse-label-back-color:#e8e8e8;--collapse-label-fore-color:#212121;--collapse-label-hover-back-color:#f0f0f0;--collapse-selected-label-back-color:#ececec;--collapse-border-color:#ddd;--collapse-content-back-color:#fafafa;--collapse-selected-label-border-color:#0277bd}.collapse{width:calc(100% - 2 * var(--universal-margin));opacity:1;display:flex;flex-direction:column;margin:var(--universal-margin);border-radius:var(--universal-border-radius)}.collapse>[type="radio"],.collapse>[type="checkbox"]{height:1px;width:1px;margin:-1px;overflow:hidden;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%)}.collapse>label{flex-grow:1;display:inline-block;height:1.5rem;cursor:pointer;transition:background 0.3s;color:var(--collapse-label-fore-color);background:var(--collapse-label-back-color);border:.0625rem solid var(--collapse-border-color);padding:calc(1.5 * var(--universal-padding))}.collapse>label:hover,.collapse>label:focus{background:var(--collapse-label-hover-back-color)}.collapse>label+div{flex-basis:auto;height:1px;width:1px;margin:-1px;overflow:hidden;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%);transition:max-height 0.3s;max-height:1px}.collapse>:checked+label{background:var(--collapse-selected-label-back-color);border-bottom-color:var(--collapse-selected-label-border-color)}.collapse>:checked+label+div{box-sizing:border-box;position:relative;width:100%;height:auto;overflow:auto;margin:0;background:var(--collapse-content-back-color);border:.0625rem solid var(--collapse-border-color);border-top:0;padding:var(--universal-padding);clip:auto;-webkit-clip-path:inset(0%);clip-path:inset(0%);max-height:400px}.collapse>label:not(:first-of-type){border-top:0}.collapse>label:first-of-type{border-radius:var(--universal-border-radius) var(--universal-border-radius) 0 0}.collapse>label:last-of-type:not(:first-of-type){border-radius:0 0 var(--universal-border-radius) var(--universal-border-radius)}.collapse>label:last-of-type:first-of-type{border-radius:var(--universal-border-radius)}.collapse>:checked:last-of-type:not(:first-of-type)+label{border-radius:0}.collapse>:checked:last-of-type+label+div{border-radius:0 0 var(--universal-border-radius) var(--universal-border-radius)}mark.secondary{--mark-back-color:#d32f2f}mark.tertiary{--mark-back-color:#308732}mark.tag{padding:calc(var(--universal-padding)/2) var(--universal-padding);border-radius:1em}:root{--progress-back-color:#ddd;--progress-fore-color:#555}progress{display:block;vertical-align:baseline;-webkit-appearance:none;-moz-appearance:none;appearance:none;height:.75rem;width:calc(100% - 2 * var(--universal-margin));margin:var(--universal-margin);border:0;border-radius:calc(2 * var(--universal-border-radius));background:var(--progress-back-color);color:var(--progress-fore-color)}progress::-webkit-progress-value{background:var(--progress-fore-color);border-top-left-radius:calc(2 * var(--universal-border-radius));border-bottom-left-radius:calc(2 * var(--universal-border-radius))}progress::-webkit-progress-bar{background:var(#ddd)}progress::-moz-progress-bar{background:var(--progress-fore-color);border-top-left-radius:calc(2 * var(--universal-border-radius));border-bottom-left-radius:calc(2 * var(--universal-border-radius))}progress[value="1000"]::-webkit-progress-value{border-radius:calc(2 * var(--universal-border-radius))}progress[value="1000"]::-moz-progress-bar{border-radius:calc(2 * var(--universal-border-radius))}progress.inline{display:inline-block;vertical-align:middle;width:60%}:root{--spinner-back-color:#ddd;--spinner-fore-color:#555}@keyframes spinner-donut-anim{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.spinner{display:inline-block;margin:var(--universal-margin);border:.25rem solid var(--spinner-back-color);border-left:.25rem solid var(--spinner-fore-color);border-radius:50%;width:1.25rem;height:1.25rem;animation:spinner-donut-anim 1.2s linear infinite}progress.primary{--progress-fore-color:#1976d2}progress.secondary{--progress-fore-color:#d32f2f}progress.tertiary{--progress-fore-color:#308732}.spinner.primary{--spinner-fore-color:#1976d2}.spinner.secondary{--spinner-fore-color:#d32f2f}.spinner.tertiary{--spinner-fore-color:#308732}span[class^='icon-']{display:inline-block;height:1em;width:1em;vertical-align:-0.125em;background-size:contain;margin:0 calc(var(--universal-margin) / 4)}span[class^='icon-'].secondary{-webkit-filter:invert(25%);filter:invert(25%)}span[class^='icon-'].inverse{-webkit-filter:invert(100%);filter:invert(100%)}span.icon-alert{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E")}span.icon-bookmark{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E")}span.icon-calendar{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E")}span.icon-credit{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E")}span.icon-edit{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E")}span.icon-link{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E")}span.icon-help{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E")}span.icon-home{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E")}span.icon-info{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E")}span.icon-lock{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E")}span.icon-mail{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E")}span.icon-location{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E")}span.icon-phone{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E")}span.icon-rss{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E")}span.icon-search{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E")}span.icon-settings{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E")}span.icon-share{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E")}span.icon-cart{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E")}span.icon-upload{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E")}span.icon-user{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23111' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E")}:root{--generic-border-color:rgba(0,0,0,0.3);--generic-box-shadow:0 .25rem .25rem 0 rgba(0,0,0,0.125),0 .125rem .125rem -.125rem rgba(0,0,0,0.25)}.hidden{display:none !important}.visually-hidden{position:absolute !important;width:1px !important;height:1px !important;margin:-1px !important;border:0 !important;padding:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(100%) !important;clip-path:inset(100%) !important;overflow:hidden !important}.bordered{border:.0625rem solid var(--generic-border-color) !important}.rounded{border-radius:var(--universal-border-radius) !important}.circular{border-radius:50% !important}.shadowed{box-shadow:var(--generic-box-shadow) !important}.responsive-margin{margin:calc(var(--universal-margin) / 4) !important}@media screen and (min-width: 768px){.responsive-margin{margin:calc(var(--universal-margin) / 2) !important}}@media screen and (min-width: 1280px){.responsive-margin{margin:var(--universal-margin) !important}}.responsive-padding{padding:calc(var(--universal-padding) / 4) !important}@media screen and (min-width: 768px){.responsive-padding{padding:calc(var(--universal-padding) / 2) !important}}@media screen and (min-width: 1280px){.responsive-padding{padding:var(--universal-padding) !important}}@media screen and (max-width: 767px){.hidden-sm{display:none !important}}@media screen and (min-width: 768px) and (max-width: 1279px){.hidden-md{display:none !important}}@media screen and (min-width: 1280px){.hidden-lg{display:none !important}}@media screen and (max-width: 767px){.visually-hidden-sm{position:absolute !important;width:1px !important;height:1px !important;margin:-1px !important;border:0 !important;padding:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(100%) !important;clip-path:inset(100%) !important;overflow:hidden !important}}@media screen and (min-width: 768px) and (max-width: 1279px){.visually-hidden-md{position:absolute !important;width:1px !important;height:1px !important;margin:-1px !important;border:0 !important;padding:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(100%) !important;clip-path:inset(100%) !important;overflow:hidden !important}}@media screen and (min-width: 1280px){.visually-hidden-lg{position:absolute !important;width:1px !important;height:1px !important;margin:-1px !important;border:0 !important;padding:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(100%) !important;clip-path:inset(100%) !important;overflow:hidden !important}} diff --git a/server/website/css/mini-nord.min.css b/server/website/css/mini-nord.min.css new file mode 100644 index 0000000..af09abb --- /dev/null +++ b/server/website/css/mini-nord.min.css @@ -0,0 +1 @@ +:root{--fore-color:#2e3440;--secondary-fore-color:#3b4252;--back-color:#eceff4;--secondary-back-color:#e5e9f0;--blockquote-color:#d08770;--pre-color:#b48ead;--border-color:#d8dee9;--secondary-border-color:#e5e9f0;--heading-ratio:1.19;--universal-margin:.5rem;--universal-padding:.5rem;--universal-border-radius:.125rem;--a-link-color:#88c0d0;--a-visited-color:#5e81ac}html{font-size:16px}a,b,del,em,i,ins,q,span,strong,u{font-size:1em}html,*{font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", Helvetica, sans-serif;line-height:1.5;-webkit-text-size-adjust:100%}*{font-size:1rem}body{margin:0;color:var(--fore-color);background:var(--back-color)}details{display:block}summary{display:list-item}abbr[title]{border-bottom:none;text-decoration:underline dotted}input{overflow:visible}img{max-width:100%;height:auto}h1,h2,h3,h4,h5,h6{line-height:1.2;margin:calc(1.5 * var(--universal-margin)) var(--universal-margin);font-weight:500}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:var(--secondary-fore-color);display:block;margin-top:-.25rem}h1{font-size:calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio))}h2{font-size:calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio))}h3{font-size:calc(1rem * var(--heading-ratio) * var(--heading-ratio))}h4{font-size:calc(1rem * var(--heading-ratio))}h5{font-size:1rem}h6{font-size:calc(1rem / var(--heading-ratio))}p{margin:var(--universal-margin)}ol,ul{margin:var(--universal-margin);padding-left:calc(2 * var(--universal-margin))}b,strong{font-weight:700}hr{box-sizing:content-box;border:0;line-height:1.25em;margin:var(--universal-margin);height:.0625rem;background:linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent)}blockquote{display:block;position:relative;font-style:italic;color:var(--secondary-fore-color);margin:var(--universal-margin);padding:calc(3 * var(--universal-padding));border:.0625rem solid var(--secondary-border-color);border-left:.375rem solid var(--blockquote-color);border-radius:0 var(--universal-border-radius) var(--universal-border-radius) 0}blockquote:before{position:absolute;top:calc(0rem - var(--universal-padding));left:0;font-family:sans-serif;font-size:3rem;font-weight:700;content:"\201c";color:var(--blockquote-color)}blockquote[cite]:after{font-style:normal;font-size:.75em;font-weight:700;content:"\a— " attr(cite);white-space:pre}code,kbd,pre,samp{font-family:Menlo, Consolas, monospace;font-size:.85em}code{background:var(--secondary-back-color);border-radius:var(--universal-border-radius);padding:calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2)}kbd{background:var(--fore-color);color:var(--back-color);border-radius:var(--universal-border-radius);padding:calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2)}pre{overflow:auto;background:var(--secondary-back-color);padding:calc(1.5 * var(--universal-padding));margin:var(--universal-margin);border:.0625rem solid var(--secondary-border-color);border-left:.25rem solid var(--pre-color);border-radius:0 var(--universal-border-radius) var(--universal-border-radius) 0}sup,sub,code,kbd{line-height:0;position:relative;vertical-align:baseline}small,sup,sub,figcaption{font-size:.75em}sup{top:-.5em}sub{bottom:-.25em}figure{margin:var(--universal-margin)}figcaption{color:var(--secondary-fore-color)}a{text-decoration:none}a:link{color:var(--a-link-color)}a:visited{color:var(--a-visited-color)}a:hover,a:focus{text-decoration:underline}.container{margin:0 auto;padding:0 calc(1.5 * var(--universal-padding))}.row{box-sizing:border-box;display:flex;flex:0 1 auto;flex-flow:row wrap}.col-sm,[class^='col-sm-'],[class^='col-sm-offset-'],.row[class*='cols-sm-']>*{box-sizing:border-box;flex:0 0 auto;padding:0 calc(var(--universal-padding) / 2)}.col-sm,.row.cols-sm>*{max-width:100%;flex-grow:1;flex-basis:0}.col-sm-1,.row.cols-sm-1>*{max-width:8.33333%;flex-basis:8.33333%}.col-sm-offset-0{margin-left:0}.col-sm-2,.row.cols-sm-2>*{max-width:16.66667%;flex-basis:16.66667%}.col-sm-offset-1{margin-left:8.33333%}.col-sm-3,.row.cols-sm-3>*{max-width:25%;flex-basis:25%}.col-sm-offset-2{margin-left:16.66667%}.col-sm-4,.row.cols-sm-4>*{max-width:33.33333%;flex-basis:33.33333%}.col-sm-offset-3{margin-left:25%}.col-sm-5,.row.cols-sm-5>*{max-width:41.66667%;flex-basis:41.66667%}.col-sm-offset-4{margin-left:33.33333%}.col-sm-6,.row.cols-sm-6>*{max-width:50%;flex-basis:50%}.col-sm-offset-5{margin-left:41.66667%}.col-sm-7,.row.cols-sm-7>*{max-width:58.33333%;flex-basis:58.33333%}.col-sm-offset-6{margin-left:50%}.col-sm-8,.row.cols-sm-8>*{max-width:66.66667%;flex-basis:66.66667%}.col-sm-offset-7{margin-left:58.33333%}.col-sm-9,.row.cols-sm-9>*{max-width:75%;flex-basis:75%}.col-sm-offset-8{margin-left:66.66667%}.col-sm-10,.row.cols-sm-10>*{max-width:83.33333%;flex-basis:83.33333%}.col-sm-offset-9{margin-left:75%}.col-sm-11,.row.cols-sm-11>*{max-width:91.66667%;flex-basis:91.66667%}.col-sm-offset-10{margin-left:83.33333%}.col-sm-12,.row.cols-sm-12>*{max-width:100%;flex-basis:100%}.col-sm-offset-11{margin-left:91.66667%}.col-sm-normal{order:initial}.col-sm-first{order:-999}.col-sm-last{order:999}@media screen and (min-width: 768px){.col-md,[class^='col-md-'],[class^='col-md-offset-'],.row[class*='cols-md-']>*{box-sizing:border-box;flex:0 0 auto;padding:0 calc(var(--universal-padding) / 2)}.col-md,.row.cols-md>*{max-width:100%;flex-grow:1;flex-basis:0}.col-md-1,.row.cols-md-1>*{max-width:8.33333%;flex-basis:8.33333%}.col-md-offset-0{margin-left:0}.col-md-2,.row.cols-md-2>*{max-width:16.66667%;flex-basis:16.66667%}.col-md-offset-1{margin-left:8.33333%}.col-md-3,.row.cols-md-3>*{max-width:25%;flex-basis:25%}.col-md-offset-2{margin-left:16.66667%}.col-md-4,.row.cols-md-4>*{max-width:33.33333%;flex-basis:33.33333%}.col-md-offset-3{margin-left:25%}.col-md-5,.row.cols-md-5>*{max-width:41.66667%;flex-basis:41.66667%}.col-md-offset-4{margin-left:33.33333%}.col-md-6,.row.cols-md-6>*{max-width:50%;flex-basis:50%}.col-md-offset-5{margin-left:41.66667%}.col-md-7,.row.cols-md-7>*{max-width:58.33333%;flex-basis:58.33333%}.col-md-offset-6{margin-left:50%}.col-md-8,.row.cols-md-8>*{max-width:66.66667%;flex-basis:66.66667%}.col-md-offset-7{margin-left:58.33333%}.col-md-9,.row.cols-md-9>*{max-width:75%;flex-basis:75%}.col-md-offset-8{margin-left:66.66667%}.col-md-10,.row.cols-md-10>*{max-width:83.33333%;flex-basis:83.33333%}.col-md-offset-9{margin-left:75%}.col-md-11,.row.cols-md-11>*{max-width:91.66667%;flex-basis:91.66667%}.col-md-offset-10{margin-left:83.33333%}.col-md-12,.row.cols-md-12>*{max-width:100%;flex-basis:100%}.col-md-offset-11{margin-left:91.66667%}.col-md-normal{order:initial}.col-md-first{order:-999}.col-md-last{order:999}}@media screen and (min-width: 1280px){.col-lg,[class^='col-lg-'],[class^='col-lg-offset-'],.row[class*='cols-lg-']>*{box-sizing:border-box;flex:0 0 auto;padding:0 calc(var(--universal-padding) / 2)}.col-lg,.row.cols-lg>*{max-width:100%;flex-grow:1;flex-basis:0}.col-lg-1,.row.cols-lg-1>*{max-width:8.33333%;flex-basis:8.33333%}.col-lg-offset-0{margin-left:0}.col-lg-2,.row.cols-lg-2>*{max-width:16.66667%;flex-basis:16.66667%}.col-lg-offset-1{margin-left:8.33333%}.col-lg-3,.row.cols-lg-3>*{max-width:25%;flex-basis:25%}.col-lg-offset-2{margin-left:16.66667%}.col-lg-4,.row.cols-lg-4>*{max-width:33.33333%;flex-basis:33.33333%}.col-lg-offset-3{margin-left:25%}.col-lg-5,.row.cols-lg-5>*{max-width:41.66667%;flex-basis:41.66667%}.col-lg-offset-4{margin-left:33.33333%}.col-lg-6,.row.cols-lg-6>*{max-width:50%;flex-basis:50%}.col-lg-offset-5{margin-left:41.66667%}.col-lg-7,.row.cols-lg-7>*{max-width:58.33333%;flex-basis:58.33333%}.col-lg-offset-6{margin-left:50%}.col-lg-8,.row.cols-lg-8>*{max-width:66.66667%;flex-basis:66.66667%}.col-lg-offset-7{margin-left:58.33333%}.col-lg-9,.row.cols-lg-9>*{max-width:75%;flex-basis:75%}.col-lg-offset-8{margin-left:66.66667%}.col-lg-10,.row.cols-lg-10>*{max-width:83.33333%;flex-basis:83.33333%}.col-lg-offset-9{margin-left:75%}.col-lg-11,.row.cols-lg-11>*{max-width:91.66667%;flex-basis:91.66667%}.col-lg-offset-10{margin-left:83.33333%}.col-lg-12,.row.cols-lg-12>*{max-width:100%;flex-basis:100%}.col-lg-offset-11{margin-left:91.66667%}.col-lg-normal{order:initial}.col-lg-first{order:-999}.col-lg-last{order:999}}:root{--card-back-color:#eceff4;--card-fore-color:#2e3440;--card-border-color:#e5e9f0}.card{display:flex;flex-direction:column;justify-content:space-between;align-self:center;position:relative;width:100%;background:var(--card-back-color);color:var(--card-fore-color);border:.0625rem solid var(--card-border-color);border-radius:var(--universal-border-radius);margin:var(--universal-margin);overflow:hidden}@media screen and (min-width: 320px){.card{max-width:320px}}.card>.section{background:var(--card-back-color);color:var(--card-fore-color);box-sizing:border-box;margin:0;border:0;border-radius:0;border-bottom:.0625rem solid var(--card-border-color);padding:var(--universal-padding);width:100%}.card>.section.media{height:200px;padding:0;-o-object-fit:cover;object-fit:cover}.card>.section:last-child{border-bottom:0}@media screen and (min-width: 240px){.card.small{max-width:240px}}@media screen and (min-width: 480px){.card.large{max-width:480px}}.card.fluid{max-width:100%;width:auto}.card.warning{--card-back-color:#ebcb8b;--card-border-color:#d08770}.card.error{--card-back-color:#bf616a;--card-border-color:#434c5e}.card>.section.dark{--card-back-color:#d8dee9}.card>.section.double-padded{padding:calc(1.5 * var(--universal-padding))}:root{--form-back-color:#e5e9f0;--form-fore-color:#2e3440;--form-border-color:#e5e9f0;--input-back-color:#eceff4;--input-fore-color:#2e3440;--input-border-color:#e5e9f0;--input-focus-color:#88c0d0;--input-invalid-color:#bf616a;--button-back-color:#e5e9f0;--button-hover-back-color:#d8dee9;--button-fore-color:#2e3440;--button-border-color:transparent;--button-hover-border-color:transparent;--button-group-border-color:rgba(124,124,124,0.54)}form{background:var(--form-back-color);color:var(--form-fore-color);border:.0625rem solid var(--form-border-color);border-radius:var(--universal-border-radius);margin:var(--universal-margin);padding:calc(2 * var(--universal-padding)) var(--universal-padding)}fieldset{border:.0625rem solid var(--form-border-color);border-radius:var(--universal-border-radius);margin:calc(var(--universal-margin) / 4);padding:var(--universal-padding)}legend{box-sizing:border-box;display:table;max-width:100%;white-space:normal;font-weight:700;padding:calc(var(--universal-padding) / 2)}label{padding:calc(var(--universal-padding) / 2) var(--universal-padding)}.input-group{display:inline-block}.input-group.fluid{display:flex;align-items:center;justify-content:center}.input-group.fluid>input{max-width:100%;flex-grow:1;flex-basis:0px}@media screen and (max-width: 767px){.input-group.fluid{align-items:stretch;flex-direction:column}}.input-group.vertical{display:flex;align-items:stretch;flex-direction:column}.input-group.vertical>input{max-width:100%;flex-grow:1;flex-basis:0px}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input:not([type]),[type="text"],[type="email"],[type="number"],[type="search"],[type="password"],[type="url"],[type="tel"],[type="checkbox"],[type="radio"],textarea,select{box-sizing:border-box;background:var(--input-back-color);color:var(--input-fore-color);border:.0625rem solid var(--input-border-color);border-radius:var(--universal-border-radius);margin:calc(var(--universal-margin) / 2);padding:var(--universal-padding) calc(1.5 * var(--universal-padding))}input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover,input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus,textarea:hover,textarea:focus,select:hover,select:focus{border-color:var(--input-focus-color);box-shadow:none}input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid,input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid,textarea:invalid,textarea:focus:invalid,select:invalid,select:focus:invalid{border-color:var(--input-invalid-color);box-shadow:none}input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly],textarea[readonly],select[readonly]{background:var(--secondary-back-color)}select{max-width:100%}option{overflow:hidden;text-overflow:ellipsis}[type="checkbox"],[type="radio"]{-webkit-appearance:none;-moz-appearance:none;appearance:none;position:relative;height:calc(1rem + var(--universal-padding) / 2);width:calc(1rem + var(--universal-padding) / 2);vertical-align:text-bottom;padding:0;flex-basis:calc(1rem + var(--universal-padding) / 2) !important;flex-grow:0 !important}[type="checkbox"]:checked:before,[type="radio"]:checked:before{position:absolute}[type="checkbox"]:checked:before{content:'\2713';font-family:sans-serif;font-size:calc(1rem + var(--universal-padding) / 2);top:calc(0rem - var(--universal-padding));left:calc(var(--universal-padding) / 4)}[type="radio"]{border-radius:100%}[type="radio"]:checked:before{border-radius:100%;content:'';top:calc(.0625rem + var(--universal-padding) / 2);left:calc(.0625rem + var(--universal-padding) / 2);background:var(--input-fore-color);width:0.5rem;height:0.5rem}:placeholder-shown{color:var(--input-fore-color)}::-ms-placeholder{color:var(--input-fore-color);opacity:0.54}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button{overflow:visible;text-transform:none}button,[type="button"],[type="submit"],[type="reset"],a.button,label.button,.button,a[role="button"],label[role="button"],[role="button"]{display:inline-block;background:var(--button-back-color);color:var(--button-fore-color);border:.0625rem solid var(--button-border-color);border-radius:var(--universal-border-radius);padding:var(--universal-padding) calc(1.5 * var(--universal-padding));margin:var(--universal-margin);text-decoration:none;cursor:pointer;transition:background 0.3s}button:hover,button:focus,[type="button"]:hover,[type="button"]:focus,[type="submit"]:hover,[type="submit"]:focus,[type="reset"]:hover,[type="reset"]:focus,a.button:hover,a.button:focus,label.button:hover,label.button:focus,.button:hover,.button:focus,a[role="button"]:hover,a[role="button"]:focus,label[role="button"]:hover,label[role="button"]:focus,[role="button"]:hover,[role="button"]:focus{background:var(--button-hover-back-color);border-color:var(--button-hover-border-color)}input:disabled,input[disabled],textarea:disabled,textarea[disabled],select:disabled,select[disabled],button:disabled,button[disabled],.button:disabled,.button[disabled],[role="button"]:disabled,[role="button"][disabled]{cursor:not-allowed;opacity:.75}.button-group{display:flex;border:.0625rem solid var(--button-group-border-color);border-radius:var(--universal-border-radius);margin:var(--universal-margin)}.button-group>button,.button-group [type="button"],.button-group>[type="submit"],.button-group>[type="reset"],.button-group>.button,.button-group>[role="button"]{margin:0;max-width:100%;flex:1 1 auto;text-align:center;border:0;border-radius:0;box-shadow:none}.button-group>:not(:first-child){border-left:.0625rem solid var(--button-group-border-color)}@media screen and (max-width: 767px){.button-group{flex-direction:column}.button-group>:not(:first-child){border:0;border-top:.0625rem solid var(--button-group-border-color)}}button.primary,[type="button"].primary,[type="submit"].primary,[type="reset"].primary,.button.primary,[role="button"].primary{--button-back-color:#5e81ac;--button-fore-color:#eceff4}button.primary:hover,button.primary:focus,[type="button"].primary:hover,[type="button"].primary:focus,[type="submit"].primary:hover,[type="submit"].primary:focus,[type="reset"].primary:hover,[type="reset"].primary:focus,.button.primary:hover,.button.primary:focus,[role="button"].primary:hover,[role="button"].primary:focus{--button-hover-back-color:#5e81ac}button.secondary,[type="button"].secondary,[type="submit"].secondary,[type="reset"].secondary,.button.secondary,[role="button"].secondary{--button-back-color:#bf616a;--button-fore-color:#eceff4}button.secondary:hover,button.secondary:focus,[type="button"].secondary:hover,[type="button"].secondary:focus,[type="submit"].secondary:hover,[type="submit"].secondary:focus,[type="reset"].secondary:hover,[type="reset"].secondary:focus,.button.secondary:hover,.button.secondary:focus,[role="button"].secondary:hover,[role="button"].secondary:focus{--button-hover-back-color:#bf616a}button.tertiary,[type="button"].tertiary,[type="submit"].tertiary,[type="reset"].tertiary,.button.tertiary,[role="button"].tertiary{--button-back-color:#a3be8c;--button-fore-color:#434c5e}button.tertiary:hover,button.tertiary:focus,[type="button"].tertiary:hover,[type="button"].tertiary:focus,[type="submit"].tertiary:hover,[type="submit"].tertiary:focus,[type="reset"].tertiary:hover,[type="reset"].tertiary:focus,.button.tertiary:hover,.button.tertiary:focus,[role="button"].tertiary:hover,[role="button"].tertiary:focus{--button-hover-back-color:#a3be8c}button.inverse,[type="button"].inverse,[type="submit"].inverse,[type="reset"].inverse,.button.inverse,[role="button"].inverse{--button-back-color:#3b4252;--button-fore-color:#eceff4}button.inverse:hover,button.inverse:focus,[type="button"].inverse:hover,[type="button"].inverse:focus,[type="submit"].inverse:hover,[type="submit"].inverse:focus,[type="reset"].inverse:hover,[type="reset"].inverse:focus,.button.inverse:hover,.button.inverse:focus,[role="button"].inverse:hover,[role="button"].inverse:focus{--button-hover-back-color:#2e3440}button.small,[type="button"].small,[type="submit"].small,[type="reset"].small,.button.small,[role="button"].small{padding:calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding));margin:var(--universal-margin)}button.large,[type="button"].large,[type="submit"].large,[type="reset"].large,.button.large,[role="button"].large{padding:calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding));margin:var(--universal-margin)}:root{--header-back-color:#eceff4;--header-hover-back-color:#e5e9f0;--header-fore-color:#3b4252;--header-border-color:#e5e9f0;--nav-back-color:#eceff4;--nav-hover-back-color:#e5e9f0;--nav-fore-color:#3b4252;--nav-border-color:#e5e9f0;--nav-link-color:#88c0d0;--footer-fore-color:#3b4252;--footer-back-color:#eceff4;--footer-border-color:#e5e9f0;--footer-link-color:#88c0d0;--drawer-back-color:#eceff4;--drawer-hover-back-color:#e5e9f0;--drawer-border-color:#e5e9f0;--drawer-close-color:#3b4252}header{height:3.1875rem;background:var(--header-back-color);color:var(--header-fore-color);border-bottom:.0625rem solid var(--header-border-color);padding:calc(var(--universal-padding) / 4) 0;white-space:nowrap;overflow-x:auto;overflow-y:hidden}header.row{box-sizing:content-box}header .logo{color:var(--header-fore-color);font-size:1.75rem;padding:var(--universal-padding) calc(2 * var(--universal-padding));text-decoration:none}header button,header [type="button"],header .button,header [role="button"]{box-sizing:border-box;position:relative;top:calc(0rem - var(--universal-padding) / 4);height:calc(3.1875rem + var(--universal-padding) / 2);background:var(--header-back-color);line-height:calc(3.1875rem - var(--universal-padding) * 1.5);text-align:center;color:var(--header-fore-color);border:0;border-radius:0;margin:0;text-transform:uppercase}header button:hover,header button:focus,header [type="button"]:hover,header [type="button"]:focus,header .button:hover,header .button:focus,header [role="button"]:hover,header [role="button"]:focus{background:var(--header-hover-back-color)}nav{background:var(--nav-back-color);color:var(--nav-fore-color);border:.0625rem solid var(--nav-border-color);border-radius:var(--universal-border-radius);margin:var(--universal-margin)}nav *{padding:var(--universal-padding) calc(1.5 * var(--universal-padding))}nav a,nav a:visited{display:block;color:var(--nav-link-color);border-radius:var(--universal-border-radius);transition:background 0.3s}nav a:hover,nav a:focus,nav a:visited:hover,nav a:visited:focus{text-decoration:none;background:var(--nav-hover-back-color)}nav .sublink-1{position:relative;margin-left:calc(2 * var(--universal-padding))}nav .sublink-1:before{position:absolute;left:calc(var(--universal-padding) - 1 * var(--universal-padding));top:-.0625rem;content:'';height:100%;border:.0625rem solid var(--nav-border-color);border-left:0}nav .sublink-2{position:relative;margin-left:calc(4 * var(--universal-padding))}nav .sublink-2:before{position:absolute;left:calc(var(--universal-padding) - 3 * var(--universal-padding));top:-.0625rem;content:'';height:100%;border:.0625rem solid var(--nav-border-color);border-left:0}footer{background:var(--footer-back-color);color:var(--footer-fore-color);border-top:.0625rem solid var(--footer-border-color);padding:calc(2 * var(--universal-padding)) var(--universal-padding);font-size:.875rem}footer a,footer a:visited{color:var(--footer-link-color)}header.sticky{position:-webkit-sticky;position:sticky;z-index:1101;top:0}footer.sticky{position:-webkit-sticky;position:sticky;z-index:1101;bottom:0}.drawer-toggle:before{display:inline-block;position:relative;vertical-align:bottom;content:'\00a0\2261\00a0';font-family:sans-serif;font-size:1.5em}@media screen and (min-width: 768px){.drawer-toggle:not(.persistent){display:none}}[type="checkbox"].drawer{height:1px;width:1px;margin:-1px;overflow:hidden;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%)}[type="checkbox"].drawer+*{display:block;box-sizing:border-box;position:fixed;top:0;width:320px;height:100vh;overflow-y:auto;background:var(--drawer-back-color);border:.0625rem solid var(--drawer-border-color);border-radius:0;margin:0;z-index:1110;right:-320px;transition:right 0.3s}[type="checkbox"].drawer+* .drawer-close{position:absolute;top:var(--universal-margin);right:var(--universal-margin);z-index:1111;width:2rem;height:2rem;border-radius:var(--universal-border-radius);padding:var(--universal-padding);margin:0;cursor:pointer;transition:background 0.3s}[type="checkbox"].drawer+* .drawer-close:before{display:block;content:'\00D7';color:var(--drawer-close-color);position:relative;font-family:sans-serif;font-size:2rem;line-height:1;text-align:center}[type="checkbox"].drawer+* .drawer-close:hover,[type="checkbox"].drawer+* .drawer-close:focus{background:var(--drawer-hover-back-color)}@media screen and (max-width: 320px){[type="checkbox"].drawer+*{width:100%}}[type="checkbox"].drawer:checked+*{right:0}@media screen and (min-width: 768px){[type="checkbox"].drawer:not(.persistent)+*{position:static;height:100%;z-index:1100}[type="checkbox"].drawer:not(.persistent)+* .drawer-close{display:none}}:root{--table-border-color:#d8dee9;--table-border-separator-color:#434c5e;--table-head-back-color:#e5e9f0;--table-head-fore-color:#2e3440;--table-body-back-color:#eceff4;--table-body-fore-color:#2e3440;--table-body-alt-back-color:#e5e9f0}table{border-collapse:separate;border-spacing:0;margin:0;display:flex;flex:0 1 auto;flex-flow:row wrap;padding:var(--universal-padding);padding-top:0}table caption{font-size:1.5rem;margin:calc(2 * var(--universal-margin)) 0;max-width:100%;flex:0 0 100%}table thead,table tbody{display:flex;flex-flow:row wrap;border:.0625rem solid var(--table-border-color)}table thead{z-index:999;border-radius:var(--universal-border-radius) var(--universal-border-radius) 0 0;border-bottom:.0625rem solid var(--table-border-separator-color)}table tbody{border-top:0;margin-top:calc(0 - var(--universal-margin));border-radius:0 0 var(--universal-border-radius) var(--universal-border-radius)}table tr{display:flex;padding:0}table th,table td{padding:calc(2 * var(--universal-padding))}table th{text-align:left;background:var(--table-head-back-color);color:var(--table-head-fore-color)}table td{background:var(--table-body-back-color);color:var(--table-body-fore-color);border-top:.0625rem solid var(--table-border-color)}table:not(.horizontal){overflow:auto;max-height:400px}table:not(.horizontal) thead,table:not(.horizontal) tbody{max-width:100%;flex:0 0 100%}table:not(.horizontal) tr{flex-flow:row wrap;flex:0 0 100%}table:not(.horizontal) th,table:not(.horizontal) td{flex:1 0 0%;overflow:hidden;text-overflow:ellipsis}table:not(.horizontal) thead{position:sticky;top:0}table:not(.horizontal) tbody tr:first-child td{border-top:0}table.horizontal{border:0}table.horizontal thead,table.horizontal tbody{border:0;flex-flow:row nowrap}table.horizontal tbody{overflow:auto;justify-content:space-between;flex:1 0 0;margin-left:calc( 4 * var(--universal-margin));padding-bottom:calc(var(--universal-padding) / 4)}table.horizontal tr{flex-direction:column;flex:1 0 auto}table.horizontal th,table.horizontal td{width:100%;border:0;border-bottom:.0625rem solid var(--table-border-color)}table.horizontal th:not(:first-child),table.horizontal td:not(:first-child){border-top:0}table.horizontal th{text-align:right;border-left:.0625rem solid var(--table-border-color);border-right:.0625rem solid var(--table-border-separator-color)}table.horizontal thead tr:first-child{padding-left:0}table.horizontal th:first-child,table.horizontal td:first-child{border-top:.0625rem solid var(--table-border-color)}table.horizontal tbody tr:last-child td{border-right:.0625rem solid var(--table-border-color)}table.horizontal tbody tr:last-child td:first-child{border-top-right-radius:0.25rem}table.horizontal tbody tr:last-child td:last-child{border-bottom-right-radius:0.25rem}table.horizontal thead tr:first-child th:first-child{border-top-left-radius:0.25rem}table.horizontal thead tr:first-child th:last-child{border-bottom-left-radius:0.25rem}@media screen and (max-width: 767px){table,table.horizontal{border-collapse:collapse;border:0;width:100%;display:table}table thead,table th,table.horizontal thead,table.horizontal th{border:0;height:1px;width:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%)}table tbody,table.horizontal tbody{border:0;display:table-row-group}table tr,table.horizontal tr{display:block;border:.0625rem solid var(--table-border-color);border-radius:var(--universal-border-radius);background:#fafafa;padding:var(--universal-padding);margin:var(--universal-margin);margin-bottom:calc(2 * var(--universal-margin))}table th,table td,table.horizontal th,table.horizontal td{width:auto}table td,table.horizontal td{display:block;border:0;text-align:right}table td:before,table.horizontal td:before{content:attr(data-label);float:left;font-weight:600}table th:first-child,table td:first-child,table.horizontal th:first-child,table.horizontal td:first-child{border-top:0}table tbody tr:last-child td,table.horizontal tbody tr:last-child td{border-right:0}}:root{--table-body-alt-back-color:#e5e9f0}table.striped tr:nth-of-type(2n)>td{background:var(--table-body-alt-back-color)}@media screen and (max-width: 768px){table.striped tr:nth-of-type(2n){background:var(--table-body-alt-back-color)}}:root{--table-body-hover-back-color:#88c0d0}table.hoverable tr:hover,table.hoverable tr:hover>td,table.hoverable tr:focus,table.hoverable tr:focus>td{background:var(--table-body-hover-back-color)}@media screen and (max-width: 768px){table.hoverable tr:hover,table.hoverable tr:hover>td,table.hoverable tr:focus,table.hoverable tr:focus>td{background:var(--table-body-hover-back-color)}}:root{--mark-back-color:#5e81ac;--mark-fore-color:#fafafa}mark{background:var(--mark-back-color);color:var(--mark-fore-color);font-size:.95em;line-height:1em;border-radius:var(--universal-border-radius);padding:calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2)}mark.inline-block{display:inline-block;font-size:1em;line-height:1.5;padding:calc(var(--universal-padding) / 2) var(--universal-padding)}:root{--toast-back-color:#2e3440;--toast-fore-color:#eceff4}.toast{position:fixed;bottom:calc(var(--universal-margin) * 3);left:50%;transform:translate(-50%, -50%);z-index:1111;color:var(--toast-fore-color);background:var(--toast-back-color);border-radius:calc(var(--universal-border-radius) * 16);padding:var(--universal-padding) calc(var(--universal-padding) * 3)}:root{--tooltip-back-color:#2e3440;--tooltip-fore-color:#eceff4}.tooltip{position:relative;display:inline-block}.tooltip:before,.tooltip:after{position:absolute;opacity:0;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%);transition:all 0.3s;z-index:1010;left:50%}.tooltip:not(.bottom):before,.tooltip:not(.bottom):after{bottom:75%}.tooltip.bottom:before,.tooltip.bottom:after{top:75%}.tooltip:hover:before,.tooltip:hover:after,.tooltip:focus:before,.tooltip:focus:after{opacity:1;clip:auto;-webkit-clip-path:inset(0%);clip-path:inset(0%)}.tooltip:before{content:'';background:transparent;border:var(--universal-margin) solid transparent;left:calc(50% - var(--universal-margin))}.tooltip:not(.bottom):before{border-top-color:#2e3440}.tooltip.bottom:before{border-bottom-color:#2e3440}.tooltip:after{content:attr(aria-label);color:var(--tooltip-fore-color);background:var(--tooltip-back-color);border-radius:var(--universal-border-radius);padding:var(--universal-padding);white-space:nowrap;transform:translateX(-50%)}.tooltip:not(.bottom):after{margin-bottom:calc(2 * var(--universal-margin))}.tooltip.bottom:after{margin-top:calc(2 * var(--universal-margin))}:root{--modal-overlay-color:rgba(0,0,0,0.45);--modal-close-color:#3b4252;--modal-close-hover-color:#e5e9f0}[type="checkbox"].modal{height:1px;width:1px;margin:-1px;overflow:hidden;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%)}[type="checkbox"].modal+div{position:fixed;top:0;left:0;display:none;width:100vw;height:100vh;background:var(--modal-overlay-color)}[type="checkbox"].modal+div .card{margin:0 auto;max-height:50vh;overflow:auto}[type="checkbox"].modal+div .card .modal-close{position:absolute;top:0;right:0;width:1.75rem;height:1.75rem;border-radius:var(--universal-border-radius);padding:var(--universal-padding);margin:0;cursor:pointer;transition:background 0.3s}[type="checkbox"].modal+div .card .modal-close:before{display:block;content:'\00D7';color:var(--modal-close-color);position:relative;font-family:sans-serif;font-size:1.75rem;line-height:1;text-align:center}[type="checkbox"].modal+div .card .modal-close:hover,[type="checkbox"].modal+div .card .modal-close:focus{background:var(--modal-close-hover-color)}[type="checkbox"].modal:checked+div{display:flex;flex:0 1 auto;z-index:1200}[type="checkbox"].modal:checked+div .card .modal-close{z-index:1211}:root{--collapse-label-back-color:#e5e9f0;--collapse-label-fore-color:#2e3440;--collapse-label-hover-back-color:#e5e9f0;--collapse-selected-label-back-color:#e5e9f0;--collapse-border-color:#e5e9f0;--collapse-content-back-color:#fafafa;--collapse-selected-label-border-color:#88c0d0}.collapse{width:calc(100% - 2 * var(--universal-margin));opacity:1;display:flex;flex-direction:column;margin:var(--universal-margin);border-radius:var(--universal-border-radius)}.collapse>[type="radio"],.collapse>[type="checkbox"]{height:1px;width:1px;margin:-1px;overflow:hidden;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%)}.collapse>label{flex-grow:1;display:inline-block;height:1.5rem;cursor:pointer;transition:background 0.3s;color:var(--collapse-label-fore-color);background:var(--collapse-label-back-color);border:.0625rem solid var(--collapse-border-color);padding:calc(1.5 * var(--universal-padding))}.collapse>label:hover,.collapse>label:focus{background:var(--collapse-label-hover-back-color)}.collapse>label+div{flex-basis:auto;height:1px;width:1px;margin:-1px;overflow:hidden;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%);transition:max-height 0.3s;max-height:1px}.collapse>:checked+label{background:var(--collapse-selected-label-back-color);border-bottom-color:var(--collapse-selected-label-border-color)}.collapse>:checked+label+div{box-sizing:border-box;position:relative;width:100%;height:auto;overflow:auto;margin:0;background:var(--collapse-content-back-color);border:.0625rem solid var(--collapse-border-color);border-top:0;padding:var(--universal-padding);clip:auto;-webkit-clip-path:inset(0%);clip-path:inset(0%);max-height:400px}.collapse>label:not(:first-of-type){border-top:0}.collapse>label:first-of-type{border-radius:var(--universal-border-radius) var(--universal-border-radius) 0 0}.collapse>label:last-of-type:not(:first-of-type){border-radius:0 0 var(--universal-border-radius) var(--universal-border-radius)}.collapse>label:last-of-type:first-of-type{border-radius:var(--universal-border-radius)}.collapse>:checked:last-of-type:not(:first-of-type)+label{border-radius:0}.collapse>:checked:last-of-type+label+div{border-radius:0 0 var(--universal-border-radius) var(--universal-border-radius)}mark.secondary{--mark-back-color:#bf616a}mark.tertiary{--mark-back-color:#a3be8c}mark.tag{padding:calc(var(--universal-padding)/2) var(--universal-padding);border-radius:1em}:root{--progress-back-color:#e5e9f0;--progress-fore-color:#434c5e}progress{display:block;vertical-align:baseline;-webkit-appearance:none;-moz-appearance:none;appearance:none;height:.75rem;width:calc(100% - 2 * var(--universal-margin));margin:var(--universal-margin);border:0;border-radius:calc(2 * var(--universal-border-radius));background:var(--progress-back-color);color:var(--progress-fore-color)}progress::-webkit-progress-value{background:var(--progress-fore-color);border-top-left-radius:calc(2 * var(--universal-border-radius));border-bottom-left-radius:calc(2 * var(--universal-border-radius))}progress::-webkit-progress-bar{background:var(#e5e9f0)}progress::-moz-progress-bar{background:var(--progress-fore-color);border-top-left-radius:calc(2 * var(--universal-border-radius));border-bottom-left-radius:calc(2 * var(--universal-border-radius))}progress[value="1000"]::-webkit-progress-value{border-radius:calc(2 * var(--universal-border-radius))}progress[value="1000"]::-moz-progress-bar{border-radius:calc(2 * var(--universal-border-radius))}progress.inline{display:inline-block;vertical-align:middle;width:60%}:root{--spinner-back-color:#d8dee9;--spinner-fore-color:#434c5e}@keyframes spinner-donut-anim{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.spinner{display:inline-block;margin:var(--universal-margin);border:.25rem solid var(--spinner-back-color);border-left:.25rem solid var(--spinner-fore-color);border-radius:50%;width:1.25rem;height:1.25rem;animation:spinner-donut-anim 1.2s linear infinite}progress.primary{--progress-fore-color:#5e81ac}progress.secondary{--progress-fore-color:#bf616a}progress.tertiary{--progress-fore-color:#a3be8c}.spinner.primary{--spinner-fore-color:#5e81ac}.spinner.secondary{--spinner-fore-color:#bf616a}.spinner.tertiary{--spinner-fore-color:#a3be8c}span[class^='icon-']{display:inline-block;height:1em;width:1em;vertical-align:-0.125em;background-size:contain;margin:0 calc(var(--universal-margin) / 4)}span[class^='icon-'].secondary{-webkit-filter:invert(25%);filter:invert(25%)}span[class^='icon-'].inverse{-webkit-filter:invert(100%);filter:invert(100%)}span.icon-alert{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E")}span.icon-bookmark{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E")}span.icon-calendar{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E")}span.icon-credit{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E")}span.icon-edit{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E")}span.icon-link{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E")}span.icon-help{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E")}span.icon-home{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E")}span.icon-info{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E")}span.icon-lock{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E")}span.icon-mail{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E")}span.icon-location{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E")}span.icon-phone{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E")}span.icon-rss{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E")}span.icon-search{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E")}span.icon-settings{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E")}span.icon-share{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E")}span.icon-cart{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E")}span.icon-upload{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E")}span.icon-user{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232e3440' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E")}:root{--generic-border-color:rgba(0,0,0,0.3);--generic-box-shadow:0 .25rem .25rem 0 rgba(0,0,0,0.125),0 .125rem .125rem -.125rem rgba(0,0,0,0.125)}.hidden{display:none !important}.visually-hidden{position:absolute !important;width:1px !important;height:1px !important;margin:-1px !important;border:0 !important;padding:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(100%) !important;clip-path:inset(100%) !important;overflow:hidden !important}.bordered{border:.0625rem solid var(--generic-border-color) !important}.rounded{border-radius:var(--universal-border-radius) !important}.circular{border-radius:50% !important}.shadowed{box-shadow:var(--generic-box-shadow) !important}.responsive-margin{margin:calc(var(--universal-margin) / 4) !important}@media screen and (min-width: 768px){.responsive-margin{margin:calc(var(--universal-margin) / 2) !important}}@media screen and (min-width: 1280px){.responsive-margin{margin:var(--universal-margin) !important}}.responsive-padding{padding:calc(var(--universal-padding) / 4) !important}@media screen and (min-width: 768px){.responsive-padding{padding:calc(var(--universal-padding) / 2) !important}}@media screen and (min-width: 1280px){.responsive-padding{padding:var(--universal-padding) !important}}@media screen and (max-width: 767px){.hidden-sm{display:none !important}}@media screen and (min-width: 768px) and (max-width: 1279px){.hidden-md{display:none !important}}@media screen and (min-width: 1280px){.hidden-lg{display:none !important}}@media screen and (max-width: 767px){.visually-hidden-sm{position:absolute !important;width:1px !important;height:1px !important;margin:-1px !important;border:0 !important;padding:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(100%) !important;clip-path:inset(100%) !important;overflow:hidden !important}}@media screen and (min-width: 768px) and (max-width: 1279px){.visually-hidden-md{position:absolute !important;width:1px !important;height:1px !important;margin:-1px !important;border:0 !important;padding:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(100%) !important;clip-path:inset(100%) !important;overflow:hidden !important}}@media screen and (min-width: 1280px){.visually-hidden-lg{position:absolute !important;width:1px !important;height:1px !important;margin:-1px !important;border:0 !important;padding:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(100%) !important;clip-path:inset(100%) !important;overflow:hidden !important}} diff --git a/server/website/css/style.css b/server/website/css/style.css new file mode 100644 index 0000000..bec9693 --- /dev/null +++ b/server/website/css/style.css @@ -0,0 +1,250 @@ + +html +{ + height: 100%; +} + +body +{ + display: flex; + justify-content: center; + align-items: center; + min-height: 100%; + +} + +@keyframes blink-shadow { + 0% { box-shadow: 0 0 32px #DDD; } + 50% { box-shadow: none; } + 100% { box-shadow: 0 0 32px #DDD; } +} + +#mainpnl +{ + box-shadow: 0 0 32px #DDD; + //animation:blink-shadow ease-in-out 4s infinite; + width: 87%; + min-width: 300px; + max-width: 900px; + position: relative; + min-height: 570px; + + background: var(--form-back-color); + color: var(--form-fore-color); + border: .0625rem solid var(--form-border-color); + border-radius: var(--universal-border-radius); + margin: 32px .5rem; + padding: calc(2 * var(--universal-padding)) var(--universal-padding); +} + +.red-code +{ + border-left: .25rem solid #E53935; +} + +.yellow-code +{ + border-left: .25rem solid #FFCB05; +} + +#mainpnl input, +#mainpnl textarea +{ + width: 100%; +} + +.responsive-label { + align-items:center; +} +@media (min-width: 768px) { + .responsive-label .col-md-3 { + text-align:right + } +} + +#mainpnl h1 +{ + text-align: center; + margin-top: 0; + margin-bottom: 24px; + font-weight: bold; + color: #FFF; + text-shadow: #000 0 0 2px, #888 0 0 8px; +} +@media (max-width: 600px) { + #mainpnl h1 { + font-size: calc(0.85rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio)); + margin-top: 40px; + } +} + +#mainpnl button +{ + width: 100%; + margin-left: 4px; + margin-right: 4px; +} + +#copyinfo +{ + margin: 4px; + position: fixed; + bottom: 0; + right: 0; + //z-index: -999; + display: flex; + flex-direction: column; + text-align: right; +} + +#copyinfo a, +#copyinfo a:visited, +#copyinfo a:active +{ + font-family: "Courier New", monospace; + color: #AAA; + text-decoration: none; + display: block; + line-height: 1em; +} + +#copyinfo a:hover +{ + font-family: "Courier New", monospace; + color: #0288D1; +} + +#tr_link +{ + position: absolute; + top: 0; + right: 0; + margin: -1px -1px 0 0; + border-top-left-radius: 0; + border-bottom-right-radius: 0; + min-width: 40px; + text-align: center; +} + +#tl_link +{ + position: absolute; + top: 0; + left: 0; + margin: -1px 0 0 -1px; + border-top-right-radius: 0; + border-bottom-left-radius: 0; + padding: 4px 4px 0 4px; +} + +.icn-google-play { + display: inline-block; + width: 32px; + height: 32px; + background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHg9IjBweCIgeT0iMHB4IgogICAgIHdpZHRoPSI1MCIgaGVpZ2h0PSI1MCIKICAgICB2aWV3Qm94PSIwIDAgNDggNDgiCiAgICAgc3R5bGU9ImZpbGw6IzAwMDAwMDsiPjxnIGlkPSJzdXJmYWNlMSI+PHBhdGggc3R5bGU9IiBmaWxsOiM0REI2QUM7IiBkPSJNIDcuNzAzMTI1IDQuMDQyOTY5IEMgNy4yOTI5NjkgNC4xNDg0MzggNyA0LjUwNzgxMyA3IDUuMTIxMDk0IEMgNyA2LjkyMTg3NSA3IDIzLjkxNDA2MyA3IDIzLjkxNDA2MyBDIDcgMjMuOTE0MDYzIDcgNDIuMjgxMjUgNyA0My4wODk4NDQgQyA3IDQzLjUzNTE1NiA3LjE5NTMxMyA0My44MzU5MzggNy41IDQzLjk0NTMxMyBMIDI3LjY3OTY4OCAyMy44ODI4MTMgWiAiPjwvcGF0aD48cGF0aCBzdHlsZT0iIGZpbGw6I0RDRTc3NTsiIGQ9Ik0gMzMuMjM4MjgxIDE4LjM1OTM3NSBMIDI0LjkyOTY4OCAxMy41NjI1IEMgMjQuOTI5Njg4IDEzLjU2MjUgOS42ODM1OTQgNC43NjE3MTkgOC43ODkwNjMgNC4yNDIxODggQyA4LjQwMjM0NCA0LjAxOTUzMSA4LjAxOTUzMSAzLjk2MDkzOCA3LjcwMzEyNSA0LjA0Mjk2OSBMIDI3LjY4MzU5NCAyMy44ODI4MTMgWiAiPjwvcGF0aD48cGF0aCBzdHlsZT0iIGZpbGw6I0QzMkYyRjsiIGQ9Ik0gOC40MTc5NjkgNDMuODAwNzgxIEMgOC45NDkyMTkgNDMuNDkyMTg4IDIzLjY5OTIxOSAzNC45NzY1NjMgMzMuMjgxMjUgMjkuNDQ1MzEzIEwgMjcuNjc5Njg4IDIzLjg4MjgxMyBMIDcuNSA0My45NDUzMTMgQyA3Ljc0NjA5NCA0NC4wMzkwNjMgOC4wNjY0MDYgNDQuMDAzOTA2IDguNDE3OTY5IDQzLjgwMDc4MSBaICI+PC9wYXRoPjxwYXRoIHN0eWxlPSIgZmlsbDojRkJDMDJEOyIgZD0iTSA0MS4zOTg0MzggMjMuMDcwMzEzIEMgNDAuNjAxNTYzIDIyLjY0MDYyNSAzMy4yOTY4NzUgMTguMzk0NTMxIDMzLjI5Njg3NSAxOC4zOTQ1MzEgTCAzMy4yMzgyODEgMTguMzU5Mzc1IEwgMjcuNjc5Njg4IDIzLjg4MjgxMyBMIDMzLjI4MTI1IDI5LjQ0NTMxMyBDIDM3LjcxNDg0NCAyNi44ODY3MTkgNDEuMDQyOTY5IDI0Ljk2NDg0NCA0MS4zMzk4NDQgMjQuNzkyOTY5IEMgNDIuMjg1MTU2IDI0LjI0NjA5NCA0Mi4xOTUzMTMgMjMuNSA0MS4zOTg0MzggMjMuMDcwMzEzIFogIj48L3BhdGg+PC9nPjwvc3ZnPg==') 50% 50% no-repeat; + background-size: 100%; +} + +#btnSend +{ + height: 42px; +} + +#btnSend .spinnerbox .spinner +{ + margin: 0; + padding: 0; + height: 16px; + width: 16px; +} + +#btnSend .spinnerbox +{ + margin: -8px; + display: flex; + justify-content: center; + align-items: center; + align-content: center; +} + +input[type='number'] { + -moz-appearance:textfield; +} + +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + -webkit-appearance: none; +} + +.input-invalid, +.input-invalid:hover, +.input-invalid:active +{ + border-color: var(--input-invalid-color) !important; + box-shadow: none !important; +} + +.card.success { + --card-back-color: rgb(48, 135, 50); + --card-border-color: rgba(0, 0, 0, 0.3);; +} + +.fullcenterflex +{ + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; + align-content: center; + pointer-events: none; +} + +.fullcenterflex .card +{ + pointer-events: auto; +} + +a.card, +a.card:active, +a.card:visited, +a.card:hover +{ + color: #000; + text-decoration: none; +} + +a.card:hover +{ + box-shadow: 0 0 16px #AAA; +} + +table.scode_table { + max-height: none; +} + +table.scode_table td:nth-child(2) { + flex-grow: 3; +} + +table.scode_table th:nth-child(2) { + flex-grow: 3; +} + +#mainpnl h2 { + margin-top: 1.75rem; +} + +.linkcaption:hover, +.linkcaption:focus { + text-decoration: none; +} + +pre, pre span +{ + font-family: Menlo, Consolas, monospace; + background: #F9F9F9;; +} \ No newline at end of file diff --git a/server/website/css/toastify.min.css b/server/website/css/toastify.min.css new file mode 100644 index 0000000..765a518 --- /dev/null +++ b/server/website/css/toastify.min.css @@ -0,0 +1,15 @@ +/** + * Minified by jsDelivr using clean-css v4.2.0. + * Original file: /npm/toastify.js@1.3.0/src/toastify.css + * + * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files + */ +/*! + * Toastify js 1.2.2 + * https://github.com/apvarun/toastify-js + * @license MIT licensed + * + * Copyright (C) 2018 Varun A P + */ +.toastify{padding:12px 20px;color:#fff;display:inline-block;box-shadow:0 3px 6px -1px rgba(0,0,0,.12),0 10px 36px -4px rgba(77,96,232,.3);background:-webkit-linear-gradient(315deg,#73a5ff,#5477f5);background:linear-gradient(135deg,#73a5ff,#5477f5);position:fixed;opacity:0;transition:all .4s cubic-bezier(.215,.61,.355,1);border-radius:2px;cursor:pointer;text-decoration:none;max-width:calc(50% - 20px)}.toastify.on{opacity:1}.toast-close{opacity:.4;padding:0 5px}.right{right:15px}.left{left:15px}.top{top:-150px}.bottom{bottom:-150px}.rounded{border-radius:25px}.avatar{width:1.5em;height:1.5em;margin:0 5px;border-radius:2px}@media only screen and (max-width:360px){.left,.right{margin-left:auto;margin-right:auto;left:0;right:0;max-width:fit-content}} +/*# sourceMappingURL=/sm/734ed69e2fe87a4469526acc0a10708fa8e0211c7d4359f9e034ceb89bb5d540.map */ \ No newline at end of file diff --git a/server/website/favicon.ico b/server/website/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..3729f2e10ab780386388a17f89025e6818e6b1ed GIT binary patch literal 99678 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

i;6A+@O>bBX=(tg`7=!r~> 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 pa|&oQNNSWhB*P(g?Mmzmvv4FO#oa#Kw1C* literal 0 HcmV?d00001 diff --git a/server/website/index.html b/server/website/index.html new file mode 100644 index 0000000..cd3c81b --- /dev/null +++ b/server/website/index.html @@ -0,0 +1,69 @@ + + + + + Simple Cloud Notifications + + + + + + + + + + + + + +
+ + + API + +

Simple Cloud Notifier

+ +
+
+
type="number">
+
+ +
+
+
type="text" maxlength="64">
+
+ +
+
+
+ +
+
+ +
+
+
type="text" maxlength="80">
+
+ +
+
+
+
+ +
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/server/website/js/logic.js b/server/website/js/logic.js new file mode 100644 index 0000000..6171928 --- /dev/null +++ b/server/website/js/logic.js @@ -0,0 +1,90 @@ + +function send() +{ + let me = document.getElementById("btnSend"); + if (me.classList.contains("btn-disabled")) return; + + me.innerHTML = "
"; + + me.classList.add("btn-disabled"); + + let uid = document.getElementById("uid"); + let key = document.getElementById("ukey"); + let msg = document.getElementById("msg"); + let txt = document.getElementById("txt"); + let pio = document.getElementById("prio"); + + uid.classList.remove('input-invalid'); + key.classList.remove('input-invalid'); + msg.classList.remove('input-invalid'); + txt.classList.remove('input-invalid'); + pio.classList.remove('input-invalid'); + + let data = new FormData(); + data.append('user_id', uid.value); + data.append('user_key', key.value); + data.append('title', msg.value); + data.append('content', txt.value); + data.append('priority', pio.value); + + let xhr = new XMLHttpRequest(); + xhr.open('POST', '/', true); + xhr.onreadystatechange = function () + { + if (xhr.readyState !== 4) return; + + console.log('Status: ' + xhr.status); + if (xhr.status === 200 || xhr.status === 401 || xhr.status === 403 || xhr.status === 412) + { + let resp = JSON.parse(xhr.responseText); + if (!resp.success || xhr.status !== 200) + { + if (resp.errhighlight === 101) uid.classList.add('input-invalid'); + if (resp.errhighlight === 102) key.classList.add('input-invalid'); + if (resp.errhighlight === 103) msg.classList.add('input-invalid'); + if (resp.errhighlight === 104) txt.classList.add('input-invalid'); + if (resp.errhighlight === 105) pio.classList.add('input-invalid'); + + Toastify({ + text: resp.message, + gravity: "top", + positionLeft: false, + backgroundColor: "#D32F2F", + }).showToast(); + } + else + { + window.location.href = + '/message_sent' + + '?ok=' + 1 + + '&message_count=' + resp.messagecount + + '"a=' + resp.quota + + '"a_remain=' + (resp.quota_max-resp.quota) + + '"a_max=' + resp.quota_max + + '&preset_user_id=' + uid.value + + '&preset_user_key=' + key.value; + } + } + else + { + Toastify({ + text: 'Request failed: Statuscode=' + xhr.status, + gravity: "top", + positionLeft: false, + backgroundColor: "#D32F2F", + }).showToast(); + } + + me.classList.remove("btn-disabled"); + me.innerHTML = "Send"; + }; + xhr.send(data); +} + +window.addEventListener("load",function () +{ + let btnSend = document.getElementById("btnSend"); + + if (btnSend !== undefined) btnSend.onclick = function () { send(); return false; }; + +},false); \ No newline at end of file diff --git a/server/website/js/toastify.js b/server/website/js/toastify.js new file mode 100644 index 0000000..bbd01cd --- /dev/null +++ b/server/website/js/toastify.js @@ -0,0 +1,8 @@ +/** + * Minified by jsDelivr using UglifyJS v3.4.3. + * Original file: /npm/toastify-js@1.3.0/src/toastify.js + * + * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files + */ +!function(t,o){"object"==typeof module&&module.exports?(require("./toastify.css"),module.exports=o()):t.Toastify=o()}(this,function(t){var i=function(t){return new i.lib.init(t)};function r(t,o){return!(!t||"string"!=typeof o)&&!!(t.className&&-1 + + + + Simple Cloud Notifications + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/server/website/website.go b/server/website/website.go new file mode 100644 index 0000000..b1661ab --- /dev/null +++ b/server/website/website.go @@ -0,0 +1,8 @@ +package website + +import "embed" + +//go:embed * +//go:embed css/* +//go:embed js/* +var Assets embed.FS