diff --git a/messages/uniworx/de.msg b/messages/uniworx/de.msg
index f620cecf7..7fa4c8bce 100644
--- a/messages/uniworx/de.msg
+++ b/messages/uniworx/de.msg
@@ -29,6 +29,16 @@ InvalidInput: Eingaben bitte korrigieren.
Term: Semester
TermPlaceholder: W/S + vierstellige Jahreszahl
+TermStartDay: Erster Tag
+TermStartDayTooltip: Üblicherweise immer 1.April oder 1.Oktober
+TermEndDay: Letzter Tag
+TermEndDayTooltip: Üblicherweise immer 30.September oder 31.März
+TermLectureStart: Beginn Vorlesungen
+TermLectureEnd: Ende Vorlesungen
+TermLectureEndTooltip: Meistens dauer das Sommersemester 14 Wochen und das Wintersemester 15 Wochen.
+TermActive: Aktiv
+
+
SchoolListHeading: Übersicht über verwaltete Institute
SchoolHeading school@SchoolName: Übersicht #{display school}
@@ -583,6 +593,7 @@ MenuSheetClone: Als neues Übungsblatt klonen
MenuCorrectionsUpload: Korrekturen hochladen
MenuCorrectionsCreate: Abgaben registrieren
MenuCorrectionsGrade: Abgaben bewerten
+MenuAuthPreds: Authorisierungseinstellungen
AuthPredsActive: Aktive Authorisierungsprädikate
AuthPredsActiveChanged: Authorisierungseinstellungen für aktuelle Sitzung gespeichert
diff --git a/src/Foundation.hs b/src/Foundation.hs
index f9415181f..4938141d6 100644
--- a/src/Foundation.hs
+++ b/src/Foundation.hs
@@ -495,12 +495,11 @@ tagAccessPredicate AuthTime = APDB $ \route _ -> case route of
case mbc of
(Just (Entity _ Course{courseRegisterFrom, courseRegisterTo}))
| not registered
- , Just regFrom <- courseRegisterFrom -- Nothing = no registration
- , regFrom <= now
- , maybe True (now <=) courseRegisterTo -> return Authorized
+ , maybe False (now >=) courseRegisterFrom -- Nothing => no registration allowed
+ , maybe True (now <=) courseRegisterTo -> return Authorized
(Just (Entity _ Course{courseDeregisterUntil}))
| registered
- , maybe True (now <=) courseDeregisterUntil -> return Authorized
+ , maybe True (now <=) courseDeregisterUntil -> return Authorized
_other -> unauthorizedI MsgUnauthorizedCourseTime
MessageR cID -> maybeT (unauthorizedI MsgUnauthorizedSystemMessageTime) $ do
@@ -975,7 +974,6 @@ siteLayout headingOverride widget = do
hasPrimaryPageActions = any (is _PageActionPrime) $ toListOf (traverse . _1 . _menuItemType) menuTypes
pc <- widgetToPageContent $ do
- addStylesheetRemote "https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,800,900|Roboto:300,400,600"
addScript $ StaticR js_zepto_js
addScript $ StaticR js_fetchPolyfill_js
addScript $ StaticR js_urlPolyfill_js
@@ -1227,6 +1225,14 @@ pageActions (ProfileR) =
, menuItemModal = False
, menuItemAccessCallback' = return True
}
+ -- , MenuItem
+ -- { menuItemType = PageActionSecondary
+ -- , menuItemLabel = MsgMenuAuthPreds
+ -- , menuItemIcon = Nothing
+ -- , menuItemRoute = SomeRoute AuthPredsR
+ -- , menuItemModal = True
+ -- , menuItemAccessCallback' = return True
+ -- }
]
pageActions TermShowR =
[ MenuItem
diff --git a/src/Handler/Home.hs b/src/Handler/Home.hs
index 148557f6f..ae3691266 100644
--- a/src/Handler/Home.hs
+++ b/src/Handler/Home.hs
@@ -268,7 +268,8 @@ postAuthPredsR = do
((authActiveRes, authActiveWidget), authActiveEnctype) <- runFormPost . renderAForm FormStandard
$ AuthTagActive
- <$> funcForm taForm (fslI MsgActiveAuthTags) True
+ <$> (submitButton -- for convenience, avoids frequent scrolling
+ *> funcForm taForm (fslI MsgActiveAuthTags) True)
<* submitButton
mReferer <- runMaybeT $ do
diff --git a/src/Handler/Sheet.hs b/src/Handler/Sheet.hs
index fd15fa58b..615fa91e1 100644
--- a/src/Handler/Sheet.hs
+++ b/src/Handler/Sheet.hs
@@ -444,25 +444,28 @@ getSheetNewR tid ssh csh = do
E.orderBy [E.desc (sheet E.^. SheetActiveFrom)]
E.limit 1
return sheet
+ now <- liftIO getCurrentTime
let template = case lastSheets of
- ((Entity {entityVal=Sheet{..}}):_) -> Just $ SheetForm
- { sfName = stepTextCounterCI sheetName
- , sfDescription = sheetDescription
- , sfType = sheetType
- , sfGrouping = sheetGrouping
- , sfVisibleFrom = addOneWeek <$> sheetVisibleFrom
- , sfActiveFrom = addOneWeek sheetActiveFrom
- , sfActiveTo = addOneWeek sheetActiveTo
- , sfSubmissionMode = sheetSubmissionMode
- , sfUploadMode = sheetUploadMode
- , sfSheetF = Nothing
- , sfHintFrom = addOneWeek <$> sheetHintFrom
- , sfHintF = Nothing
- , sfSolutionFrom = addOneWeek <$> sheetSolutionFrom
- , sfSolutionF = Nothing
- , sfMarkingF = Nothing
- , sfMarkingText = sheetMarkingText
- }
+ ((Entity {entityVal=Sheet{..}}):_) ->
+ let addTime = addWeeks $ max 1 $ weeksToAdd sheetActiveTo now
+ in Just $ SheetForm
+ { sfName = stepTextCounterCI sheetName
+ , sfDescription = sheetDescription
+ , sfType = sheetType
+ , sfGrouping = sheetGrouping
+ , sfVisibleFrom = addTime <$> sheetVisibleFrom
+ , sfActiveFrom = addTime sheetActiveFrom
+ , sfActiveTo = addTime sheetActiveTo
+ , sfSubmissionMode = sheetSubmissionMode
+ , sfUploadMode = sheetUploadMode
+ , sfSheetF = Nothing
+ , sfHintFrom = addTime <$> sheetHintFrom
+ , sfHintF = Nothing
+ , sfSolutionFrom = addTime <$> sheetSolutionFrom
+ , sfSolutionF = Nothing
+ , sfMarkingF = Nothing
+ , sfMarkingText = sheetMarkingText
+ }
_other -> Nothing
let action newSheet = -- More specific error message for new sheet could go here, if insertUnique returns Nothing
insertUnique $ newSheet
diff --git a/src/Handler/Term.hs b/src/Handler/Term.hs
index 0c778343b..0f9da91a8 100644
--- a/src/Handler/Term.hs
+++ b/src/Handler/Term.hs
@@ -10,6 +10,13 @@ import Yesod.Form.Bootstrap3
import qualified Database.Esqueleto as E
+-- | Default start day of term for season,
+-- @True@: start of term, @False@: end of term
+defaultDay :: Bool -> Season -> Day
+defaultDay True Winter = fromGregorian 2020 10 1
+defaultDay False Winter = fromGregorian 2020 3 31
+defaultDay True Summer = fromGregorian 2020 4 1
+defaultDay False Summer = fromGregorian 2020 9 30
validateTerm :: Term -> [Text]
@@ -120,7 +127,7 @@ getTermShowR = do
, FilterColumn $ \term -> term E.^. TermActive :: E.SqlExpr (E.Value Bool)
)
, ( "course"
- , FilterColumn $ \term csh -> case csh of -- FilterColumn-Lambdas are
+ , FilterColumn $ \term csh -> case csh of -- FilterColumn-Lambdas are
[] -> E.val True :: E.SqlExpr (E.Value Bool)
cshs -> E.exists . E.from $ \course ->
E.where_ $ course E.^. CourseTerm E.==. term E.^. TermId
@@ -137,20 +144,32 @@ getTermShowR = do
$(widgetFile "terms")
getTermEditR :: Handler Html
-getTermEditR =
- -- TODO: Defaults für Semester hier ermitteln und übergeben
- termEditHandler Nothing
+getTermEditR = do
+ mbLastTerm <- runDB $ selectFirst [] [Desc TermName]
+ let template = case mbLastTerm of
+ Nothing -> mempty
+ (Just (Entity { entityVal=Term{..} })) -> let
+ ntid = succ termName
+ seas = season ntid
+ yr = year ntid
+ yr' = if seas == Summer then yr else succ yr
+ in mempty
+ { tftName = Just $ ntid
+ , tftStart = Just $ defaultDay True seas & setYear yr
+ , tftEnd = Just $ defaultDay False seas & setYear yr'
+ }
+ termEditHandler template
postTermEditR :: Handler Html
-postTermEditR = termEditHandler Nothing
+postTermEditR = termEditHandler mempty
getTermEditExistR :: TermId -> Handler Html
getTermEditExistR tid = do
term <- runDB $ get tid
- termEditHandler term
+ termEditHandler $ termToTemplate term
-termEditHandler :: Maybe Term -> Handler Html
+termEditHandler :: TermFormTemplate -> Handler Html
termEditHandler term = do
((result, formWidget), formEnctype) <- runFormPost $ newTermForm term
case result of
@@ -172,17 +191,63 @@ termEditHandler term = do
setTitleI MsgTermEditHeading
$(widgetFile "formPage")
-newTermForm :: Maybe Term -> Form Term
+data TermFormTemplate = TermFormTemplate
+ { tftName :: Maybe TermIdentifier
+ , tftStart :: Maybe Day
+ , tftEnd :: Maybe Day
+ , tftHolidays :: Maybe [Day]
+ , tftLectureStart :: Maybe Day
+ , tftLectureEnd :: Maybe Day
+ , tftActive :: Maybe Bool
+ }
+
+-- | TermFormTemplates form a pointwise-left biased Semigroup
+instance Semigroup TermFormTemplate where
+ left <> right = TermFormTemplate
+ { tftName = tftName left <|> tftName right
+ , tftStart = tftStart left <|> tftStart right
+ , tftEnd = tftEnd left <|> tftEnd right
+ , tftHolidays = tftHolidays left <|> tftHolidays right
+ , tftLectureStart = tftLectureStart left <|> tftLectureStart right
+ , tftLectureEnd = tftLectureEnd left <|> tftLectureEnd right
+ , tftActive = tftActive left <|> tftActive right
+ }
+
+instance Monoid TermFormTemplate where
+ mappend = (<>)
+ mempty = TermFormTemplate
+ { tftName = Nothing
+ , tftStart = Nothing
+ , tftEnd = Nothing
+ , tftHolidays = Nothing
+ , tftLectureStart = Nothing
+ , tftLectureEnd = Nothing
+ , tftActive = Nothing
+ }
+
+termToTemplate ::Maybe Term -> TermFormTemplate
+termToTemplate Nothing = mempty
+termToTemplate (Just Term{..}) = TermFormTemplate
+ { tftName = Just termName
+ , tftStart = Just termStart
+ , tftEnd = Just termEnd
+ , tftHolidays = Just termHolidays
+ , tftLectureStart = Just termLectureStart
+ , tftLectureEnd = Just termLectureEnd
+ , tftActive = Just termActive
+ }
+
+newTermForm :: TermFormTemplate -> Form Term
newTermForm template html = do
mr <- getMessageRender
(result, widget) <- flip (renderAForm FormStandard) html $ Term
- <$> areq termNewField (fslpI MsgTerm (mr MsgTermPlaceholder)) (termName <$> template)
- <*> areq dayField (fsl ("Erster Tag" :: Text)) (termStart <$> template)
- <*> areq dayField (fsl ("Letzer Tag" :: Text)) (termEnd <$> template)
+ <$> areq termNewField (fslpI MsgTerm (mr MsgTermPlaceholder)) (tftName template)
+ <*> areq dayField (fslI MsgTermStartDay & setTooltip MsgTermStartDayTooltip) (tftStart template)
+ <*> areq dayField (fslI MsgTermEndDay & setTooltip MsgTermEndDayTooltip) (tftEnd template)
<*> pure [] -- TODO: List of Day field required, must probably be done as its own form and then combined
- <*> areq dayField (fsl "Beginn Vorlesungen") (termLectureStart <$> template)
- <*> areq dayField (fsl ("Ende Vorlesungen" :: Text)) (termLectureEnd <$> template)
- <*> areq checkBoxField (bfs ("Aktiv" :: Text)) (termActive <$> template)
+ <*> areq dayField (fslI MsgTermLectureStart) (tftLectureStart template)
+ <*> areq dayField (fslI MsgTermLectureEnd & setTooltip MsgTermLectureEndTooltip) (tftLectureEnd template)
+ <*> areq checkBoxField (bfs ("Aktiv" :: Text)) (tftActive template)
<* submitButton
return $ case result of
FormSuccess termResult
diff --git a/src/Handler/Utils/DateTime.hs b/src/Handler/Utils/DateTime.hs
index 890990027..1d31051fa 100644
--- a/src/Handler/Utils/DateTime.hs
+++ b/src/Handler/Utils/DateTime.hs
@@ -5,7 +5,9 @@ module Handler.Utils.DateTime
, getTimeLocale, getDateTimeFormat
, validDateTimeFormats, dateTimeFormatOptions
, formatTimeMail
- , addOneWeek
+ , addOneWeek, addWeeks
+ , weekDiff, weeksToAdd
+ , setYear
) where
import Import
@@ -14,12 +16,13 @@ import Data.Time.Zones
import qualified Data.Time.Zones as TZ
import Data.Time hiding (formatTime, localTimeToUTC, utcToLocalTime)
-import Data.Time.Clock (addUTCTime,nominalDay)
+-- import Data.Time.Clock (addUTCTime,nominalDay)
import qualified Data.Time.Format as Time
import Data.Set (Set)
import qualified Data.Set as Set
+
utcToLocalTime :: UTCTime -> LocalTime
utcToLocalTime = TZ.utcToLocalTimeTZ appTZ
@@ -125,14 +128,42 @@ dateTimeFormatOptions sel = do
let
toOption fmt@DateTimeFormat{..} = do
- dateTime <- formatTime' unDateTimeFormat now
+ dateTime <- formatTime' unDateTimeFormat now
return (dateTime, fmt)
-
- optionsPairs <=< mapM toOption . Set.toList $ validDateTimeFormats tl sel
+
+ optionsPairs <=< mapM toOption . Set.toList $ validDateTimeFormats tl sel
addOneWeek :: UTCTime -> UTCTime
-addOneWeek = addUTCTime (7 * nominalDay)
+addOneWeek = addWeeks 1
--- addOneTerm? -> Move Handler.Utils.DateTime
+addWeeks :: Integer -> UTCTime -> UTCTime
+addWeeks n utct = utct { utctDay = newDay }
+ where
+ oldDay = utctDay utct
+ -- newDay = addGregorianDurationRollOver $ stimes n calendarWeek -- only available in newer version 1.9 of Data.Time.Calendar
+ newDay = addDays (7*n) oldDay
+weekDiff :: UTCTime -> UTCTime -> Integer
+-- ^ Difference between times, rounded down to weeks
+weekDiff old new = dayDiff `div` 7
+ where
+ dayOld = utctDay old
+ dayNew = utctDay new
+ dayDiff = diffDays dayNew dayOld
+
+weeksToAdd :: UTCTime -> UTCTime -> Integer
+-- ^ Number of weeks needed to add so that first
+-- time occurs later than second time
+-- (loop avoids off-by-one error with weekDiff corner cases)
+weeksToAdd old new = loop 0 old
+ where
+ loop n t
+ | t > new = n
+ | otherwise = loop (succ n) (addOneWeek t)
+
+
+setYear :: Integer -> Day -> Day
+setYear year date = fromGregorian year month day
+ where
+ (_,month,day) = toGregorian date
\ No newline at end of file
diff --git a/static/css/fonts.css b/static/css/fonts.css
index ae0be87be..785fe33d3 100644
--- a/static/css/fonts.css
+++ b/static/css/fonts.css
@@ -17,3 +17,113 @@
font-family:"Font Awesome 5 Free";
font-weight:900;
}
+
+@font-face {
+ font-family: 'Source Sans Pro';
+ font-style: normal;
+ font-weight: 300;
+ src:
+ local('Source Sans Pro Light'),
+ local('SourceSansPro-Light'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwlxdu.woff2 */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_300.woff2') format('woff2'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwlxdo.woff */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_300.woff') format('woff'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwlxdq.eot */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_300.eot?#iefix') format('embedded-opentype'),
+ /* from https://fonts.gstatic.com/l/font?kit=6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwlxdp&skey=e2b26fc7e9e1ade8&v=v11#SourceSansPro */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_300.svg#SourceSansPro') format('svg'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3ik4zwlxdr.ttf */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_300.ttf') format('truetype');
+}
+@font-face {
+ font-family: 'Source Sans Pro';
+ font-style: normal;
+ font-weight: 400;
+ src:
+ local('Source Sans Pro Regular'),
+ local('SourceSansPro-Regular'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2 */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_400.woff2') format('woff2'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7j.woff */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_400.woff') format('woff'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7h.eot */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_400.eot?#iefix') format('embedded-opentype'),
+ /* from https://fonts.gstatic.com/l/font?kit=6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7i&skey=1e026b1c27170b9b&v=v11#SourceSansPro */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_400.svg#SourceSansPro') format('svg'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7g.ttf */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_400.ttf') format('truetype');
+}
+@font-face {
+ font-family: 'Source Sans Pro';
+ font-style: normal;
+ font-weight: 600;
+ src:
+ local('Source Sans Pro SemiBold'),
+ local('SourceSansPro-SemiBold'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwlxdu.woff2 */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_600.woff2') format('woff2'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwlxdo.woff */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_600.woff') format('woff'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwlxdq.eot */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_600.eot?#iefix') format('embedded-opentype'),
+ /* from https://fonts.gstatic.com/l/font?kit=6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwlxdp&skey=227a890402fab339&v=v11#SourceSansPro */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_600.svg#SourceSansPro') format('svg'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3i54rwlxdr.ttf */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_600.ttf') format('truetype');
+}
+@font-face {
+ font-family: 'Source Sans Pro';
+ font-style: normal;
+ font-weight: 900;
+ src:
+ local('Source Sans Pro Black'),
+ local('SourceSansPro-Black'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwlxdu.woff2 */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_900.woff2') format('woff2'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwlxdo.woff */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_900.woff') format('woff'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwlxdq.eot */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_900.eot?#iefix') format('embedded-opentype'),
+ /* from https://fonts.gstatic.com/l/font?kit=6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwlxdp&skey=cf4dfcb31d72fb0a&v=v11#SourceSansPro */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_900.svg#SourceSansPro') format('svg'),
+ /* from https://fonts.gstatic.com/s/sourcesanspro/v11/6xKydSBYKcSV-LCoeQqfX1RYOo3iu4nwlxdr.ttf */
+ url('../fonts/sourcesanspro/Source_Sans_Pro_900.ttf') format('truetype');
+}
+
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 300;
+ src:
+ local('Roboto Light'),
+ local('Roboto-Light'),
+ /* from https://fonts.gstatic.com/s/roboto/v18/KFOlCnqEu92Fr1MmSU5fBBc4.woff2 */
+ url('../fonts/roboto/Roboto_300.woff2') format('woff2'),
+ /* from https://fonts.gstatic.com/s/roboto/v18/KFOlCnqEu92Fr1MmSU5fBBc-.woff */
+ url('../fonts/roboto/Roboto_300.woff') format('woff'),
+ /* from https://fonts.gstatic.com/s/roboto/v18/KFOlCnqEu92Fr1MmSU5fBBc8.eot */
+ url('../fonts/roboto/Roboto_300.eot?#iefix') format('embedded-opentype'),
+ /* from https://fonts.gstatic.com/l/font?kit=KFOlCnqEu92Fr1MmSU5fBBc_&skey=11ce8ad5f54705ca&v=v18#Roboto */
+ url('../fonts/roboto/Roboto_300.svg#Roboto') format('svg'),
+ /* from https://fonts.gstatic.com/s/roboto/v18/KFOlCnqEu92Fr1MmSU5fBBc9.ttf */
+ url('../fonts/roboto/Roboto_300.ttf') format('truetype');
+}
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ src:
+ local('Roboto'),
+ local('Roboto-Regular'),
+ /* from https://fonts.gstatic.com/s/roboto/v18/KFOmCnqEu92Fr1Mu4mxK.woff2 */
+ url('../fonts/roboto/Roboto_400.woff2') format('woff2'),
+ /* from https://fonts.gstatic.com/s/roboto/v18/KFOmCnqEu92Fr1Mu4mxM.woff */
+ url('../fonts/roboto/Roboto_400.woff') format('woff'),
+ /* from https://fonts.gstatic.com/s/roboto/v18/KFOmCnqEu92Fr1Mu4mxO.eot */
+ url('../fonts/roboto/Roboto_400.eot?#iefix') format('embedded-opentype'),
+ /* from https://fonts.gstatic.com/l/font?kit=KFOmCnqEu92Fr1Mu4mxN&skey=a0a0114a1dcab3ac&v=v18#Roboto */
+ url('../fonts/roboto/Roboto_400.svg#Roboto') format('svg'),
+ /* from https://fonts.gstatic.com/s/roboto/v18/KFOmCnqEu92Fr1Mu4mxP.ttf */
+ url('../fonts/roboto/Roboto_400.ttf') format('truetype');
+}
diff --git a/static/fonts/roboto/Roboto_300.eot b/static/fonts/roboto/Roboto_300.eot
new file mode 100644
index 000000000..17b7d5cd2
Binary files /dev/null and b/static/fonts/roboto/Roboto_300.eot differ
diff --git a/static/fonts/roboto/Roboto_300.svg b/static/fonts/roboto/Roboto_300.svg
new file mode 100644
index 000000000..4ded944a8
--- /dev/null
+++ b/static/fonts/roboto/Roboto_300.svg
@@ -0,0 +1,312 @@
+
+
+
diff --git a/static/fonts/roboto/Roboto_300.ttf b/static/fonts/roboto/Roboto_300.ttf
new file mode 100644
index 000000000..a22188eed
Binary files /dev/null and b/static/fonts/roboto/Roboto_300.ttf differ
diff --git a/static/fonts/roboto/Roboto_300.woff b/static/fonts/roboto/Roboto_300.woff
new file mode 100644
index 000000000..96663f072
Binary files /dev/null and b/static/fonts/roboto/Roboto_300.woff differ
diff --git a/static/fonts/roboto/Roboto_300.woff2 b/static/fonts/roboto/Roboto_300.woff2
new file mode 100644
index 000000000..52c5845a7
Binary files /dev/null and b/static/fonts/roboto/Roboto_300.woff2 differ
diff --git a/static/fonts/roboto/Roboto_400.eot b/static/fonts/roboto/Roboto_400.eot
new file mode 100644
index 000000000..a0780d6e3
Binary files /dev/null and b/static/fonts/roboto/Roboto_400.eot differ
diff --git a/static/fonts/roboto/Roboto_400.svg b/static/fonts/roboto/Roboto_400.svg
new file mode 100644
index 000000000..627f5a368
--- /dev/null
+++ b/static/fonts/roboto/Roboto_400.svg
@@ -0,0 +1,308 @@
+
+
+
diff --git a/static/fonts/roboto/Roboto_400.ttf b/static/fonts/roboto/Roboto_400.ttf
new file mode 100644
index 000000000..b91bf3f7e
Binary files /dev/null and b/static/fonts/roboto/Roboto_400.ttf differ
diff --git a/static/fonts/roboto/Roboto_400.woff b/static/fonts/roboto/Roboto_400.woff
new file mode 100644
index 000000000..92dfacc61
Binary files /dev/null and b/static/fonts/roboto/Roboto_400.woff differ
diff --git a/static/fonts/roboto/Roboto_400.woff2 b/static/fonts/roboto/Roboto_400.woff2
new file mode 100644
index 000000000..7e854e669
Binary files /dev/null and b/static/fonts/roboto/Roboto_400.woff2 differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_300.eot b/static/fonts/sourcesanspro/Source_Sans_Pro_300.eot
new file mode 100644
index 000000000..7092e737a
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_300.eot differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_300.svg b/static/fonts/sourcesanspro/Source_Sans_Pro_300.svg
new file mode 100644
index 000000000..806471c89
--- /dev/null
+++ b/static/fonts/sourcesanspro/Source_Sans_Pro_300.svg
@@ -0,0 +1,347 @@
+
+
+
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_300.ttf b/static/fonts/sourcesanspro/Source_Sans_Pro_300.ttf
new file mode 100644
index 000000000..f9f9a3a0b
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_300.ttf differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_300.woff b/static/fonts/sourcesanspro/Source_Sans_Pro_300.woff
new file mode 100644
index 000000000..7ceadfc81
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_300.woff differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_300.woff2 b/static/fonts/sourcesanspro/Source_Sans_Pro_300.woff2
new file mode 100644
index 000000000..bfb4050ba
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_300.woff2 differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_400.eot b/static/fonts/sourcesanspro/Source_Sans_Pro_400.eot
new file mode 100644
index 000000000..c5262239d
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_400.eot differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_400.svg b/static/fonts/sourcesanspro/Source_Sans_Pro_400.svg
new file mode 100644
index 000000000..64f90f599
--- /dev/null
+++ b/static/fonts/sourcesanspro/Source_Sans_Pro_400.svg
@@ -0,0 +1,344 @@
+
+
+
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_400.ttf b/static/fonts/sourcesanspro/Source_Sans_Pro_400.ttf
new file mode 100644
index 000000000..e1247aef6
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_400.ttf differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_400.woff b/static/fonts/sourcesanspro/Source_Sans_Pro_400.woff
new file mode 100644
index 000000000..16f51fff1
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_400.woff differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_400.woff2 b/static/fonts/sourcesanspro/Source_Sans_Pro_400.woff2
new file mode 100644
index 000000000..efa300c56
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_400.woff2 differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_600.eot b/static/fonts/sourcesanspro/Source_Sans_Pro_600.eot
new file mode 100644
index 000000000..46508d418
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_600.eot differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_600.svg b/static/fonts/sourcesanspro/Source_Sans_Pro_600.svg
new file mode 100644
index 000000000..3fda041c6
--- /dev/null
+++ b/static/fonts/sourcesanspro/Source_Sans_Pro_600.svg
@@ -0,0 +1,343 @@
+
+
+
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_600.ttf b/static/fonts/sourcesanspro/Source_Sans_Pro_600.ttf
new file mode 100644
index 000000000..8b7620ff1
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_600.ttf differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_600.woff b/static/fonts/sourcesanspro/Source_Sans_Pro_600.woff
new file mode 100644
index 000000000..3c6ce2ff3
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_600.woff differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_600.woff2 b/static/fonts/sourcesanspro/Source_Sans_Pro_600.woff2
new file mode 100644
index 000000000..e379beda7
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_600.woff2 differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_900.eot b/static/fonts/sourcesanspro/Source_Sans_Pro_900.eot
new file mode 100644
index 000000000..af91ce20d
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_900.eot differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_900.svg b/static/fonts/sourcesanspro/Source_Sans_Pro_900.svg
new file mode 100644
index 000000000..5911db3f9
--- /dev/null
+++ b/static/fonts/sourcesanspro/Source_Sans_Pro_900.svg
@@ -0,0 +1,346 @@
+
+
+
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_900.ttf b/static/fonts/sourcesanspro/Source_Sans_Pro_900.ttf
new file mode 100644
index 000000000..75257d047
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_900.ttf differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_900.woff b/static/fonts/sourcesanspro/Source_Sans_Pro_900.woff
new file mode 100644
index 000000000..de95d21bd
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_900.woff differ
diff --git a/static/fonts/sourcesanspro/Source_Sans_Pro_900.woff2 b/static/fonts/sourcesanspro/Source_Sans_Pro_900.woff2
new file mode 100644
index 000000000..36278e155
Binary files /dev/null and b/static/fonts/sourcesanspro/Source_Sans_Pro_900.woff2 differ