├── .gitignore ├── README.md ├── src ├── api │ ├── adminGroup.go │ ├── cookieGroup.go │ ├── handlers │ │ ├── adminhandlers.go │ │ ├── authenticationhandlers.go │ │ ├── cathandlers.go │ │ ├── cookiehandlers.go │ │ ├── doghandlers.go │ │ ├── generalhandlers.go │ │ ├── hamsterhandlers.go │ │ └── jwthandlers.go │ ├── jwtGroup.go │ ├── mainGroup.go │ └── middlewares │ │ ├── adminMiddlewares.go │ │ ├── cookieMiddlewares.go │ │ ├── jwtMiddlewares.go │ │ └── mainMiddlewares.go ├── main │ └── main.go ├── router │ └── router.go └── webserver │ └── webserver.go └── static ├── css ├── animate.css ├── preloader.css ├── responsive.css ├── simple-line-icons.css └── style.css ├── fonts ├── Simple-Line-Icons.dev.svg ├── Simple-Line-Icons.eot ├── Simple-Line-Icons.svg ├── Simple-Line-Icons.ttf └── Simple-Line-Icons.woff ├── img ├── after_effects.svg ├── amazon.png ├── apple-touch-icon-ipad-retina.png ├── apple-touch-icon-ipad.png ├── apple-touch-icon-iphone-retina.png ├── apple-touch-icon-iphone.png ├── bill.jpg ├── curb.png ├── dan.jpg ├── elance-odesk.png ├── eric.png ├── favicon.png ├── flash.svg ├── hero-img.png ├── icon.png ├── illustrator.svg ├── indesign.svg ├── payoneer.png ├── photoshop.svg ├── ramil.jpg ├── s1.png ├── s2.png ├── s3.png ├── s4.png ├── s5.png ├── s6.png ├── trianglify-background.svg └── user.png ├── index.html └── js ├── drifolio.js ├── jquery.easing.min.js ├── jquery.jribbble-1.0.1.ugly.js ├── jquery.nicescroll.min.js └── wow.min.js /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | pkg/ 3 | src/github.com/ 4 | src/golang.org/ 5 | .idea/ 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Golnag Server using Echo Tutorials Series - [Link](https://www.youtube.com/watch?v=_pww3NJuWnk&list=PLFmONUGpIk0YwlJMZOo21a9Q1juVrk4YY) 2 | Sources for [tutorial series on Youtube](https://www.youtube.com/watch?v=_pww3NJuWnk&list=PLFmONUGpIk0YwlJMZOo21a9Q1juVrk4YY) for creating a web server in Golang using the [Echo](https://github.com/labstack/echo) Package. 3 | 4 | ## Description 5 | The [Series](https://www.youtube.com/watch?v=_pww3NJuWnk&list=PLFmONUGpIk0YwlJMZOo21a9Q1juVrk4YY) will go through most of [Echo](https://github.com/labstack/echo) features like requests types, CRUD, playing with headers, cookies 6 | Middlewares and more. 7 | Starting from the very basic 'hello world' and finishing with a full production server ready for a real 8 | life app. 9 | 10 | ## Structure 11 | Each part have a video and a branch of the end state, each next part starts on top of the one before it. 12 | master is the last published part. 13 | 14 | ## Installation 15 | Clone the project: 16 | ``` 17 | git clone https://github.com/verybluebot/echo-server-tutorial.git 18 | ``` 19 | cd into it: 20 | ``` 21 | cd echo-server-tutorial 22 | ``` 23 | 24 | define `GOPATH`: 25 | note: this is asuming you are inside the root of the project. 26 | ``` 27 | echo GOPATH=`pwd` 28 | ``` 29 | 30 | build binaries: 31 | ``` 32 | go install main 33 | 34 | ``` 35 | 36 | run the server: 37 | 38 | ``` 39 | bin/main 40 | 41 | ``` 42 | 43 | Note: if you want to use anything other the `master` aka the last publish part, switch to 44 | its branch and build binaries. 45 | 46 | list all branches: 47 | ``` 48 | git branch -a 49 | ``` 50 | checkout to the branch you want and build/run like before: 51 | ``` 52 | git checkout part_1_hello_world 53 | 54 | go install main 55 | 56 | bin/main 57 | ``` 58 | 59 | -------------------------------------------------------------------------------- /src/api/adminGroup.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "github.com/labstack/echo" 5 | "api/handlers" 6 | ) 7 | 8 | func AdminGroup(g *echo.Group) { 9 | g.GET("/main", handlers.MainAdmin) 10 | } 11 | -------------------------------------------------------------------------------- /src/api/cookieGroup.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "api/handlers" 5 | 6 | "github.com/labstack/echo" 7 | ) 8 | 9 | func CookieGroup(g *echo.Group) { 10 | g.GET("/main", handlers.MainCookie) 11 | } 12 | -------------------------------------------------------------------------------- /src/api/handlers/adminhandlers.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/labstack/echo" 7 | ) 8 | 9 | func MainAdmin(c echo.Context) error { 10 | return c.String(http.StatusOK, "horay you are on the secret amdin main page!") 11 | } 12 | -------------------------------------------------------------------------------- /src/api/handlers/authenticationhandlers.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | "time" 7 | 8 | "github.com/dgrijalva/jwt-go" 9 | "github.com/labstack/echo" 10 | ) 11 | 12 | type JwtClaims struct { 13 | Name string `json:"name"` 14 | jwt.StandardClaims 15 | } 16 | 17 | func Login(c echo.Context) error { 18 | username := c.QueryParam("username") 19 | password := c.QueryParam("password") 20 | 21 | // check username and password against DB after hashing the password 22 | if username == "jack" && password == "1234" { 23 | cookie := &http.Cookie{} 24 | 25 | // this is the same 26 | //cookie := new(http.Cookie) 27 | 28 | cookie.Name = "sessionID" 29 | cookie.Value = "some_string" 30 | cookie.Expires = time.Now().Add(48 * time.Hour) 31 | 32 | c.SetCookie(cookie) 33 | 34 | // create jwt token 35 | token, err := createJwtToken() 36 | if err != nil { 37 | log.Println("Error Creating JWT token", err) 38 | return c.String(http.StatusInternalServerError, "something went wrong") 39 | } 40 | 41 | return c.JSON(http.StatusOK, map[string]string{ 42 | "message": "You were logged in!", 43 | "token": token, 44 | }) 45 | } 46 | 47 | return c.String(http.StatusUnauthorized, "Your username or password were wrong") 48 | } 49 | 50 | func createJwtToken() (string, error) { 51 | claims := JwtClaims{ 52 | "jack", 53 | jwt.StandardClaims{ 54 | Id: "main_user_id", 55 | ExpiresAt: time.Now().Add(24 * time.Hour).Unix(), 56 | }, 57 | } 58 | 59 | rawToken := jwt.NewWithClaims(jwt.SigningMethodHS512, claims) 60 | 61 | token, err := rawToken.SignedString([]byte("mySecret")) 62 | if err != nil { 63 | return "", err 64 | } 65 | 66 | return token, nil 67 | } 68 | -------------------------------------------------------------------------------- /src/api/handlers/cathandlers.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "net/http" 5 | "fmt" 6 | "log" 7 | "io/ioutil" 8 | "encoding/json" 9 | 10 | "github.com/labstack/echo" 11 | ) 12 | 13 | type Cat struct { 14 | Name string `json:"name"` 15 | Type string `json:"type"` 16 | } 17 | 18 | func GetCats(c echo.Context) error { 19 | catName := c.QueryParam("name") 20 | catType := c.QueryParam("type") 21 | 22 | dataType := c.Param("data") 23 | 24 | if dataType == "string" { 25 | return c.String(http.StatusOK, fmt.Sprintf("your cat name is: %s\nand his type is: %s\n", catName, catType)) 26 | } 27 | 28 | if dataType == "json" { 29 | return c.JSON(http.StatusOK, map[string]string{ 30 | "name": catName, 31 | "type": catType, 32 | }) 33 | } 34 | 35 | return c.JSON(http.StatusBadRequest, map[string]string{ 36 | "error": "you need to lets us know if you want json or string data", 37 | }) 38 | } 39 | 40 | func AddCat(c echo.Context) error { 41 | cat := Cat{} 42 | 43 | defer c.Request().Body.Close() 44 | 45 | b, err := ioutil.ReadAll(c.Request().Body) 46 | if err != nil { 47 | log.Printf("Failed reading the request body for addCats: %s\n", err) 48 | return c.String(http.StatusInternalServerError, "") 49 | } 50 | 51 | err = json.Unmarshal(b, &cat) 52 | if err != nil { 53 | log.Printf("Failed unmarshaling in addCats: %s\n", err) 54 | return c.String(http.StatusInternalServerError, "") 55 | } 56 | 57 | log.Printf("this is your cat: %#v\n", cat) 58 | return c.String(http.StatusOK, "we got your cat!") 59 | } -------------------------------------------------------------------------------- /src/api/handlers/cookiehandlers.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/labstack/echo" 7 | ) 8 | 9 | func MainCookie(c echo.Context) error { 10 | return c.String(http.StatusOK, "you are on the secret cookie page!") 11 | } -------------------------------------------------------------------------------- /src/api/handlers/doghandlers.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | "log" 7 | 8 | "github.com/labstack/echo" 9 | ) 10 | 11 | type Dog struct { 12 | Name string `json:"name"` 13 | Type string `json:"type"` 14 | } 15 | 16 | func AddDog(c echo.Context) error { 17 | dog := Dog{} 18 | 19 | defer c.Request().Body.Close() 20 | 21 | err := json.NewDecoder(c.Request().Body).Decode(&dog) 22 | if err != nil { 23 | log.Printf("Failed processing addDog request: %s\n", err) 24 | return echo.NewHTTPError(http.StatusInternalServerError) 25 | } 26 | 27 | log.Printf("this is your dog: %#v", dog) 28 | return c.String(http.StatusOK, "we got your dog!") 29 | } 30 | -------------------------------------------------------------------------------- /src/api/handlers/generalhandlers.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "github.com/labstack/echo" 5 | "net/http" 6 | ) 7 | 8 | func Yallo(c echo.Context) error { 9 | return c.String(http.StatusOK, "yallo from the web side!") 10 | } -------------------------------------------------------------------------------- /src/api/handlers/hamsterhandlers.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "log" 5 | "github.com/labstack/echo" 6 | "net/http" 7 | ) 8 | 9 | type Hamster struct { 10 | Name string `json:"name"` 11 | Type string `json:"type"` 12 | } 13 | 14 | func AddHamster(c echo.Context) error { 15 | hamster := Hamster{} 16 | 17 | err := c.Bind(&hamster) 18 | if err != nil { 19 | log.Printf("Failed processing addHamster request: %s\n", err) 20 | return echo.NewHTTPError(http.StatusInternalServerError) 21 | } 22 | 23 | log.Printf("this is your hamster: %#v", hamster) 24 | return c.String(http.StatusOK, "we got your hamster!") 25 | } -------------------------------------------------------------------------------- /src/api/handlers/jwthandlers.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "net/http" 5 | "log" 6 | 7 | "github.com/labstack/echo" 8 | "github.com/dgrijalva/jwt-go" 9 | ) 10 | 11 | func MainJwt(c echo.Context) error { 12 | user := c.Get("user") 13 | token := user.(*jwt.Token) 14 | 15 | claims := token.Claims.(jwt.MapClaims) 16 | 17 | log.Println("User Name: ", claims["name"], "User ID: ", claims["jti"]) 18 | 19 | return c.String(http.StatusOK, "you are on the top secret jwt page!") 20 | } -------------------------------------------------------------------------------- /src/api/jwtGroup.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "api/handlers" 5 | 6 | "github.com/labstack/echo" 7 | ) 8 | 9 | func JwtGroup(g *echo.Group) { 10 | g.GET("/main", handlers.MainJwt) 11 | } 12 | -------------------------------------------------------------------------------- /src/api/mainGroup.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "api/handlers" 5 | "github.com/labstack/echo" 6 | ) 7 | 8 | func MainGroup(e *echo.Echo) { 9 | e.GET("/login", handlers.Login) 10 | e.GET("/yallo", handlers.Yallo) 11 | e.GET("/cats/:data", handlers.GetCats) 12 | 13 | e.POST("/cats", handlers.AddCat) 14 | e.POST("/dogs", handlers.AddDog) 15 | e.POST("/hamsters", handlers.AddHamster) 16 | } 17 | -------------------------------------------------------------------------------- /src/api/middlewares/adminMiddlewares.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "github.com/labstack/echo" 5 | "github.com/labstack/echo/middleware" 6 | ) 7 | 8 | func SetAdminMiddlewares(g *echo.Group) { 9 | // this logs the webserver interaction 10 | g.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{ 11 | Format: `[${time_rfc3339}] ${status} ${method} ${host}${path} ${latency_human}` + "\n", 12 | })) 13 | 14 | g.Use(middleware.BasicAuth(func(username, password string, c echo.Context) (bool, error) { 15 | // check in the DB 16 | if username == "jack" && password == "1234" { 17 | return true, nil 18 | } 19 | 20 | return true, nil 21 | })) 22 | } 23 | -------------------------------------------------------------------------------- /src/api/middlewares/cookieMiddlewares.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "strings" 5 | "net/http" 6 | "log" 7 | 8 | "github.com/labstack/echo" 9 | ) 10 | 11 | func SetCookieMiddlewares(g *echo.Group) { 12 | g.Use(checkCookie) 13 | } 14 | 15 | func checkCookie(next echo.HandlerFunc) echo.HandlerFunc { 16 | return func(c echo.Context) error { 17 | cookie, err := c.Cookie("sessionID") 18 | if err != nil { 19 | if strings.Contains(err.Error(), "named cookie not present") { 20 | return c.String(http.StatusUnauthorized, "you dont have any cookie") 21 | } 22 | 23 | log.Println(err) 24 | return err 25 | } 26 | 27 | if cookie.Value == "some_string" { 28 | return next(c) 29 | } 30 | 31 | return c.String(http.StatusUnauthorized, "you dont have the right cookie, cookie") 32 | } 33 | } -------------------------------------------------------------------------------- /src/api/middlewares/jwtMiddlewares.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "github.com/labstack/echo" 5 | "github.com/labstack/echo/middleware" 6 | ) 7 | 8 | func SetJwtMiddlewares(g *echo.Group) { 9 | g.Use(middleware.JWTWithConfig(middleware.JWTConfig{ 10 | SigningMethod: "HS512", 11 | SigningKey: []byte("mySecret"), 12 | })) 13 | } -------------------------------------------------------------------------------- /src/api/middlewares/mainMiddlewares.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "github.com/labstack/echo" 5 | "github.com/labstack/echo/middleware" 6 | ) 7 | 8 | func SetMainMiddlewares(e *echo.Echo) { 9 | e.Use(middleware.StaticWithConfig(middleware.StaticConfig{ 10 | Root: "../static", 11 | })) 12 | 13 | e.Use(serverHeader) 14 | } 15 | 16 | func serverHeader(next echo.HandlerFunc) echo.HandlerFunc { 17 | return func(c echo.Context) error { 18 | c.Response().Header().Set(echo.HeaderServer, "BlueBot/1.0") 19 | c.Response().Header().Set("notReallyHeader", "thisHaveNoMeaning") 20 | 21 | return next(c) 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "router" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("Welcome to the webserver") 10 | e := router.New() 11 | 12 | e.Start(":8000") 13 | } 14 | -------------------------------------------------------------------------------- /src/router/router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "api/middlewares" 5 | "github.com/labstack/echo" 6 | "api" 7 | ) 8 | 9 | func New() *echo.Echo { 10 | e := echo.New() 11 | 12 | // create groups 13 | adminGroup := e.Group("/admin") 14 | cookieGroup := e.Group("/cookie") 15 | jwtGroup := e.Group("/jwt") 16 | 17 | // set all middlewares 18 | middlewares.SetMainMiddlewares(e) 19 | middlewares.SetAdminMiddlewares(adminGroup) 20 | middlewares.SetCookieMiddlewares(cookieGroup) 21 | middlewares.SetJwtMiddlewares(jwtGroup) 22 | 23 | // set main routes 24 | api.MainGroup(e) 25 | 26 | // set group routes 27 | api.AdminGroup(adminGroup) 28 | api.CookieGroup(cookieGroup) 29 | api.JwtGroup(jwtGroup) 30 | 31 | return e 32 | } -------------------------------------------------------------------------------- /src/webserver/webserver.go: -------------------------------------------------------------------------------- 1 | package webserver 2 | 3 | import ( 4 | "sync" 5 | "router" 6 | "log" 7 | "github.com/labstack/echo" 8 | ) 9 | 10 | var initWebServer sync.Once 11 | var ws *WebServer 12 | 13 | type WebServer struct { 14 | router *echo.Echo 15 | } 16 | 17 | func Instance() *WebServer { 18 | initWebServer.Do(func() { 19 | ws = &WebServer{} 20 | ws.router = router.New() 21 | }) 22 | 23 | return ws 24 | } 25 | 26 | func (w *WebServer) Start() { 27 | // start the server 28 | 29 | var wg sync.WaitGroup 30 | 31 | wg.Add(1) 32 | go func() { 33 | defer wg.Done() 34 | log.Println("Start HTTP server on port :8000") 35 | log.Fatal(w.router.Start(":8000")) 36 | }() 37 | 38 | 39 | wg.Wait() 40 | } -------------------------------------------------------------------------------- /static/css/preloader.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | body { 3 | overflow: hidden; 4 | margin: auto; 5 | } 6 | 7 | /* Preloader */ 8 | #preloader { 9 | position: fixed; 10 | top: 0; 11 | left: 0; 12 | right: 0; 13 | bottom: 0; 14 | background-color: #363942; /* preloader background color */ 15 | z-index: 99; /* makes sure it stays on top */ 16 | } 17 | 18 | #status { 19 | color: #fff; 20 | font-size: 6em; 21 | text-align: center; 22 | position: absolute; 23 | width: 200px; 24 | height: 200px; 25 | left: 50%; /* centers the loading animation horizontally one the screen */ 26 | top: 55%; /* centers the loading animation vertically one the screen */ 27 | background-repeat: no-repeat; 28 | background-position: center; 29 | margin: -100px 0 0 -100px; /* is width and height divided by two */ 30 | } -------------------------------------------------------------------------------- /static/css/responsive.css: -------------------------------------------------------------------------------- 1 | /* Medium Devices, Desktops */ 2 | @media only screen and (max-width : 1024px) { 3 | /*HREO AREA */ 4 | #hero{max-height: 660px;} 5 | 6 | /* FEATURED CLIENTS SECTION*/ 7 | #clients img{height: 50px;} 8 | } 9 | 10 | /* Small Devices, Tablets */ 11 | @media only screen and (max-width : 980px) { 12 | 13 | /*HREO AREA */ 14 | #hero{height: 540px;} 15 | 16 | /*ABOUT SECTION*/ 17 | #about{padding-top: 40px;} 18 | 19 | /* FEATURED CLIENTS SECTION*/ 20 | #clients {text-align: center;} 21 | #clients img{height: 40px;} 22 | #clients ul{float: none;} 23 | #clients h4 {display: none;} 24 | 25 | /* PORTFOLIO SECTION */ 26 | #shotsByPlayerId li{width: 47%;} 27 | #shotsByPlayerId li:first-child{width: 97%;} 28 | 29 | .myphoto{text-align: center;} 30 | 31 | /*COLLUPSABLE NAVIGATION MENU*/ 32 | .navbar-header {float: none;} 33 | .navbar-left,.navbar-right {float: none !important;} 34 | .navbar-toggle {display: block;} 35 | .navbar-collapse.collapse {display: none!important;} 36 | .navbar-nav>li { 37 | float: none; 38 | padding-left: 30px; 39 | overflow: hidden; 40 | } 41 | .collapse.in{display:block !important;} 42 | } 43 | 44 | 45 | /* Mobile Devices */ 46 | @media only screen and (max-width : 640px) { 47 | 48 | h2 {font-size: 1.9em;} 49 | h3{font-size: 1.5em} 50 | h4{font-size: 1.1em;} 51 | 52 | 53 | .myphoto{display: none;} 54 | 55 | 56 | /*Hero area*/ 57 | #hero{height: 400px;} 58 | .herocontent{padding-top: 30px;} 59 | 60 | /*About section*/ 61 | #about{text-align: center;} 62 | 63 | /*Portfolio*/ 64 | #shotsByPlayerId li {width: 96%;} 65 | 66 | /*Footer*/ 67 | .footerlinks li{display: none;} 68 | } 69 | 70 | /* Smaller Mobile Devices */ 71 | @media only screen and (max-width : 480px) { 72 | #hero{height: 320px;} 73 | #clients {display: none;} 74 | .footersocial li{font-size: 1.5em} 75 | } 76 | 77 | /* Smallest Mobile Devices */ 78 | @media only screen and (max-width : 320px) { 79 | #hero{height: 480px;} 80 | .herocontent{padding-top: 100px; padding-bottom: 30px;} 81 | 82 | } 83 | 84 | 85 | -------------------------------------------------------------------------------- /static/css/simple-line-icons.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Simple-Line-Icons'; 3 | src:url('../fonts/Simple-Line-Icons.eot'); 4 | src:url('../fonts/Simple-Line-Icons.eot?#iefix') format('embedded-opentype'), 5 | url('../fonts/Simple-Line-Icons.woff') format('woff'), 6 | url('../fonts/Simple-Line-Icons.ttf') format('truetype'), 7 | url('../fonts/Simple-Line-Icons.svg#Simple-Line-Icons') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | /* Use the following CSS code if you want to use data attributes for inserting your icons */ 13 | [data-icon]:before { 14 | font-family: 'Simple-Line-Icons'; 15 | content: attr(data-icon); 16 | speak: none; 17 | font-weight: normal; 18 | font-variant: normal; 19 | text-transform: none; 20 | line-height: 1; 21 | -webkit-font-smoothing: antialiased; 22 | -moz-osx-font-smoothing: grayscale; 23 | } 24 | 25 | /* Use the following CSS code if you want to have a class per icon */ 26 | /* 27 | Instead of a list of all class selectors, 28 | you can use the generic selector below, but it's slower: 29 | [class*="icon-"] { 30 | */ 31 | .icon-user-female, .icon-user-follow, .icon-user-following, .icon-user-unfollow, .icon-trophy, .icon-screen-smartphone, .icon-screen-desktop, .icon-plane, .icon-notebook, .icon-moustache, .icon-mouse, .icon-magnet, .icon-energy, .icon-emoticon-smile, .icon-disc, .icon-cursor-move, .icon-crop, .icon-credit-card, .icon-chemistry, .icon-user, .icon-speedometer, .icon-social-youtube, .icon-social-twitter, .icon-social-tumblr, .icon-social-facebook, .icon-social-dropbox, .icon-social-dribbble, .icon-shield, .icon-screen-tablet, .icon-magic-wand, .icon-hourglass, .icon-graduation, .icon-ghost, .icon-game-controller, .icon-fire, .icon-eyeglasses, .icon-envelope-open, .icon-envelope-letter, .icon-bell, .icon-badge, .icon-anchor, .icon-wallet, .icon-vector, .icon-speech, .icon-puzzle, .icon-printer, .icon-present, .icon-playlist, .icon-pin, .icon-picture, .icon-map, .icon-layers, .icon-handbag, .icon-globe-alt, .icon-globe, .icon-frame, .icon-folder-alt, .icon-film, .icon-feed, .icon-earphones-alt, .icon-earphones, .icon-drop, .icon-drawer, .icon-docs, .icon-directions, .icon-direction, .icon-diamond, .icon-cup, .icon-compass, .icon-call-out, .icon-call-in, .icon-call-end, .icon-calculator, .icon-bubbles, .icon-briefcase, .icon-book-open, .icon-basket-loaded, .icon-basket, .icon-bag, .icon-action-undo, .icon-action-redo, .icon-wrench, .icon-umbrella, .icon-trash, .icon-tag, .icon-support, .icon-size-fullscreen, .icon-size-actual, .icon-shuffle, .icon-share-alt, .icon-share, .icon-rocket, .icon-question, .icon-pie-chart, .icon-pencil, .icon-note, .icon-music-tone-alt, .icon-music-tone, .icon-microphone, .icon-loop, .icon-logout, .icon-login, .icon-list, .icon-like, .icon-home, .icon-grid, .icon-graph, .icon-equalizer, .icon-dislike, .icon-cursor, .icon-control-start, .icon-control-rewind, .icon-control-play, .icon-control-pause, .icon-control-forward, .icon-control-end, .icon-calendar, .icon-bulb, .icon-bar-chart, .icon-arrow-up, .icon-arrow-right, .icon-arrow-left, .icon-arrow-down, .icon-ban, .icon-bubble, .icon-camcorder, .icon-camera, .icon-check, .icon-clock, .icon-close, .icon-cloud-download, .icon-cloud-upload, .icon-doc, .icon-envelope, .icon-eye, .icon-flag, .icon-folder, .icon-heart, .icon-info, .icon-key, .icon-link, .icon-lock, .icon-lock-open, .icon-magnifier, .icon-magnifier-add, .icon-magnifier-remove, .icon-paper-clip, .icon-paper-plane, .icon-plus, .icon-pointer, .icon-power, .icon-refresh, .icon-reload, .icon-settings, .icon-star, .icon-symbol-female, .icon-symbol-male, .icon-target, .icon-volume-1, .icon-volume-2, .icon-volume-off, .icon-users { 32 | font-family: 'Simple-Line-Icons'; 33 | speak: none; 34 | font-style: normal; 35 | font-weight: normal; 36 | font-variant: normal; 37 | text-transform: none; 38 | line-height: 1; 39 | -webkit-font-smoothing: antialiased; 40 | } 41 | .icon-user-female:before { 42 | content: "\e000"; 43 | } 44 | .icon-user-follow:before { 45 | content: "\e002"; 46 | } 47 | .icon-user-following:before { 48 | content: "\e003"; 49 | } 50 | .icon-user-unfollow:before { 51 | content: "\e004"; 52 | } 53 | .icon-trophy:before { 54 | content: "\e006"; 55 | } 56 | .icon-screen-smartphone:before { 57 | content: "\e010"; 58 | } 59 | .icon-screen-desktop:before { 60 | content: "\e011"; 61 | } 62 | .icon-plane:before { 63 | content: "\e012"; 64 | } 65 | .icon-notebook:before { 66 | content: "\e013"; 67 | } 68 | .icon-moustache:before { 69 | content: "\e014"; 70 | } 71 | .icon-mouse:before { 72 | content: "\e015"; 73 | } 74 | .icon-magnet:before { 75 | content: "\e016"; 76 | } 77 | .icon-energy:before { 78 | content: "\e020"; 79 | } 80 | .icon-emoticon-smile:before { 81 | content: "\e021"; 82 | } 83 | .icon-disc:before { 84 | content: "\e022"; 85 | } 86 | .icon-cursor-move:before { 87 | content: "\e023"; 88 | } 89 | .icon-crop:before { 90 | content: "\e024"; 91 | } 92 | .icon-credit-card:before { 93 | content: "\e025"; 94 | } 95 | .icon-chemistry:before { 96 | content: "\e026"; 97 | } 98 | .icon-user:before { 99 | content: "\e005"; 100 | } 101 | .icon-speedometer:before { 102 | content: "\e007"; 103 | } 104 | .icon-social-youtube:before { 105 | content: "\e008"; 106 | } 107 | .icon-social-twitter:before { 108 | content: "\e009"; 109 | } 110 | .icon-social-tumblr:before { 111 | content: "\e00a"; 112 | } 113 | .icon-social-facebook:before { 114 | content: "\e00b"; 115 | } 116 | .icon-social-dropbox:before { 117 | content: "\e00c"; 118 | } 119 | .icon-social-dribbble:before { 120 | content: "\e00d"; 121 | } 122 | .icon-shield:before { 123 | content: "\e00e"; 124 | } 125 | .icon-screen-tablet:before { 126 | content: "\e00f"; 127 | } 128 | .icon-magic-wand:before { 129 | content: "\e017"; 130 | } 131 | .icon-hourglass:before { 132 | content: "\e018"; 133 | } 134 | .icon-graduation:before { 135 | content: "\e019"; 136 | } 137 | .icon-ghost:before { 138 | content: "\e01a"; 139 | } 140 | .icon-game-controller:before { 141 | content: "\e01b"; 142 | } 143 | .icon-fire:before { 144 | content: "\e01c"; 145 | } 146 | .icon-eyeglasses:before { 147 | content: "\e01d"; 148 | } 149 | .icon-envelope-open:before { 150 | content: "\e01e"; 151 | } 152 | .icon-envelope-letter:before { 153 | content: "\e01f"; 154 | } 155 | .icon-bell:before { 156 | content: "\e027"; 157 | } 158 | .icon-badge:before { 159 | content: "\e028"; 160 | } 161 | .icon-anchor:before { 162 | content: "\e029"; 163 | } 164 | .icon-wallet:before { 165 | content: "\e02a"; 166 | } 167 | .icon-vector:before { 168 | content: "\e02b"; 169 | } 170 | .icon-speech:before { 171 | content: "\e02c"; 172 | } 173 | .icon-puzzle:before { 174 | content: "\e02d"; 175 | } 176 | .icon-printer:before { 177 | content: "\e02e"; 178 | } 179 | .icon-present:before { 180 | content: "\e02f"; 181 | } 182 | .icon-playlist:before { 183 | content: "\e030"; 184 | } 185 | .icon-pin:before { 186 | content: "\e031"; 187 | } 188 | .icon-picture:before { 189 | content: "\e032"; 190 | } 191 | .icon-map:before { 192 | content: "\e033"; 193 | } 194 | .icon-layers:before { 195 | content: "\e034"; 196 | } 197 | .icon-handbag:before { 198 | content: "\e035"; 199 | } 200 | .icon-globe-alt:before { 201 | content: "\e036"; 202 | } 203 | .icon-globe:before { 204 | content: "\e037"; 205 | } 206 | .icon-frame:before { 207 | content: "\e038"; 208 | } 209 | .icon-folder-alt:before { 210 | content: "\e039"; 211 | } 212 | .icon-film:before { 213 | content: "\e03a"; 214 | } 215 | .icon-feed:before { 216 | content: "\e03b"; 217 | } 218 | .icon-earphones-alt:before { 219 | content: "\e03c"; 220 | } 221 | .icon-earphones:before { 222 | content: "\e03d"; 223 | } 224 | .icon-drop:before { 225 | content: "\e03e"; 226 | } 227 | .icon-drawer:before { 228 | content: "\e03f"; 229 | } 230 | .icon-docs:before { 231 | content: "\e040"; 232 | } 233 | .icon-directions:before { 234 | content: "\e041"; 235 | } 236 | .icon-direction:before { 237 | content: "\e042"; 238 | } 239 | .icon-diamond:before { 240 | content: "\e043"; 241 | } 242 | .icon-cup:before { 243 | content: "\e044"; 244 | } 245 | .icon-compass:before { 246 | content: "\e045"; 247 | } 248 | .icon-call-out:before { 249 | content: "\e046"; 250 | } 251 | .icon-call-in:before { 252 | content: "\e047"; 253 | } 254 | .icon-call-end:before { 255 | content: "\e048"; 256 | } 257 | .icon-calculator:before { 258 | content: "\e049"; 259 | } 260 | .icon-bubbles:before { 261 | content: "\e04a"; 262 | } 263 | .icon-briefcase:before { 264 | content: "\e04b"; 265 | } 266 | .icon-book-open:before { 267 | content: "\e04c"; 268 | } 269 | .icon-basket-loaded:before { 270 | content: "\e04d"; 271 | } 272 | .icon-basket:before { 273 | content: "\e04e"; 274 | } 275 | .icon-bag:before { 276 | content: "\e04f"; 277 | } 278 | .icon-action-undo:before { 279 | content: "\e050"; 280 | } 281 | .icon-action-redo:before { 282 | content: "\e051"; 283 | } 284 | .icon-wrench:before { 285 | content: "\e052"; 286 | } 287 | .icon-umbrella:before { 288 | content: "\e053"; 289 | } 290 | .icon-trash:before { 291 | content: "\e054"; 292 | } 293 | .icon-tag:before { 294 | content: "\e055"; 295 | } 296 | .icon-support:before { 297 | content: "\e056"; 298 | } 299 | .icon-size-fullscreen:before { 300 | content: "\e057"; 301 | } 302 | .icon-size-actual:before { 303 | content: "\e058"; 304 | } 305 | .icon-shuffle:before { 306 | content: "\e059"; 307 | } 308 | .icon-share-alt:before { 309 | content: "\e05a"; 310 | } 311 | .icon-share:before { 312 | content: "\e05b"; 313 | } 314 | .icon-rocket:before { 315 | content: "\e05c"; 316 | } 317 | .icon-question:before { 318 | content: "\e05d"; 319 | } 320 | .icon-pie-chart:before { 321 | content: "\e05e"; 322 | } 323 | .icon-pencil:before { 324 | content: "\e05f"; 325 | } 326 | .icon-note:before { 327 | content: "\e060"; 328 | } 329 | .icon-music-tone-alt:before { 330 | content: "\e061"; 331 | } 332 | .icon-music-tone:before { 333 | content: "\e062"; 334 | } 335 | .icon-microphone:before { 336 | content: "\e063"; 337 | } 338 | .icon-loop:before { 339 | content: "\e064"; 340 | } 341 | .icon-logout:before { 342 | content: "\e065"; 343 | } 344 | .icon-login:before { 345 | content: "\e066"; 346 | } 347 | .icon-list:before { 348 | content: "\e067"; 349 | } 350 | .icon-like:before { 351 | content: "\e068"; 352 | } 353 | .icon-home:before { 354 | content: "\e069"; 355 | } 356 | .icon-grid:before { 357 | content: "\e06a"; 358 | } 359 | .icon-graph:before { 360 | content: "\e06b"; 361 | } 362 | .icon-equalizer:before { 363 | content: "\e06c"; 364 | } 365 | .icon-dislike:before { 366 | content: "\e06d"; 367 | } 368 | .icon-cursor:before { 369 | content: "\e06e"; 370 | } 371 | .icon-control-start:before { 372 | content: "\e06f"; 373 | } 374 | .icon-control-rewind:before { 375 | content: "\e070"; 376 | } 377 | .icon-control-play:before { 378 | content: "\e071"; 379 | } 380 | .icon-control-pause:before { 381 | content: "\e072"; 382 | } 383 | .icon-control-forward:before { 384 | content: "\e073"; 385 | } 386 | .icon-control-end:before { 387 | content: "\e074"; 388 | } 389 | .icon-calendar:before { 390 | content: "\e075"; 391 | } 392 | .icon-bulb:before { 393 | content: "\e076"; 394 | } 395 | .icon-bar-chart:before { 396 | content: "\e077"; 397 | } 398 | .icon-arrow-up:before { 399 | content: "\e078"; 400 | } 401 | .icon-arrow-right:before { 402 | content: "\e079"; 403 | } 404 | .icon-arrow-left:before { 405 | content: "\e07a"; 406 | } 407 | .icon-arrow-down:before { 408 | content: "\e07b"; 409 | } 410 | .icon-ban:before { 411 | content: "\e07c"; 412 | } 413 | .icon-bubble:before { 414 | content: "\e07d"; 415 | } 416 | .icon-camcorder:before { 417 | content: "\e07e"; 418 | } 419 | .icon-camera:before { 420 | content: "\e07f"; 421 | } 422 | .icon-check:before { 423 | content: "\e080"; 424 | } 425 | .icon-clock:before { 426 | content: "\e081"; 427 | } 428 | .icon-close:before { 429 | content: "\e082"; 430 | } 431 | .icon-cloud-download:before { 432 | content: "\e083"; 433 | } 434 | .icon-cloud-upload:before { 435 | content: "\e084"; 436 | } 437 | .icon-doc:before { 438 | content: "\e085"; 439 | } 440 | .icon-envelope:before { 441 | content: "\e086"; 442 | } 443 | .icon-eye:before { 444 | content: "\e087"; 445 | } 446 | .icon-flag:before { 447 | content: "\e088"; 448 | } 449 | .icon-folder:before { 450 | content: "\e089"; 451 | } 452 | .icon-heart:before { 453 | content: "\e08a"; 454 | } 455 | .icon-info:before { 456 | content: "\e08b"; 457 | } 458 | .icon-key:before { 459 | content: "\e08c"; 460 | } 461 | .icon-link:before { 462 | content: "\e08d"; 463 | } 464 | .icon-lock:before { 465 | content: "\e08e"; 466 | } 467 | .icon-lock-open:before { 468 | content: "\e08f"; 469 | } 470 | .icon-magnifier:before { 471 | content: "\e090"; 472 | } 473 | .icon-magnifier-add:before { 474 | content: "\e091"; 475 | } 476 | .icon-magnifier-remove:before { 477 | content: "\e092"; 478 | } 479 | .icon-paper-clip:before { 480 | content: "\e093"; 481 | } 482 | .icon-paper-plane:before { 483 | content: "\e094"; 484 | } 485 | .icon-plus:before { 486 | content: "\e095"; 487 | } 488 | .icon-pointer:before { 489 | content: "\e096"; 490 | } 491 | .icon-power:before { 492 | content: "\e097"; 493 | } 494 | .icon-refresh:before { 495 | content: "\e098"; 496 | } 497 | .icon-reload:before { 498 | content: "\e099"; 499 | } 500 | .icon-settings:before { 501 | content: "\e09a"; 502 | } 503 | .icon-star:before { 504 | content: "\e09b"; 505 | } 506 | .icon-symbol-female:before { 507 | content: "\e09c"; 508 | } 509 | .icon-symbol-male:before { 510 | content: "\e09d"; 511 | } 512 | .icon-target:before { 513 | content: "\e09e"; 514 | } 515 | .icon-volume-1:before { 516 | content: "\e09f"; 517 | } 518 | .icon-volume-2:before { 519 | content: "\e0a0"; 520 | } 521 | .icon-volume-off:before { 522 | content: "\e0a1"; 523 | } 524 | .icon-users:before { 525 | content: "\e001"; 526 | } -------------------------------------------------------------------------------- /static/css/style.css: -------------------------------------------------------------------------------- 1 | *{ -webkit-transition: .7s ease-out; 2 | -moz-transition: .7s ease-out; 3 | -o-transition: .7s ease-out; 4 | transition: .7s ease-out; 5 | list-style: none; 6 | } 7 | 8 | /*================================ 9 | TYPOGRAPHY 10 | ================================*/ 11 | body { 12 | font-family: 'Raleway', sans-serif; 13 | line-height: 1.8em; 14 | } 15 | 16 | .bigicon {font-size: 3em;} 17 | h2{font-size: 42px;} 18 | h3{font-size: 28px;} 19 | h4{font-size: 18px; line-height: 1.4em;} 20 | 21 | p{ 22 | letter-spacing: 1px; 23 | color: #c3c3c3; 24 | font-weight: lighter; 25 | } 26 | 27 | 28 | /*================================ 29 | DEFAULT STYLE & FORMATING 30 | ================================*/ 31 | ul{padding: 0;} 32 | a{color: #ea9312} 33 | a:hover{color: #c3c3c3; text-decoration: none;} 34 | 35 | #services{text-align: center;} 36 | .col-md-4, .col-md-6{padding-bottom: 50px;} 37 | .col-md-3 {padding: 0;} 38 | 39 | .sectionhead{ 40 | text-align: center; 41 | padding-top: 100px; 42 | padding-bottom: 50px; 43 | } 44 | 45 | hr.separetor{ 46 | width: 80px; 47 | color: #363942; 48 | border-top: 2px solid #ea9312; 49 | } 50 | 51 | 52 | .btn-default{ 53 | background: none; 54 | border: none; 55 | text-transform: uppercase; 56 | margin: 50px 0; 57 | color: #c3c3c3; 58 | letter-spacing: 2px; 59 | } 60 | 61 | .btn-default:hover{ 62 | background: none; 63 | color: #ea9312; 64 | } 65 | 66 | .btnicon, .brandicon{ 67 | margin-right: 10px; 68 | } 69 | 70 | 71 | /*================================ 72 | HERO AREA 73 | ================================*/ 74 | #hero{ 75 | color: #fff; 76 | text-align: center; 77 | background: url(../img/trianglify-background.svg)no-repeat; /*your background image*/ 78 | background-size: cover; 79 | max-height: 880px; 80 | overflow: hidden; 81 | } 82 | 83 | .herocontent{ 84 | padding-top: 100px; 85 | width: 100%; 86 | max-width: 900px; 87 | } 88 | .heroshot{ 89 | margin-top: 20px; 90 | width: 100%; 91 | max-width: 1200px; 92 | 93 | } 94 | 95 | /*================================ 96 | CLIENTS SECTION 97 | ================================*/ 98 | #clients{ 99 | padding-top: 30px; 100 | } 101 | #clients h4{ 102 | text-transooteorm: uppercase; 103 | padding-top: 10px; 104 | } 105 | 106 | #clients .col-md-4{ 107 | padding-bottom: 0; 108 | } 109 | 110 | #clients ul{float: right} 111 | 112 | #clients li{ 113 | display: inline; 114 | margin-right: 35px; 115 | } 116 | 117 | #clients li:last-child{ 118 | margin-right: 0px; 119 | } 120 | 121 | 122 | /*================================ 123 | ABOUT SECTION 124 | ================================*/ 125 | #about{padding-top: 100px;} 126 | 127 | .myapps{margin-top: 25px;} 128 | .myapps li{display: inline} 129 | .myapps li img{ 130 | width: 30px; 131 | } 132 | 133 | /*================================ 134 | PORTFOLIO SECTION 135 | ================================*/ 136 | #portfolio{ 137 | background: #efefef; 138 | margin-top: 50px; 139 | padding: 30px 0; 140 | text-align: center; 141 | } 142 | 143 | #shotsByPlayerId li{ 144 | width: 31%; 145 | float: left; 146 | padding: 15px; 147 | margin: 10px; 148 | background: #fff; 149 | border-radius: 5px; 150 | } 151 | 152 | #shotsByPlayerId li:hover{ 153 | box-shadow: 1px 2px 25px rgba(160, 160, 160, 0.4); 154 | -webkit-transition: .7s ease-out; 155 | -moz-transition: .7s ease-out; 156 | -o-transition: .7s ease-out; 157 | transition: .7s ease-out; 158 | } 159 | 160 | #shotsByPlayerId li img{ 161 | width: 100%; 162 | border-radius: 5px; 163 | } 164 | 165 | #shotsByPlayerId img:hover{ 166 | opacity: .5; 167 | overflow: hidden; 168 | } 169 | 170 | #shotsByPlayerId a:hover{color: #ea9312;} 171 | 172 | #shotsByPlayerId h3{ 173 | text-align: left; 174 | font-size: 14px; 175 | letter-spacing: 1px; 176 | text-transform: uppercase; 177 | font-weight: normal; 178 | white-space: nowrap; 179 | width: 100%; 180 | overflow: hidden; 181 | text-overflow: ellipsis;} 182 | 183 | #shotsByPlayerId h3 a{color: #363942;} 184 | 185 | .likecount a{float: left; color: #c3c3c3;} 186 | .commentcount a{float: right; color: #c3c3c3;} 187 | 188 | /*================================ 189 | TESTIMONIAL SECTION 190 | ================================*/ 191 | 192 | .clientsphoto img{ 193 | width: 80px; 194 | float: left; 195 | margin-right: 20px; 196 | border-radius: 50%; 197 | } 198 | 199 | .clientsphoto img:hover{ 200 | border-radius: 15%; 201 | } 202 | 203 | blockquote{ 204 | margin: 0; 205 | padding: 0 0 10px 0; 206 | border: none; 207 | } 208 | 209 | blockquote p{ 210 | font-style: italic; 211 | font-size: 14px; 212 | } 213 | 214 | .quote{overflow: hidden} 215 | .quote h5{margin-bottom: 5px;} 216 | 217 | 218 | /*================================ 219 | FOOTER SECTION 220 | ================================*/ 221 | 222 | footer{ 223 | text-align: center; 224 | padding: 50px 0; 225 | background: #363942; 226 | } 227 | 228 | footer p, footer .bigicon {color: #7e7e7e;} 229 | 230 | .footerlinks{margin: 30px 0;} 231 | .footerlinks li{ 232 | display: inline; 233 | padding: 10px; 234 | text-transform: uppercase; 235 | letter-spacing: 3px; 236 | } 237 | 238 | .footersocial {margin-top: 30px;} 239 | 240 | .footersocial li{ 241 | display:inline; 242 | padding: 0 15px; 243 | font-size: 2em; 244 | } 245 | 246 | .footersocial li a {color: #7e7e7e;} 247 | .footersocial li a:hover {color: #ea9312;} 248 | 249 | /*================================ 250 | FOLLOW BUTTON 251 | ================================*/ 252 | .dribbble-follow-button { 253 | display: inline-block; 254 | margin-top: 15px; 255 | } 256 | 257 | .dribbble-follow-button .label, .dribbble-follow-button .count { 258 | font: bold 11px/18px 'Helvetica Neue', Helvetica, Arial, sans-serif; 259 | color: #333; 260 | border: 1px solid #ccc; 261 | text-decoration: none; 262 | display: inline-block; 263 | position: relative; 264 | border-radius: 3px; 265 | } 266 | 267 | .dribbble-follow-button .label { 268 | padding: 0 3px 0 1px; 269 | white-space: nowrap; 270 | background: #e3e3e3; 271 | background: linear-gradient(top, white, #dedede); 272 | } 273 | 274 | .dribbble-follow-button .label i { 275 | height: 18px; 276 | width: 18px; 277 | float: left; 278 | background: url(../img/icon.png) no-repeat top left; 279 | } 280 | 281 | .dribbble-follow-button .label:hover { 282 | border-color: #bbb; 283 | background: #fff; 284 | color: #333; 285 | } 286 | 287 | .dribbble-follow-button .label:active { 288 | box-shadow: 0 1px 5px rgba(0,0,0,.15) inset; 289 | } 290 | 291 | .dribbble-follow-button .count { 292 | margin-left: 5px; 293 | padding: 0 3px; 294 | color: #333; 295 | border-color: #bbb; 296 | font-weight: normal; 297 | background: white; 298 | } 299 | 300 | .dribbble-follow-button .count:hover { 301 | text-decoration: underline; 302 | } 303 | 304 | .dribbble-follow-button .count > * { 305 | top: 50%; 306 | left: 0; 307 | margin: -4px 0 0 -4px; 308 | border: 4px solid transparent; 309 | border-right-color: #aaa; 310 | border-left: 0; 311 | position: absolute; 312 | } 313 | 314 | .dribbble-follow-button .count u { 315 | margin-left: -3px; 316 | border-right-color: white; 317 | } 318 | 319 | -------------------------------------------------------------------------------- /static/fonts/Simple-Line-Icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/fonts/Simple-Line-Icons.eot -------------------------------------------------------------------------------- /static/fonts/Simple-Line-Icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/fonts/Simple-Line-Icons.ttf -------------------------------------------------------------------------------- /static/fonts/Simple-Line-Icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/fonts/Simple-Line-Icons.woff -------------------------------------------------------------------------------- /static/img/after_effects.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/img/amazon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/amazon.png -------------------------------------------------------------------------------- /static/img/apple-touch-icon-ipad-retina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/apple-touch-icon-ipad-retina.png -------------------------------------------------------------------------------- /static/img/apple-touch-icon-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/apple-touch-icon-ipad.png -------------------------------------------------------------------------------- /static/img/apple-touch-icon-iphone-retina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/apple-touch-icon-iphone-retina.png -------------------------------------------------------------------------------- /static/img/apple-touch-icon-iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/apple-touch-icon-iphone.png -------------------------------------------------------------------------------- /static/img/bill.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/bill.jpg -------------------------------------------------------------------------------- /static/img/curb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/curb.png -------------------------------------------------------------------------------- /static/img/dan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/dan.jpg -------------------------------------------------------------------------------- /static/img/elance-odesk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/elance-odesk.png -------------------------------------------------------------------------------- /static/img/eric.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/eric.png -------------------------------------------------------------------------------- /static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/favicon.png -------------------------------------------------------------------------------- /static/img/flash.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/img/hero-img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/hero-img.png -------------------------------------------------------------------------------- /static/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/icon.png -------------------------------------------------------------------------------- /static/img/illustrator.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/img/indesign.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/img/payoneer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/payoneer.png -------------------------------------------------------------------------------- /static/img/photoshop.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/img/ramil.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/ramil.jpg -------------------------------------------------------------------------------- /static/img/s1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/s1.png -------------------------------------------------------------------------------- /static/img/s2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/s2.png -------------------------------------------------------------------------------- /static/img/s3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/s3.png -------------------------------------------------------------------------------- /static/img/s4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/s4.png -------------------------------------------------------------------------------- /static/img/s5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/s5.png -------------------------------------------------------------------------------- /static/img/s6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/s6.png -------------------------------------------------------------------------------- /static/img/trianglify-background.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/img/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/verybluebot/echo-server-tutorial/ef058839e06fe20dbc0597a7a548af9b9966c92e/static/img/user.png -------------------------------------------------------------------------------- /static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 14 | 15 | 20 | 21 | 24 |I'm gonna build me an airport, put my name on it. Why, Michael? So you can fly away from your feelings? I don't care if it takes from now till the end of Shrimpfest.
164 |Bugger bag egg's old boy willy jolly scrote munta skive pillock, bloody shambles nose rag blummin' scrote narky ever so, Lorem ipsum dolor sit amet, consectetur adipisicing elit.
165 | 166 | Follow 167 |Grinder affogato, dark, sweet carajillo, flavour seasonal aroma single origin cream. Percolator. Eligendi impedit dolores nulla.
210 |Grinder affogato, dark, sweet carajillo, flavour seasonal aroma single origin cream. Percolator. Eligendi impedit dolores nulla.
216 |Grinder affogato, dark, sweet carajillo, flavour seasonal aroma single origin cream. Percolator. Eligendi impedit dolores nulla.
222 |Grinder affogato, dark, sweet carajillo, flavour seasonal aroma single origin cream. Percolator. Eligendi impedit dolores nulla.
228 |Grinder affogato, dark, sweet carajillo, flavour seasonal aroma single origin cream. Percolator. Eligendi impedit dolores nulla.
234 |Grinder affogato, dark, sweet carajillo, flavour seasonal aroma single origin cream. Percolator. Eligendi impedit dolores nulla.
240 |287 |289 |Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia et pariatur ipsam tempora officia ea iusto expedita, nulla, hic odit saepe repellat nesciunt dolorum, officiis laborum ad, aliquam. Quos, et.
288 |
Co-Founder, Dribbble
291 |302 |304 |Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia et pariatur ipsam tempora officia ea iusto expedita, nulla, hic odit saepe repellat nesciunt dolorum, officiis laborum ad, aliquam. Quos, et. lorem
303 |
Art Director at Focus Lab LLC.
306 |317 |319 |Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia et pariatur ipsam tempora officia ea iusto expedita, nulla, hic odit saepe repellat nesciunt dolorum, officiis laborum ad, aliquam. Quos, et.
318 |
Principal Designer, JellyJar
321 |332 |334 |Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quia et pariatur ipsam tempora officia ea iusto expedita, nulla, hic odit saepe repellat nesciunt dolorum, officiis laborum ad, aliquam. Quos, et.
333 |
Visual Designer, Bluroon
336 |