├── .gitignore
├── test
├── avatar.jpg
└── singup.js
├── public
└── css
│ ├── themes
│ ├── basic
│ │ └── assets
│ │ │ └── fonts
│ │ │ ├── icons.eot
│ │ │ ├── icons.ttf
│ │ │ └── icons.woff
│ ├── default
│ │ └── assets
│ │ │ ├── fonts
│ │ │ ├── icons.eot
│ │ │ ├── icons.ttf
│ │ │ ├── icons.woff
│ │ │ └── icons.woff2
│ │ │ └── images
│ │ │ └── flags.png
│ ├── github
│ │ └── assets
│ │ │ └── fonts
│ │ │ ├── octicons.ttf
│ │ │ ├── octicons.woff
│ │ │ └── octicons-local.ttf
│ └── material
│ │ └── assets
│ │ └── fonts
│ │ ├── icons.eot
│ │ ├── icons.ttf
│ │ └── icons.woff
│ ├── floder.css
│ ├── components
│ ├── sticky.min.css
│ ├── tab.min.css
│ ├── breadcrumb.min.css
│ ├── nag.min.css
│ ├── rail.min.css
│ ├── sticky.css
│ ├── site.min.css
│ ├── embed.min.css
│ ├── container.min.css
│ ├── ad.min.css
│ ├── tab.css
│ ├── reset.min.css
│ ├── shape.min.css
│ ├── dimmer.min.css
│ ├── breadcrumb.css
│ ├── comment.min.css
│ ├── nag.css
│ ├── rail.css
│ ├── site.css
│ ├── feed.min.css
│ ├── image.min.css
│ ├── container.css
│ ├── embed.css
│ ├── shape.css
│ ├── loader.min.css
│ ├── dimmer.css
│ ├── ad.css
│ ├── rating.min.js
│ ├── reveal.min.css
│ ├── item.min.css
│ ├── nag.min.js
│ ├── divider.min.css
│ ├── search.min.css
│ ├── site.min.js
│ ├── comment.css
│ ├── modal.min.css
│ ├── message.min.css
│ ├── accordion.min.css
│ ├── image.css
│ ├── accordion.min.js
│ ├── feed.css
│ └── progress.min.css
│ └── style.css
├── views
├── 404.html
├── error.html
├── signin.html
├── create.html
├── components
│ ├── header.html
│ └── comments.html
├── edit.html
├── signup.html
├── posts.html
├── base.html
└── post.html
├── config
└── default.js
├── models
├── users.js
├── comments.js
└── posts.js
├── routes
├── signout.js
├── index.js
├── signin.js
├── signup.js
└── posts.js
├── README.md
├── middlewares
└── check.js
├── logger.js
├── template.js
├── package.json
├── package_back.json
├── lib
└── mongo.js
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | npm-debug.log
2 | node_modules
3 | coverage
4 |
--------------------------------------------------------------------------------
/test/avatar.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/995270418L/koa2-blog/HEAD/test/avatar.jpg
--------------------------------------------------------------------------------
/public/css/themes/basic/assets/fonts/icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/995270418L/koa2-blog/HEAD/public/css/themes/basic/assets/fonts/icons.eot
--------------------------------------------------------------------------------
/public/css/themes/basic/assets/fonts/icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/995270418L/koa2-blog/HEAD/public/css/themes/basic/assets/fonts/icons.ttf
--------------------------------------------------------------------------------
/public/css/themes/basic/assets/fonts/icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/995270418L/koa2-blog/HEAD/public/css/themes/basic/assets/fonts/icons.woff
--------------------------------------------------------------------------------
/public/css/themes/default/assets/fonts/icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/995270418L/koa2-blog/HEAD/public/css/themes/default/assets/fonts/icons.eot
--------------------------------------------------------------------------------
/public/css/themes/default/assets/fonts/icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/995270418L/koa2-blog/HEAD/public/css/themes/default/assets/fonts/icons.ttf
--------------------------------------------------------------------------------
/public/css/themes/default/assets/fonts/icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/995270418L/koa2-blog/HEAD/public/css/themes/default/assets/fonts/icons.woff
--------------------------------------------------------------------------------
/public/css/themes/default/assets/fonts/icons.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/995270418L/koa2-blog/HEAD/public/css/themes/default/assets/fonts/icons.woff2
--------------------------------------------------------------------------------
/public/css/themes/default/assets/images/flags.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/995270418L/koa2-blog/HEAD/public/css/themes/default/assets/images/flags.png
--------------------------------------------------------------------------------
/public/css/themes/github/assets/fonts/octicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/995270418L/koa2-blog/HEAD/public/css/themes/github/assets/fonts/octicons.ttf
--------------------------------------------------------------------------------
/public/css/themes/github/assets/fonts/octicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/995270418L/koa2-blog/HEAD/public/css/themes/github/assets/fonts/octicons.woff
--------------------------------------------------------------------------------
/public/css/themes/material/assets/fonts/icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/995270418L/koa2-blog/HEAD/public/css/themes/material/assets/fonts/icons.eot
--------------------------------------------------------------------------------
/public/css/themes/material/assets/fonts/icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/995270418L/koa2-blog/HEAD/public/css/themes/material/assets/fonts/icons.ttf
--------------------------------------------------------------------------------
/public/css/themes/material/assets/fonts/icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/995270418L/koa2-blog/HEAD/public/css/themes/material/assets/fonts/icons.woff
--------------------------------------------------------------------------------
/public/css/themes/github/assets/fonts/octicons-local.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/995270418L/koa2-blog/HEAD/public/css/themes/github/assets/fonts/octicons-local.ttf
--------------------------------------------------------------------------------
/views/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ title }}
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/views/error.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ title }}
6 |
7 |
8 |
9 | {{ error.message}}
10 | {{ error.stack }}
11 |
12 |
--------------------------------------------------------------------------------
/config/default.js:
--------------------------------------------------------------------------------
1 | let config = {
2 | port: 3000,
3 | mongodb: 'mongodb://127.0.0.1:27017/f_blog',
4 | redis_host:'127.0.0.1',
5 | redis_port: 6379,
6 | redis_db:0,
7 | redis_password:'',
8 | ENV : 'development',
9 | blog_title: 'Koa2-blog',
10 | blog_description: '让我们一起,为梦想窒息!'
11 | };
12 | module.exports = config;
13 |
--------------------------------------------------------------------------------
/models/users.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 用户模块(crud)
3 | */
4 | const User = require('../lib/mongo').User;
5 |
6 | module.exports = {
7 | create : function create(user){
8 | return User.create(user).exec();
9 | },
10 | getUserByName: function getUserByName(name){
11 | return User.findOne({name:name})
12 | .addCreatedAt() //自定义插件(通过_id生成时间戳)
13 | .exec();
14 | }
15 | };
16 |
17 |
--------------------------------------------------------------------------------
/routes/signout.js:
--------------------------------------------------------------------------------
1 | //处理所有以 '/signout' 开头的请求
2 | const koaRouter = require('koa-router');
3 | const checkLogin = require('../middlewares/check').checkLogin;
4 |
5 | const router = new koaRouter({
6 | prefix: '/signout'
7 | });
8 |
9 | //GET /signout 登出
10 | router.get('/',checkLogin,async (ctx,next) =>{
11 | //清空session信息
12 | ctx.session.user =null;
13 | ctx.flash('success','登出成功');
14 | ctx.redirect('/posts');
15 | });
16 |
17 | module.exports = router;
--------------------------------------------------------------------------------
/public/css/floder.css:
--------------------------------------------------------------------------------
1 | body,button,input,select,testarea{
2 | font-weight: 300;
3 | font-family:"Open Sans",Tahoma,arial,"Hiragino Sans GB","Hiragino Sans GB W3",STHeiti,"Microsoft YaHei",sans-serif
4 | }
5 |
6 | body{
7 | font-size: 18px;
8 | color: #222;
9 | }
10 |
11 |
12 | .page_header_bar{
13 | position: fixed;
14 | left:0;
15 | top:0;
16 | width:100%;
17 | height:60px;
18 | z-index: 100; //堆叠顺序,也就是离用户的距离
19 | transition: background 1s linear;
20 | background: rgba(255,255,255,.2);
21 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # koa2-blog
2 | 该项目基于node-v7.7.1,mongodb v3.4.2,redis 3.2.8构建而成,最主要的是node的版本一定要支持async/await语法,否则只能使用babel了。
3 |
4 | 项目本地使用:
5 | 1. 开启mongod服务:
6 |
7 | -> mongod --fork --logpath ~/data/log/mongodb.log --dbpath ~/data/db
8 | 2.开启redis-server
9 |
10 | -> redis-server &
11 | 3.运行项目:
12 |
13 | -> node index.js
14 | 项目使用[redis](https://redis.io/)做session管理,[Koa2](http://koajs.com/)做系统框架,[mondogb](https://www.mongodb.com/cn)做储存,flash做消息中间件。具体请看[源代码](https://github.com/995270418L/koa2-blog/),注释都写的非常清楚。大家不懂的多查查文档就可以了,也可以留言一同解决。
15 |
--------------------------------------------------------------------------------
/middlewares/check.js:
--------------------------------------------------------------------------------
1 |
2 | //给每个路由都使用这个middleware检查用户权限
3 |
4 | module.exports = {
5 | checkLogin : async (ctx,next) =>{
6 | if(!ctx.session.user){
7 | //将验证消息添加到redis message(flash-message)
8 | ctx.flash('error',"未登录");
9 | //请求重定向
10 | return ctx.redirect('/signin');
11 | }
12 | await next();
13 | },
14 | checkNotLogin: async (ctx,next)=>{
15 | if(ctx.session.user){
16 | ctx.flash('success',"已登录");
17 | return ctx.redirect('back'); //返回之前的页面
18 | }
19 | await next();
20 | }
21 | };
--------------------------------------------------------------------------------
/routes/index.js:
--------------------------------------------------------------------------------
1 | //获取所有路由
2 | const fs = require('fs');
3 | const path = require('path');
4 | const koaRouter = require('koa-router');
5 | const router = new koaRouter();
6 | //路由管理文件(处理一类请求)
7 | fs
8 | .readdirSync(__dirname)
9 | .filter(file => (file.indexOf('.') !==0) && (file.split('.').slice(-1)[0] === 'js') && file !== 'index.js')
10 | .forEach(file => {
11 | const route = require(path.join(__dirname,file));
12 | router.use(route.routes(),route.allowedMethods());
13 | });
14 |
15 | router.get('/', async (ctx,next) => {
16 | ctx.redirect('/posts');
17 | });
18 |
19 | module.exports = router;
--------------------------------------------------------------------------------
/public/css/components/sticky.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Sticky
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.sticky{position:static;-webkit-transition:none;transition:none;z-index:800}.ui.sticky.bound{position:absolute;left:auto;right:auto}.ui.sticky.fixed{position:fixed;left:auto;right:auto}.ui.sticky.bound.top,.ui.sticky.fixed.top{top:0;bottom:auto}.ui.sticky.bound.bottom,.ui.sticky.fixed.bottom{top:auto;bottom:0}.ui.native.sticky{position:-webkit-sticky;position:-moz-sticky;position:-ms-sticky;position:-o-sticky;position:sticky}
--------------------------------------------------------------------------------
/views/signin.html:
--------------------------------------------------------------------------------
1 | {% extends './components/header.html'%}{% block main %}
2 |
3 |
19 | {% endblock %}
--------------------------------------------------------------------------------
/logger.js:
--------------------------------------------------------------------------------
1 | //日志传输流
2 | const winston = require('winston');
3 |
4 | let successLogger = new (winston.Logger)({
5 | transports:[
6 | new winston.transports.Console({
7 | name:'console-success-log',
8 | level: 'info',
9 | json:true,
10 | colorize: true
11 | }),
12 | new (winston.transports.File)({
13 | name: 'file-info-log',
14 | filename: 'logs/success.log'
15 | })
16 | ]
17 | });
18 |
19 | let errorLogger = new (winston.Logger)({
20 | transport:[
21 | new winston.transports.Console({
22 | name: 'console-error-log',
23 | json: true,
24 | colorize: true
25 | }),
26 | new winston.transports.File({
27 | name: 'file-error-log',
28 | filename: 'logs/error.log'
29 | })
30 | ]
31 | });
32 |
33 | module.exports = {
34 | success : successLogger,
35 | error : errorLogger
36 | }
37 |
--------------------------------------------------------------------------------
/public/css/components/tab.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Tab
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.tab{display:none}.ui.tab.active,.ui.tab.open{display:block}.ui.tab.loading{position:relative;overflow:hidden;display:block;min-height:250px}.ui.tab.loading *{position:relative!important;left:-10000px!important}.ui.tab.loading.segment:before,.ui.tab.loading:before{position:absolute;content:'';top:100px;left:50%;margin:-1.25em 0 0 -1.25em;width:2.5em;height:2.5em;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.tab.loading.segment:after,.ui.tab.loading:after{position:absolute;content:'';top:100px;left:50%;margin:-1.25em 0 0 -1.25em;width:2.5em;height:2.5em;-webkit-animation:button-spin .6s linear;animation:button-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 transparent transparent;border-style:solid;border-width:.2em;box-shadow:0 0 0 1px transparent}
--------------------------------------------------------------------------------
/template.js:
--------------------------------------------------------------------------------
1 | //初始化nunjucks
2 | const views = require('koa-nunjucks-next');
3 | const config = require('./config/default');
4 |
5 | function template(path,opts){
6 | let autoescape = opts.autoescape || true; //是否编译输出
7 | let watch = opts.watch || false; //是否映射模板更改
8 | let noCache = opts.noCache || false; //默认需要缓存
9 | // let globals = opts.globals;
10 | // console.log(globals);
11 | return views(path,{
12 | autoescape:autoescape,
13 | watch:watch,
14 | noCache:noCache,
15 | globals :{
16 | blog_title: config.blog_title,
17 | blog_description : config.blog_description
18 | },
19 | filters: {
20 | asyncAdd: (val1, val2) => {
21 | return new Promise((resolve, reject) => {
22 | setTimeout(() => resolve(val1 + val2), 2000);
23 | });
24 | },
25 | syncAdd: (val1, val2) => {
26 | return val1 + val2;
27 | }
28 | }
29 | });
30 | };
31 |
32 | //输出整合好的模板
33 | module.exports = template;
34 |
35 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "f-blog",
3 | "version": "1.0.0",
4 | "description": "'floder's blog'",
5 | "main": "app.js",
6 | "scripts": {
7 | "test": "node --harmony ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha"
8 | },
9 | "author": "floder",
10 | "license": "ISC",
11 | "dependencies": {
12 | "koa": "^2.0.1-alpha.8",
13 | "koa-bodyparser": "^3.2.0",
14 | "koa-flash2": "0.0.2",
15 | "koa-generic-session": "^1.11.5",
16 | "koa-logger-winston": "0.0.2",
17 | "koa-multer": "^1.0.1",
18 | "koa-nunjucks-next": "^1.1.2",
19 | "koa-redis": "^2.1.3",
20 | "koa-router": "^7.0.1",
21 | "koa-session2": "^2.2.1",
22 | "koa-static": "^3.0.0",
23 | "markdown": "^0.5.0",
24 | "marked": "^0.3.6",
25 | "mocha": "^3.2.0",
26 | "moment": "^2.17.1",
27 | "mongolass": "^2.4.2",
28 | "objectid-to-timestamp": "^1.3.0",
29 | "redis": "^2.6.5",
30 | "semantic-ui": "^2.2.9",
31 | "supertest": "^3.0.0",
32 | "winston": "^2.3.1"
33 | },
34 | "devDependencies": {
35 | "istanbul": "^0.4.5"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/views/create.html:
--------------------------------------------------------------------------------
1 | {% extends './components/header.html' %}{% block main %}
2 |
3 |
23 |
24 |
25 |
29 | {% endblock %}
--------------------------------------------------------------------------------
/public/css/components/breadcrumb.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Breadcrumb
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.breadcrumb{line-height:1;display:inline-block;margin:0 0;vertical-align:middle}.ui.breadcrumb:first-child{margin-top:0}.ui.breadcrumb:last-child{margin-bottom:0}.ui.breadcrumb .divider{display:inline-block;opacity:.7;margin:0 .21428571rem 0;font-size:.92857143em;color:rgba(0,0,0,.4);vertical-align:baseline}.ui.breadcrumb a{color:#4183c4}.ui.breadcrumb a:hover{color:#1e70bf}.ui.breadcrumb .icon.divider{font-size:.85714286em;vertical-align:baseline}.ui.breadcrumb a.section{cursor:pointer}.ui.breadcrumb .section{display:inline-block;margin:0;padding:0}.ui.breadcrumb.segment{display:inline-block;padding:.78571429em 1em}.ui.breadcrumb .active.section{font-weight:700}.ui.mini.breadcrumb{font-size:.78571429rem}.ui.tiny.breadcrumb{font-size:.85714286rem}.ui.small.breadcrumb{font-size:.92857143rem}.ui.breadcrumb{font-size:1rem}.ui.large.breadcrumb{font-size:1.14285714rem}.ui.big.breadcrumb{font-size:1.28571429rem}.ui.huge.breadcrumb{font-size:1.42857143rem}.ui.massive.breadcrumb{font-size:1.71428571rem}
--------------------------------------------------------------------------------
/views/components/header.html:
--------------------------------------------------------------------------------
1 | {% extends '../base.html' %} {% block body %}
2 |
28 |
29 |
30 |
31 |
32 | {% if success %}
33 |
36 | {% elif error %}
37 |
40 | {% endif %}
41 |
42 |
43 | {% block main %}{% endblock %}
44 | {% endblock %}
--------------------------------------------------------------------------------
/views/edit.html:
--------------------------------------------------------------------------------
1 | {% extends './components/header.html' %}{% block main %}
2 |
25 |
26 |
27 |
31 | {% endblock %}
--------------------------------------------------------------------------------
/public/css/components/nag.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Nag
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.nag{display:none;opacity:.95;position:relative;top:0;left:0;z-index:999;min-height:0;width:100%;margin:0;padding:.75em 1em;background:#555;box-shadow:0 1px 2px 0 rgba(0,0,0,.2);font-size:1rem;text-align:center;color:rgba(0,0,0,.87);border-radius:0 0 .28571429rem .28571429rem;-webkit-transition:.2s background ease;transition:.2s background ease}a.ui.nag{cursor:pointer}.ui.nag>.title{display:inline-block;margin:0 .5em;color:#fff}.ui.nag>.close.icon{cursor:pointer;opacity:.4;position:absolute;top:50%;right:1em;font-size:1em;margin:-.5em 0 0;color:#fff;-webkit-transition:opacity .2s ease;transition:opacity .2s ease}.ui.nag:hover{background:#555;opacity:1}.ui.nag .close:hover{opacity:1}.ui.overlay.nag{position:absolute;display:block}.ui.fixed.nag{position:fixed}.ui.bottom.nag,.ui.bottom.nags{border-radius:.28571429rem .28571429rem 0 0;top:auto;bottom:0}.ui.inverted.nag,.ui.inverted.nags .nag{background-color:#f3f4f5;color:rgba(0,0,0,.85)}.ui.inverted.nag .close,.ui.inverted.nag .title,.ui.inverted.nags .nag .close,.ui.inverted.nags .nag .title{color:rgba(0,0,0,.4)}.ui.nags .nag{border-radius:0!important}.ui.nags .nag:last-child{border-radius:0 0 .28571429rem .28571429rem}.ui.bottom.nags .nag:last-child{border-radius:.28571429rem .28571429rem 0 0}
--------------------------------------------------------------------------------
/public/css/components/rail.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Rail
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.rail{position:absolute;top:0;width:300px;height:100%}.ui.left.rail{left:auto;right:100%;padding:0 2rem 0 0;margin:0 2rem 0 0}.ui.right.rail{left:100%;right:auto;padding:0 0 0 2rem;margin:0 0 0 2rem}.ui.left.internal.rail{left:0;right:auto;padding:0 0 0 2rem;margin:0 0 0 2rem}.ui.right.internal.rail{left:auto;right:0;padding:0 2rem 0 0;margin:0 2rem 0 0}.ui.dividing.rail{width:302.5px}.ui.left.dividing.rail{padding:0 2.5rem 0 0;margin:0 2.5rem 0 0;border-right:1px solid rgba(34,36,38,.15)}.ui.right.dividing.rail{border-left:1px solid rgba(34,36,38,.15);padding:0 0 0 2.5rem;margin:0 0 0 2.5rem}.ui.close.rail{width:calc(300px + 1em)}.ui.close.left.rail{padding:0 1em 0 0;margin:0 1em 0 0}.ui.close.right.rail{padding:0 0 0 1em;margin:0 0 0 1em}.ui.very.close.rail{width:calc(300px + .5em)}.ui.very.close.left.rail{padding:0 .5em 0 0;margin:0 .5em 0 0}.ui.very.close.right.rail{padding:0 0 0 .5em;margin:0 0 0 .5em}.ui.attached.left.rail,.ui.attached.right.rail{padding:0;margin:0}.ui.mini.rail{font-size:.78571429rem}.ui.tiny.rail{font-size:.85714286rem}.ui.small.rail{font-size:.92857143rem}.ui.rail{font-size:1rem}.ui.large.rail{font-size:1.14285714rem}.ui.big.rail{font-size:1.28571429rem}.ui.huge.rail{font-size:1.42857143rem}.ui.massive.rail{font-size:1.71428571rem}
--------------------------------------------------------------------------------
/views/signup.html:
--------------------------------------------------------------------------------
1 | {% extends './components/header.html'%} {% block main %}
2 |
38 | {% endblock %}
--------------------------------------------------------------------------------
/public/css/style.css:
--------------------------------------------------------------------------------
1 | /* -------------全局样式 ------------*/
2 |
3 | body{
4 | width:1100px;
5 | height:100%;
6 | margin: 0 auto;
7 | padding-top: 40px;
8 | }
9 |
10 | a:hover{
11 | border-bottom: 3px solid #4fc08d;
12 | }
13 |
14 | .button{
15 | background-color: #4fc08d !important;
16 | color: #fff !important;
17 | }
18 |
19 | .avatar {
20 | border-radius: 3px;
21 | width:48px;
22 | height:48px;
23 | float:right;
24 | }
25 |
26 | /* ------------- nav ----------- */
27 |
28 | .nav{
29 | margin-bottom: 20px;
30 | color: #999;
31 | text-align:center;
32 | }
33 |
34 | .nav h1{
35 | color: #4fc08d;
36 | display: inline-block;
37 | margin: 10px 0;
38 | }
39 |
40 | /* -----------nav-setting---------------- */
41 |
42 | .nav-setting{
43 | position:fixed;
44 | right:30px;
45 | }
46 |
47 | .nav-setting .ui.dropdown.button{
48 | padding:10px 10px 0 10px;
49 | background-color: #ffffff !important;
50 | }
51 |
52 | .nav-setting .icon.bars{
53 | color: #000000;
54 | font-size: 18px;
55 | }
56 |
57 | /* ------------- post-content ---------------- */
58 |
59 | .post-content h3 a{
60 | color: #4fc08d; !important;
61 | }
62 |
63 | .post-content .tag{
64 | font-size: 13px;
65 | margin-right: 5px;
66 | color: #999999;
67 | }
68 |
69 | .post-content .tag.right{
70 | float: right;
71 | margin-right: 0;
72 | }
73 |
74 | .post-content .tag-right a {
75 | color: #999999;
76 | }
77 |
78 | /* ---------------repeat ui------------------*/
79 |
80 | .ui.selection.dropdown {
81 | min-height:2.3em;
82 | }
--------------------------------------------------------------------------------
/views/posts.html:
--------------------------------------------------------------------------------
1 | {% extends './components/header.html' %}{% block main %}
2 | {% for item in posts%}
3 |
4 |
5 |
12 |
13 |
14 |
15 |
{{item.content | safe }}
16 |
17 |
{{ item.created_at}}
18 |
19 | 浏览{{item.pv}}
20 | 留言{{item.commentsCount}}
21 | {% if user %}
22 | {% if item.author._id %}
23 | {% if (user._id.toString() === item.author._id.toString())%}
24 |
32 | {% endif %}
33 | {% endif %}
34 | {% endif %}
35 |
36 |
37 |
38 |
39 |
40 |
41 | {% endfor%}
42 | {% endblock %}
--------------------------------------------------------------------------------
/package_back.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "f-blog",
3 | "version": "1.0.0",
4 | "description": "'floder's blog'",
5 | "main": "app.js",
6 | "scripts": {
7 | "test": "node --harmony ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha"
8 | },
9 | "author": "floder",
10 | "license": "ISC",
11 | "dependencies": {
12 | "koa": "^2.0.1-alpha.8",
13 | "koa-bodyparser": "^3.2.0", //解析post请求的文本数据
14 | "koa-flash2": "0.0.2", //往session里添加flash消息
15 | "koa-generic-session": "^1.11.5", //session依赖的一个包
16 | "koa-logger-winston": "0.0.2", //日志包
17 | "koa-multer": "^1.0.1", //解析post请求的文件
18 | "koa-nunjucks-next": "^1.1.2", //适用于koa的nunjucks模板
19 | "koa-redis": "^2.1.3", //将session保存在redis中的一个中间件
20 | "koa-router": "^7.0.1", //路由文件
21 | "koa-session2": "^2.2.1", //koa2的session文件
22 | "koa-static": "^3.0.0", //静态文件映射的middleware
23 | "markdown": "^0.5.0",
24 | "marked": "^0.3.6", //将markdown格式的文件转换成html
25 | "mocha": "^3.2.0", //mocha测试
26 | "moment": "^2.17.1", //日期格式化工具
27 | "mongolass": "^2.4.2", //操作mongodb的一个工具
28 | "objectid-to-timestamp": "^1.3.0", //从ObjectId中抽取时间
29 | "redis": "^2.6.5", //操作redis的工具
30 | "semantic-ui": "^2.2.9", //前端工具semantic-ui,也可以使用cdn地址
31 | "supertest": "^3.0.0", //和mocha整合测试
32 | "winston": "^2.3.1" //winston模板
33 | },
34 | "devDependencies": {
35 | "istanbul": "^0.4.5" //代码覆盖率工具
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/public/css/components/sticky.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Sticky
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 |
11 |
12 | /*******************************
13 | Sticky
14 | *******************************/
15 |
16 | .ui.sticky {
17 | position: static;
18 | -webkit-transition: none;
19 | transition: none;
20 | z-index: 800;
21 | }
22 |
23 |
24 | /*******************************
25 | States
26 | *******************************/
27 |
28 |
29 | /* Bound */
30 | .ui.sticky.bound {
31 | position: absolute;
32 | left: auto;
33 | right: auto;
34 | }
35 |
36 | /* Fixed */
37 | .ui.sticky.fixed {
38 | position: fixed;
39 | left: auto;
40 | right: auto;
41 | }
42 |
43 | /* Bound/Fixed Position */
44 | .ui.sticky.bound.top,
45 | .ui.sticky.fixed.top {
46 | top: 0px;
47 | bottom: auto;
48 | }
49 | .ui.sticky.bound.bottom,
50 | .ui.sticky.fixed.bottom {
51 | top: auto;
52 | bottom: 0px;
53 | }
54 |
55 |
56 | /*******************************
57 | Types
58 | *******************************/
59 |
60 | .ui.native.sticky {
61 | position: -webkit-sticky;
62 | position: -moz-sticky;
63 | position: -ms-sticky;
64 | position: -o-sticky;
65 | position: sticky;
66 | }
67 |
68 |
69 | /*******************************
70 | Theme Overrides
71 | *******************************/
72 |
73 |
74 |
75 | /*******************************
76 | Site Overrides
77 | *******************************/
78 |
79 |
--------------------------------------------------------------------------------
/routes/signin.js:
--------------------------------------------------------------------------------
1 | //处理所有登录开始的请求
2 |
3 | const koaRouter = require('koa-router');
4 | let checkNotLogin = require('../middlewares/check').checkNotLogin;
5 | const crypto = require('crypto');
6 | const userModel = require('../models/users');
7 |
8 | const router = new koaRouter({
9 | prefix: '/signin'
10 | });
11 |
12 | //验证密码
13 | function auth(plainPassword,encryPassword){
14 | let hash = crypto.createHash('sha256');
15 | hash.update(plainPassword);
16 | return hash.digest('hex') === encryPassword ;
17 | }
18 | //GET /signin 登录页
19 | router.get('/',checkNotLogin,async(ctx,next) => {
20 | await ctx.render('signin',{title: '用户登录'});
21 | });
22 |
23 | //POST /signin 用户登录
24 | router.post('/',checkNotLogin,async(ctx,next) => {
25 | let name = ctx.request.body.name;
26 | let password = ctx.request.body.password;
27 | console.log("name: " + name + " ; " + "password: " + password);
28 |
29 | //根据用户名从mongodb找寻用户
30 | let user = await userModel.getUserByName(name);
31 | if(!user){
32 | console.log('user not exist');
33 | ctx.flash('error','用户不存在');
34 | return ctx.redirect('back');
35 | }
36 | console.log('user exists');
37 |
38 | if(!auth(password,user.password)){
39 | console.log('username or password is not right');
40 | ctx.flash('error','用户名或者密码错误');
41 | return ctx.redirect('back');
42 | }
43 |
44 | ctx.flash('success','登录成功');
45 |
46 | user.password = null;
47 |
48 | ctx.session.user = user;
49 |
50 | ctx.redirect('/posts');
51 | });
52 |
53 | module.exports = router;
--------------------------------------------------------------------------------
/public/css/components/site.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Site
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic&subset=latin);body,html{height:100%}html{font-size:14px}body{margin:0;padding:0;overflow-x:hidden;min-width:320px;background:#fff;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:14px;line-height:1.4285em;color:rgba(0,0,0,.87);font-smoothing:antialiased}h1,h2,h3,h4,h5{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;line-height:1.28571429em;margin:calc(2rem - .14285714em) 0 1rem;font-weight:700;padding:0}h1{min-height:1rem;font-size:2rem}h2{font-size:1.71428571rem}h3{font-size:1.28571429rem}h4{font-size:1.07142857rem}h5{font-size:1rem}h1:first-child,h2:first-child,h3:first-child,h4:first-child,h5:first-child{margin-top:0}h1:last-child,h2:last-child,h3:last-child,h4:last-child,h5:last-child{margin-bottom:0}p{margin:0 0 1em;line-height:1.4285em}p:first-child{margin-top:0}p:last-child{margin-bottom:0}a{color:#4183c4;text-decoration:none}a:hover{color:#1e70bf;text-decoration:none}::-webkit-selection{background-color:#cce2ff;color:rgba(0,0,0,.87)}::-moz-selection{background-color:#cce2ff;color:rgba(0,0,0,.87)}::selection{background-color:#cce2ff;color:rgba(0,0,0,.87)}input::-webkit-selection,textarea::-webkit-selection{background-color:rgba(100,100,100,.4);color:rgba(0,0,0,.87)}input::-moz-selection,textarea::-moz-selection{background-color:rgba(100,100,100,.4);color:rgba(0,0,0,.87)}input::selection,textarea::selection{background-color:rgba(100,100,100,.4);color:rgba(0,0,0,.87)}
--------------------------------------------------------------------------------
/models/comments.js:
--------------------------------------------------------------------------------
1 | let marked = require('marked');
2 | let _Comment = require('../lib/mongo').Comment;
3 |
4 | //将comment的Content 从 markdown 转换成html
5 | _Comment.plugin('contentToHtml',{
6 | afterFind: function(comments){
7 | return comments.map(function(comment){
8 | comment.content = marked(comment.content);
9 | return comment;
10 | });
11 | },
12 | afterFindOne: function(comment){
13 | if(comment){
14 | comment.content = marked(comment.content);
15 | }
16 | return comment;
17 | }
18 | });
19 |
20 | module.exports = {
21 |
22 | //创建留言
23 | create : function create(comment){
24 | return _Comment
25 | .create(comment)
26 | .exec();
27 | },
28 |
29 | //通过用户id 和留言id 删除一个留言
30 | delCommentById : function delCommentById(commentId,author){
31 | return _Comment.remove({author:author,_id:commentId}).exec();
32 | },
33 |
34 | //通过文章id 删除该文章下所有留言
35 | delCommentsByPostId : function delCommentsByPostId(postId){
36 | return _Comment.remove({postId: postId}).exec();
37 | },
38 |
39 | //通过文章id 获取该文章下所有留言,按留言创建时间排序
40 | getComments : function getComments(postId){
41 | return _Comment.find({postId: postId})
42 | .populate({path:'author',model:'User'})
43 | .sort({_id: 1})
44 | .addCreatedAt()
45 | .contentToHtml()
46 | .exec();
47 | },
48 |
49 | //通过文章id获取该文章下留言数
50 | getCommentsCount: function getCommentsCount(postId){
51 | return _Comment.count({postId : postId}).exec();
52 | }
53 |
54 | }
--------------------------------------------------------------------------------
/views/components/comments.html:
--------------------------------------------------------------------------------
1 | {% extends '../post.html' %}{% block comment %}
2 |
47 | {% endblock %}
--------------------------------------------------------------------------------
/lib/mongo.js:
--------------------------------------------------------------------------------
1 | /**
2 | * mongo连接以及输出Schema模型
3 | */
4 |
5 | const config = require('../config/default');
6 | const Mongolass = require('mongolass');
7 | const moment = require('moment');
8 | const objectIdToTimestamp = require('objectid-to-timestamp');
9 | const mongolass = new Mongolass(config.mongodb);
10 |
11 | //根据id生成创建时间 created_at
12 | mongolass.plugin('addCreatedAt',{
13 | afterFind: function (results){
14 | results.forEach(item => item.created_at = moment(objectIdToTimestamp(item._id)).format('YYYY-MM-DD HH:mm'));
15 | return results;
16 | },
17 | afterFindOne: function(result){
18 | if(result){
19 | result.created_at = moment(objectIdToTimestamp(result._id)).format('YYYY-MM-DD HH:mm');
20 | }
21 | return result;
22 | }
23 | });
24 |
25 | let User = mongolass.model('user',{
26 | name: {type: 'string'},
27 | password: {type : 'string'},
28 | avatar: {type:'string'},
29 | gender:{type:'string',enum:['m','f','x']},
30 | bio:{type:'string'} //个人简介
31 | });
32 |
33 | User.index({name:1},{unique: true}).exec(); //name建立索引
34 |
35 | let Post = mongolass.model('Post',{
36 | author: {type: Mongolass.Types.ObjectId},
37 | title:{type: 'string'},
38 | content: {type: 'string'},
39 | pv: {type:'number'} //点击量
40 | });
41 |
42 | Post.index({author:-1,_id: -1}).exec(); //按创建时间降序查看用户文章列表
43 |
44 | let Comments = mongolass.model('Comment',{
45 | author: {type: Mongolass.Types.ObjectId},
46 | content: { type: 'string'},
47 | postId: {type: Mongolass.Types.ObjectId}
48 | });
49 |
50 | Comments.index({postId: 1, _id: 1}).exec(); //通过文章id 获取该文章下所有留言
51 | Comments.index({author: 1,_id: 1}).exec(); //通过用户id和留言id 删除一个留言
52 |
53 | module.exports = {
54 | User : User,
55 | Post : Post,
56 | Comment: Comments
57 | };
58 |
59 |
60 |
--------------------------------------------------------------------------------
/public/css/components/embed.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Video
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.embed{position:relative;max-width:100%;height:0;overflow:hidden;background:#dcddde;padding-bottom:56.25%}.ui.embed embed,.ui.embed iframe,.ui.embed object{position:absolute;border:none;width:100%;height:100%;top:0;left:0;margin:0;padding:0}.ui.embed>.embed{display:none}.ui.embed>.placeholder{position:absolute;cursor:pointer;top:0;left:0;display:block;width:100%;height:100%;background-color:radial-gradient(transparent 45%,rgba(0,0,0,.3))}.ui.embed>.icon{cursor:pointer;position:absolute;top:0;left:0;width:100%;height:100%;z-index:2}.ui.embed>.icon:after{position:absolute;top:0;left:0;width:100%;height:100%;z-index:3;content:'';background:-webkit-radial-gradient(transparent 45%,rgba(0,0,0,.3));background:radial-gradient(transparent 45%,rgba(0,0,0,.3));opacity:.5;-webkit-transition:opacity .5s ease;transition:opacity .5s ease}.ui.embed>.icon:before{position:absolute;top:50%;left:50%;z-index:4;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);color:#fff;font-size:6rem;text-shadow:0 2px 10px rgba(34,36,38,.2);-webkit-transition:opacity .5s ease,color .5s ease;transition:opacity .5s ease,color .5s ease;z-index:10}.ui.embed .icon:hover:after{background:-webkit-radial-gradient(transparent 45%,rgba(0,0,0,.3));background:radial-gradient(transparent 45%,rgba(0,0,0,.3));opacity:1}.ui.embed .icon:hover:before{color:#fff}.ui.active.embed>.icon,.ui.active.embed>.placeholder{display:none}.ui.active.embed>.embed{display:block}.ui.square.embed{padding-bottom:100%}.ui[class*="4:3"].embed{padding-bottom:75%}.ui[class*="16:9"].embed{padding-bottom:56.25%}.ui[class*="21:9"].embed{padding-bottom:42.85714286%}
--------------------------------------------------------------------------------
/public/css/components/container.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Container
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.container{display:block;max-width:100%!important}@media only screen and (max-width:767px){.ui.container{width:auto!important;margin-left:1em!important;margin-right:1em!important}.ui.grid.container{width:auto!important}.ui.relaxed.grid.container{width:auto!important}.ui.very.relaxed.grid.container{width:auto!important}}@media only screen and (min-width:768px) and (max-width:991px){.ui.container{width:723px;margin-left:auto!important;margin-right:auto!important}.ui.grid.container{width:calc(723px + 2rem)!important}.ui.relaxed.grid.container{width:calc(723px + 3rem)!important}.ui.very.relaxed.grid.container{width:calc(723px + 5rem)!important}}@media only screen and (min-width:992px) and (max-width:1199px){.ui.container{width:933px;margin-left:auto!important;margin-right:auto!important}.ui.grid.container{width:calc(933px + 2rem)!important}.ui.relaxed.grid.container{width:calc(933px + 3rem)!important}.ui.very.relaxed.grid.container{width:calc(933px + 5rem)!important}}@media only screen and (min-width:1200px){.ui.container{width:1127px;margin-left:auto!important;margin-right:auto!important}.ui.grid.container{width:calc(1127px + 2rem)!important}.ui.relaxed.grid.container{width:calc(1127px + 3rem)!important}.ui.very.relaxed.grid.container{width:calc(1127px + 5rem)!important}}.ui.text.container{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;max-width:700px!important;line-height:1.5}.ui.text.container{font-size:1.14285714rem}.ui.fluid.container{width:100%}.ui[class*="left aligned"].container{text-align:left}.ui[class*="center aligned"].container{text-align:center}.ui[class*="right aligned"].container{text-align:right}.ui.justified.container{text-align:justify;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}
--------------------------------------------------------------------------------
/public/css/components/ad.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Ad
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Copyright 2013 Contributors
7 | * Released under the MIT license
8 | * http://opensource.org/licenses/MIT
9 | *
10 | */.ui.ad{display:block;overflow:hidden;margin:1em 0}.ui.ad:first-child{margin:0}.ui.ad:last-child{margin:0}.ui.ad iframe{margin:0;padding:0;border:none;overflow:hidden}.ui.leaderboard.ad{width:728px;height:90px}.ui[class*="medium rectangle"].ad{width:300px;height:250px}.ui[class*="large rectangle"].ad{width:336px;height:280px}.ui[class*="half page"].ad{width:300px;height:600px}.ui.square.ad{width:250px;height:250px}.ui[class*="small square"].ad{width:200px;height:200px}.ui[class*="small rectangle"].ad{width:180px;height:150px}.ui[class*="vertical rectangle"].ad{width:240px;height:400px}.ui.button.ad{width:120px;height:90px}.ui[class*="square button"].ad{width:125px;height:125px}.ui[class*="small button"].ad{width:120px;height:60px}.ui.skyscraper.ad{width:120px;height:600px}.ui[class*="wide skyscraper"].ad{width:160px}.ui.banner.ad{width:468px;height:60px}.ui[class*="vertical banner"].ad{width:120px;height:240px}.ui[class*="top banner"].ad{width:930px;height:180px}.ui[class*="half banner"].ad{width:234px;height:60px}.ui[class*="large leaderboard"].ad{width:970px;height:90px}.ui.billboard.ad{width:970px;height:250px}.ui.panorama.ad{width:980px;height:120px}.ui.netboard.ad{width:580px;height:400px}.ui[class*="large mobile banner"].ad{width:320px;height:100px}.ui[class*="mobile leaderboard"].ad{width:320px;height:50px}.ui.mobile.ad{display:none}@media only screen and (max-width:767px){.ui.mobile.ad{display:block}}.ui.centered.ad{margin-left:auto;margin-right:auto}.ui.test.ad{position:relative;background:#545454}.ui.test.ad:after{position:absolute;top:50%;left:50%;width:100%;text-align:center;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);content:'Ad';color:#fff;font-size:1em;font-weight:700}.ui.mobile.test.ad:after{font-size:.85714286em}.ui.test.ad[data-text]:after{content:attr(data-text)}
--------------------------------------------------------------------------------
/public/css/components/tab.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Tab
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 |
11 |
12 | /*******************************
13 | UI Tabs
14 | *******************************/
15 |
16 | .ui.tab {
17 | display: none;
18 | }
19 |
20 |
21 | /*******************************
22 | States
23 | *******************************/
24 |
25 |
26 | /*--------------------
27 | Active
28 | ---------------------*/
29 |
30 | .ui.tab.active,
31 | .ui.tab.open {
32 | display: block;
33 | }
34 |
35 | /*--------------------
36 | Loading
37 | ---------------------*/
38 |
39 | .ui.tab.loading {
40 | position: relative;
41 | overflow: hidden;
42 | display: block;
43 | min-height: 250px;
44 | }
45 | .ui.tab.loading * {
46 | position: relative !important;
47 | left: -10000px !important;
48 | }
49 | .ui.tab.loading:before,
50 | .ui.tab.loading.segment:before {
51 | position: absolute;
52 | content: '';
53 | top: 100px;
54 | left: 50%;
55 | margin: -1.25em 0em 0em -1.25em;
56 | width: 2.5em;
57 | height: 2.5em;
58 | border-radius: 500rem;
59 | border: 0.2em solid rgba(0, 0, 0, 0.1);
60 | }
61 | .ui.tab.loading:after,
62 | .ui.tab.loading.segment:after {
63 | position: absolute;
64 | content: '';
65 | top: 100px;
66 | left: 50%;
67 | margin: -1.25em 0em 0em -1.25em;
68 | width: 2.5em;
69 | height: 2.5em;
70 | -webkit-animation: button-spin 0.6s linear;
71 | animation: button-spin 0.6s linear;
72 | -webkit-animation-iteration-count: infinite;
73 | animation-iteration-count: infinite;
74 | border-radius: 500rem;
75 | border-color: #767676 transparent transparent;
76 | border-style: solid;
77 | border-width: 0.2em;
78 | box-shadow: 0px 0px 0px 1px transparent;
79 | }
80 |
81 |
82 | /*******************************
83 | Tab Overrides
84 | *******************************/
85 |
86 |
87 |
88 | /*******************************
89 | User Overrides
90 | *******************************/
91 |
92 |
--------------------------------------------------------------------------------
/public/css/components/reset.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Reset
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */*,:after,:before{box-sizing:inherit}html{box-sizing:border-box}input[type=email],input[type=password],input[type=search],input[type=text]{-webkit-appearance:none;-moz-appearance:none}/*! normalize.css v3.0.1 | MIT License | git.io/normalize *//*! normalize.css v3.0.1 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | //程序的入口
2 | /**
3 | * module dependency
4 | */
5 | const path = require('path');
6 | const Koa = require('koa');
7 | const session = require('koa-generic-session');
8 | const redisStore = require('koa-redis');
9 | const flash = require('koa-flash2');
10 | const config = require('./config/default');
11 | const router = require('./routes');
12 | const server = require('koa-static');
13 | const redis = require('redis');
14 | const template = require('./template');
15 | const parse = require('koa-bodyparser');
16 | const logger = require('./logger');
17 | const koaLogger = require('koa-logger-winston');
18 | const isProduction = process.env.NODE_ENV === 'production';
19 | const app = new Koa();
20 |
21 | //设置静态文件目录
22 | app.use(server(__dirname + '/public'));
23 | //session中间件
24 | let client = redis.createClient(config.redis_port,config.redis_host);
25 | app.keys = ['keys','f_blog_keys'];
26 |
27 | app.use(session({
28 | store: redisStore({
29 | // db:config.redis_db,
30 | client : client
31 | })
32 | }));
33 |
34 | //flash中间件,用来显示通知
35 | app.use(flash());
36 |
37 | app.use(parse());
38 |
39 | console.log("isProduction: " + isProduction);
40 |
41 | //整合nunjucks
42 | app.use(template('views',{
43 | noCache : !isProduction,
44 | watch : !isProduction
45 | }));
46 |
47 | //添加模板所需的三个变量
48 | app.use(async (ctx,next) => {
49 |
50 | Object.assign(ctx.state,{
51 | user : ctx.session.user,
52 | success : ctx.flash('success').toString(),
53 | error : ctx.flash('error').toString()
54 | });
55 | await next();
56 | });
57 |
58 | //正常请求的日志
59 | app.use(koaLogger(logger.success));
60 |
61 | //路由
62 | app.use(router.routes());
63 |
64 | //错误日志
65 | app.use(koaLogger(logger.error));
66 |
67 | //处理404error
68 | app.use(async (ctx,next) => {
69 | if(ctx.status === 404){
70 | await ctx.render('404',{title: '404 Page'});
71 | }
72 | await next();
73 | });
74 |
75 | //处理500error页面
76 | app.on('error',async (err,ctx) => {
77 | await ctx.render('error',{title:'系统错误',error:err});
78 | });
79 |
80 | //如果index.js 被require了,则导出app,通常用于测试
81 | if(module.parent){
82 | module.exports = app;
83 | }else{
84 | app.listen(config.port,function(){
85 | console.log(`f_blog listening on port ${config.port}`);
86 | });
87 | }
88 |
--------------------------------------------------------------------------------
/public/css/components/shape.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Shape
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.shape{position:relative;vertical-align:top;display:inline-block;-webkit-perspective:2000px;perspective:2000px;-webkit-transition:left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out;transition:left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out,left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out;transition:transform .6s ease-in-out,left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out}.ui.shape .sides{-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.ui.shape .side{opacity:1;width:100%;margin:0!important;-webkit-backface-visibility:hidden;backface-visibility:hidden}.ui.shape .side{display:none}.ui.shape .side *{-webkit-backface-visibility:visible!important;backface-visibility:visible!important}.ui.cube.shape .side{min-width:15em;height:15em;padding:2em;background-color:#e6e6e6;color:rgba(0,0,0,.87);box-shadow:0 0 2px rgba(0,0,0,.3)}.ui.cube.shape .side>.content{width:100%;height:100%;display:table;text-align:center;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.ui.cube.shape .side>.content>div{display:table-cell;vertical-align:middle;font-size:2em}.ui.text.shape.animating .sides{position:static}.ui.text.shape .side{white-space:nowrap}.ui.text.shape .side>*{white-space:normal}.ui.loading.shape{position:absolute;top:-9999px;left:-9999px}.ui.shape .animating.side{position:absolute;top:0;left:0;display:block;z-index:100}.ui.shape .hidden.side{opacity:.6}.ui.shape.animating .sides{position:absolute}.ui.shape.animating .sides{-webkit-transition:left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out;transition:left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out,left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out;transition:transform .6s ease-in-out,left .6s ease-in-out,width .6s ease-in-out,height .6s ease-in-out,-webkit-transform .6s ease-in-out}.ui.shape.animating .side{-webkit-transition:opacity .6s ease-in-out;transition:opacity .6s ease-in-out}.ui.shape .active.side{display:block}
--------------------------------------------------------------------------------
/public/css/components/dimmer.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Dimmer
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.dimmable:not(.body){position:relative}.ui.dimmer{display:none;position:absolute;top:0!important;left:0!important;width:100%;height:100%;text-align:center;vertical-align:middle;background-color:rgba(0,0,0,.85);opacity:0;line-height:1;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-transition:background-color .5s linear;transition:background-color .5s linear;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;will-change:opacity;z-index:1000}.ui.dimmer>.content{width:100%;height:100%;display:table;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.ui.dimmer>.content>*{display:table-cell;vertical-align:middle;color:#fff}.ui.segment>.ui.dimmer{border-radius:inherit!important}.animating.dimmable:not(body),.dimmed.dimmable:not(body){overflow:hidden}.dimmed.dimmable>.ui.animating.dimmer,.dimmed.dimmable>.ui.visible.dimmer,.ui.active.dimmer{display:block;opacity:1}.ui.disabled.dimmer{width:0!important;height:0!important}.ui.page.dimmer{position:fixed;-webkit-transform-style:'';transform-style:'';-webkit-perspective:2000px;perspective:2000px;-webkit-transform-origin:center center;transform-origin:center center}body.animating.in.dimmable,body.dimmed.dimmable{overflow:hidden}body.dimmable>.dimmer{position:fixed}.blurring.dimmable>:not(.dimmer){-webkit-filter:blur(0) grayscale(0);filter:blur(0) grayscale(0);-webkit-transition:.8s -webkit-filter ease;transition:.8s -webkit-filter ease;transition:.8s filter ease;transition:.8s filter ease,.8s -webkit-filter ease}.blurring.dimmed.dimmable>:not(.dimmer){-webkit-filter:blur(5px) grayscale(.7);filter:blur(5px) grayscale(.7)}.blurring.dimmable>.dimmer{background-color:rgba(0,0,0,.6)}.blurring.dimmable>.inverted.dimmer{background-color:rgba(255,255,255,.6)}.ui.dimmer>.top.aligned.content>*{vertical-align:top}.ui.dimmer>.bottom.aligned.content>*{vertical-align:bottom}.ui.inverted.dimmer{background-color:rgba(255,255,255,.85)}.ui.inverted.dimmer>.content>*{color:#fff}.ui.simple.dimmer{display:block;overflow:hidden;opacity:1;width:0;height:0%;z-index:-100;background-color:rgba(0,0,0,0)}.dimmed.dimmable>.ui.simple.dimmer{overflow:visible;opacity:1;width:100%;height:100%;background-color:rgba(0,0,0,.85);z-index:1}.ui.simple.inverted.dimmer{background-color:rgba(255,255,255,0)}.dimmed.dimmable>.ui.simple.inverted.dimmer{background-color:rgba(255,255,255,.85)}
--------------------------------------------------------------------------------
/public/css/components/breadcrumb.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Breadcrumb
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 |
11 |
12 | /*******************************
13 | Breadcrumb
14 | *******************************/
15 |
16 | .ui.breadcrumb {
17 | line-height: 1;
18 | display: inline-block;
19 | margin: 0em 0em;
20 | vertical-align: middle;
21 | }
22 | .ui.breadcrumb:first-child {
23 | margin-top: 0em;
24 | }
25 | .ui.breadcrumb:last-child {
26 | margin-bottom: 0em;
27 | }
28 |
29 |
30 | /*******************************
31 | Content
32 | *******************************/
33 |
34 |
35 | /* Divider */
36 | .ui.breadcrumb .divider {
37 | display: inline-block;
38 | opacity: 0.7;
39 | margin: 0em 0.21428571rem 0em;
40 | font-size: 0.92857143em;
41 | color: rgba(0, 0, 0, 0.4);
42 | vertical-align: baseline;
43 | }
44 |
45 | /* Link */
46 | .ui.breadcrumb a {
47 | color: #4183C4;
48 | }
49 | .ui.breadcrumb a:hover {
50 | color: #1e70bf;
51 | }
52 |
53 | /* Icon Divider */
54 | .ui.breadcrumb .icon.divider {
55 | font-size: 0.85714286em;
56 | vertical-align: baseline;
57 | }
58 |
59 | /* Section */
60 | .ui.breadcrumb a.section {
61 | cursor: pointer;
62 | }
63 | .ui.breadcrumb .section {
64 | display: inline-block;
65 | margin: 0em;
66 | padding: 0em;
67 | }
68 |
69 | /* Loose Coupling */
70 | .ui.breadcrumb.segment {
71 | display: inline-block;
72 | padding: 0.78571429em 1em;
73 | }
74 |
75 |
76 | /*******************************
77 | States
78 | *******************************/
79 |
80 | .ui.breadcrumb .active.section {
81 | font-weight: bold;
82 | }
83 |
84 |
85 | /*******************************
86 | Variations
87 | *******************************/
88 |
89 | .ui.mini.breadcrumb {
90 | font-size: 0.78571429rem;
91 | }
92 | .ui.tiny.breadcrumb {
93 | font-size: 0.85714286rem;
94 | }
95 | .ui.small.breadcrumb {
96 | font-size: 0.92857143rem;
97 | }
98 | .ui.breadcrumb {
99 | font-size: 1rem;
100 | }
101 | .ui.large.breadcrumb {
102 | font-size: 1.14285714rem;
103 | }
104 | .ui.big.breadcrumb {
105 | font-size: 1.28571429rem;
106 | }
107 | .ui.huge.breadcrumb {
108 | font-size: 1.42857143rem;
109 | }
110 | .ui.massive.breadcrumb {
111 | font-size: 1.71428571rem;
112 | }
113 |
114 |
115 | /*******************************
116 | Theme Overrides
117 | *******************************/
118 |
119 |
120 |
121 | /*******************************
122 | Site Overrides
123 | *******************************/
124 |
125 |
--------------------------------------------------------------------------------
/views/base.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{title}} - floder
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | {% block body %}{% endblock %}
13 |
82 |
83 |
--------------------------------------------------------------------------------
/public/css/components/comment.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Comment
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.comments{margin:1.5em 0;max-width:650px}.ui.comments:first-child{margin-top:0}.ui.comments:last-child{margin-bottom:0}.ui.comments .comment{position:relative;background:0 0;margin:.5em 0 0;padding:.5em 0 0;border:none;border-top:none;line-height:1.2}.ui.comments .comment:first-child{margin-top:0;padding-top:0}.ui.comments .comment .comments{margin:0 0 .5em .5em;padding:1em 0 1em 1em}.ui.comments .comment .comments:before{position:absolute;top:0;left:0}.ui.comments .comment .comments .comment{border:none;border-top:none;background:0 0}.ui.comments .comment .avatar{display:block;width:2.5em;height:auto;float:left;margin:.2em 0 0}.ui.comments .comment .avatar img,.ui.comments .comment img.avatar{display:block;margin:0 auto;width:100%;height:100%;border-radius:.25rem}.ui.comments .comment>.content{display:block}.ui.comments .comment>.avatar~.content{margin-left:3.5em}.ui.comments .comment .author{font-size:1em;color:rgba(0,0,0,.87);font-weight:700}.ui.comments .comment a.author{cursor:pointer}.ui.comments .comment a.author:hover{color:#1e70bf}.ui.comments .comment .metadata{display:inline-block;margin-left:.5em;color:rgba(0,0,0,.4);font-size:.875em}.ui.comments .comment .metadata>*{display:inline-block;margin:0 .5em 0 0}.ui.comments .comment .metadata>:last-child{margin-right:0}.ui.comments .comment .text{margin:.25em 0 .5em;font-size:1em;word-wrap:break-word;color:rgba(0,0,0,.87);line-height:1.3}.ui.comments .comment .actions{font-size:.875em}.ui.comments .comment .actions a{cursor:pointer;display:inline-block;margin:0 .75em 0 0;color:rgba(0,0,0,.4)}.ui.comments .comment .actions a:last-child{margin-right:0}.ui.comments .comment .actions a.active,.ui.comments .comment .actions a:hover{color:rgba(0,0,0,.8)}.ui.comments>.reply.form{margin-top:1em}.ui.comments .comment .reply.form{width:100%;margin-top:1em}.ui.comments .reply.form textarea{font-size:1em;height:12em}.ui.collapsed.comments,.ui.comments .collapsed.comment,.ui.comments .collapsed.comments{display:none}.ui.threaded.comments .comment .comments{margin:-1.5em 0 -1em 1.25em;padding:3em 0 2em 2.25em;box-shadow:-1px 0 0 rgba(34,36,38,.15)}.ui.minimal.comments .comment .actions{opacity:0;position:absolute;top:0;right:0;left:auto;-webkit-transition:opacity .2s ease;transition:opacity .2s ease;-webkit-transition-delay:.1s;transition-delay:.1s}.ui.minimal.comments .comment>.content:hover>.actions{opacity:1}.ui.mini.comments{font-size:.78571429rem}.ui.tiny.comments{font-size:.85714286rem}.ui.small.comments{font-size:.92857143rem}.ui.comments{font-size:1rem}.ui.large.comments{font-size:1.14285714rem}.ui.big.comments{font-size:1.28571429rem}.ui.huge.comments{font-size:1.42857143rem}.ui.massive.comments{font-size:1.71428571rem}
--------------------------------------------------------------------------------
/test/singup.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const assert = require('assert');
3 | const request = require('supertest');
4 | const app = require('../index'); //没导出?
5 | const User = require('../lib/mongo').User;
6 |
7 | let testname1 = 'testName1';
8 | let testname2 = 'floder';
9 |
10 | describe('signup',function(){
11 | describe('POST /signup',function(){
12 | let agent = request.agent(app); //persist cookie when redirect
13 | beforeEach(function (done){
14 | User.create({
15 | name:testname1,
16 | password:'123456',
17 | avatar:'',
18 | gender: 'x',
19 | bio: ''
20 | }).exec()
21 | .then(function(){
22 | done();
23 | })
24 | .catch(done);
25 | });
26 | afterEach(function(done){
27 | //删除测试用户
28 | User.remove({name: {$in: [testname1,testname2]}})
29 | .exec()
30 | .then(function(){
31 | done();
32 | })
33 | .catch(done);
34 | });
35 |
36 | //用户名错误的情况
37 | it('wrong name',function(done){
38 | agent
39 | .post('/signup')
40 | .type('form')
41 | .attach('avatar',path.join(__dirname,'avatar.jpg'))
42 | .field({name:''})
43 | .redirects()
44 | .end(function(err,res){
45 | if(err) return done(err);
46 | assert(res.text.match(/名字长度为1-10/));
47 | done();
48 | });
49 | });
50 |
51 | // 用户名被占用的情况
52 | it('duplicate name', function(done) {
53 | agent
54 | .post('/signup')
55 | .type('form')
56 | .attach('avatar', path.join(__dirname, 'avatar.png'))
57 | .field({ name: testName1, gender: 'm', bio: 'noder', password: '123456', repassword: '123456' })
58 | .redirects()
59 | .end(function(err, res) {
60 | if (err) return done(err);
61 | assert(res.text.match(/用户名已被占用/));
62 | done();
63 | });
64 | });
65 |
66 | // 注册成功的情况
67 | it('success', function(done) {
68 | agent
69 | .post('/signup')
70 | .type('form')
71 | .attach('avatar', path.join(__dirname, 'avatar.png'))
72 | .field({ name: testName2, gender: 'm', bio: 'noder', password: '123456', repassword: '123456' })
73 | .redirects()
74 | .end(function(err, res) {
75 | if (err) return done(err);
76 | assert(res.text.match(/注册成功/));
77 | done();
78 | });
79 | });
80 | });
81 | });
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/routes/signup.js:
--------------------------------------------------------------------------------
1 | //处理所有以 '/signup' 开头的请求
2 |
3 | const koaRouter = require('koa-router');
4 | const fs = require('fs');
5 | const path = require('path');
6 | const crypto = require('crypto'); //加密模块
7 | const checkNotLogin = require('../middlewares/check').checkNotLogin;
8 | const userModel = require('../models/users');
9 | // const formidable = require('koa-formidable');
10 | const multer = require('koa-multer');
11 | // const util = require('util');
12 | let router = new koaRouter({
13 | prefix: '/signup'
14 | });
15 |
16 | const upload = multer({
17 | dest: path.join(__dirname,"../public/img")
18 | });
19 |
20 | function encrypt(plainPassword,method){
21 | const hash = crypto.createHash(method);
22 | hash.update(plainPassword);
23 | return hash.digest('hex');
24 | };
25 |
26 | //GET /signup 注册页
27 | router.get('/',checkNotLogin,async(ctx,next)=> {
28 | await ctx.render('signup',{title:'signup'});
29 | });
30 | //POST /signup 用户注册
31 | router.post('/',checkNotLogin,upload.single('avatar'),async(ctx,next) =>{
32 | let req = ctx.req;
33 | let name = req.body.name;
34 | let gender = req.body.gender;
35 | let bio = req.body.bio;
36 | let avatar;
37 | let password = req.body.password;
38 | let repassword = req.body.repassword;
39 |
40 | try{
41 | if(!(name.trim().length) >= 1 && name.trim().length <= 10){
42 | ctx.flash('error','名字长度为1-10');
43 | }
44 | if(['m','f','x'].indexOf(gender) === -1){
45 | ctx.flash('error','性别不对');
46 | }
47 | if(!(bio.trim().length >= 1 && bio.trim().length <= 30)){
48 | ctx.flash('error','简介不能超过30个字符');
49 | }
50 | if(!ctx.req.file.originalname){
51 | ctx.flash('error','需要上传头像');
52 | }
53 | if(password.length < 6){
54 | ctx.flash('error','密码长度必须大于6');
55 | }
56 | if(password !== repassword){
57 | ctx.flash('error','两次密码不同');
58 | }
59 | avatar = req.file.path.split('/').pop(); //返回文件的名字
60 | }catch(e){
61 | //注册失败,异步删除以上传的图片
62 | fs.unlink(ctx.req.file.path);
63 | //往session里面加入一条错误消息
64 | ctx.flash('error',e.message);
65 | return ctx.redirect('/signup');
66 | }
67 | //密码明文加密
68 | password = encrypt(password,'sha256');
69 |
70 | //待写入数据库信息
71 | let user = {
72 | name: name,
73 | password: password,
74 | gender: gender,
75 | bio: bio,
76 | avatar: avatar //保存的是文件的名字
77 | };
78 |
79 | console.log(user);
80 |
81 | //将用户信息写入数据库
82 | try{
83 | let create = await userModel.create(user);
84 | user = create.ops[0];
85 | user.password = null;
86 | ctx.session.user = user;
87 | //写入flash消息
88 | ctx.flash('success','注册成功');
89 | }catch(e){
90 | //删除上传的文件
91 | fs.unlink(ctx.req.file.path);
92 | if(e.errmsg.match('E11000 duplicate key')){
93 | ctx.flash('error','用户名已被占用');
94 | return ctx.redirect('/signup');
95 | }
96 | }
97 | ctx.redirect('/posts');
98 | });
99 |
100 | module.exports = router;
--------------------------------------------------------------------------------
/views/post.html:
--------------------------------------------------------------------------------
1 | {% extends './components/header.html' %}{% block main %}
2 | {% if item %}
3 |
4 |
5 |
12 |
13 |
14 |
15 |
{{item.content | safe }}
16 |
17 |
{{ item.created_at}}
18 |
19 | 浏览{{item.pv}}
20 | 留言{{item.commentsCount}}
21 | {% if user %}
22 | {% if item.author._id %}
23 | {% if (user._id.toString() === item.author._id.toString())%}
24 |
32 | {% endif %}
33 | {% endif %}
34 | {% endif %}
35 |
36 |
37 |
38 |
39 |
40 |
41 | {% endif %}
42 |
43 |
88 |
89 |
90 |
94 | {% endblock %}
--------------------------------------------------------------------------------
/public/css/components/nag.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Nag
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 |
11 |
12 | /*******************************
13 | Nag
14 | *******************************/
15 |
16 | .ui.nag {
17 | display: none;
18 | opacity: 0.95;
19 | position: relative;
20 | top: 0em;
21 | left: 0px;
22 | z-index: 999;
23 | min-height: 0em;
24 | width: 100%;
25 | margin: 0em;
26 | padding: 0.75em 1em;
27 | background: #555555;
28 | box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.2);
29 | font-size: 1rem;
30 | text-align: center;
31 | color: rgba(0, 0, 0, 0.87);
32 | border-radius: 0em 0em 0.28571429rem 0.28571429rem;
33 | -webkit-transition: 0.2s background ease;
34 | transition: 0.2s background ease;
35 | }
36 | a.ui.nag {
37 | cursor: pointer;
38 | }
39 | .ui.nag > .title {
40 | display: inline-block;
41 | margin: 0em 0.5em;
42 | color: #FFFFFF;
43 | }
44 | .ui.nag > .close.icon {
45 | cursor: pointer;
46 | opacity: 0.4;
47 | position: absolute;
48 | top: 50%;
49 | right: 1em;
50 | font-size: 1em;
51 | margin: -0.5em 0em 0em;
52 | color: #FFFFFF;
53 | -webkit-transition: opacity 0.2s ease;
54 | transition: opacity 0.2s ease;
55 | }
56 |
57 |
58 | /*******************************
59 | States
60 | *******************************/
61 |
62 |
63 | /* Hover */
64 | .ui.nag:hover {
65 | background: #555555;
66 | opacity: 1;
67 | }
68 | .ui.nag .close:hover {
69 | opacity: 1;
70 | }
71 |
72 |
73 | /*******************************
74 | Variations
75 | *******************************/
76 |
77 |
78 | /*--------------
79 | Static
80 | ---------------*/
81 |
82 | .ui.overlay.nag {
83 | position: absolute;
84 | display: block;
85 | }
86 |
87 | /*--------------
88 | Fixed
89 | ---------------*/
90 |
91 | .ui.fixed.nag {
92 | position: fixed;
93 | }
94 |
95 | /*--------------
96 | Bottom
97 | ---------------*/
98 |
99 | .ui.bottom.nags,
100 | .ui.bottom.nag {
101 | border-radius: 0.28571429rem 0.28571429rem 0em 0em;
102 | top: auto;
103 | bottom: 0em;
104 | }
105 |
106 | /*--------------
107 | White
108 | ---------------*/
109 |
110 | .ui.inverted.nags .nag,
111 | .ui.inverted.nag {
112 | background-color: #F3F4F5;
113 | color: rgba(0, 0, 0, 0.85);
114 | }
115 | .ui.inverted.nags .nag .close,
116 | .ui.inverted.nags .nag .title,
117 | .ui.inverted.nag .close,
118 | .ui.inverted.nag .title {
119 | color: rgba(0, 0, 0, 0.4);
120 | }
121 |
122 |
123 | /*******************************
124 | Groups
125 | *******************************/
126 |
127 | .ui.nags .nag {
128 | border-radius: 0em !important;
129 | }
130 | .ui.nags .nag:last-child {
131 | border-radius: 0em 0em 0.28571429rem 0.28571429rem;
132 | }
133 | .ui.bottom.nags .nag:last-child {
134 | border-radius: 0.28571429rem 0.28571429rem 0em 0em;
135 | }
136 |
137 |
138 | /*******************************
139 | Theme Overrides
140 | *******************************/
141 |
142 |
143 |
144 | /*******************************
145 | User Overrides
146 | *******************************/
147 |
148 |
--------------------------------------------------------------------------------
/public/css/components/rail.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Rail
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 |
11 |
12 | /*******************************
13 | Rails
14 | *******************************/
15 |
16 | .ui.rail {
17 | position: absolute;
18 | top: 0%;
19 | width: 300px;
20 | height: 100%;
21 | }
22 | .ui.left.rail {
23 | left: auto;
24 | right: 100%;
25 | padding: 0em 2rem 0em 0em;
26 | margin: 0em 2rem 0em 0em;
27 | }
28 | .ui.right.rail {
29 | left: 100%;
30 | right: auto;
31 | padding: 0em 0em 0em 2rem;
32 | margin: 0em 0em 0em 2rem;
33 | }
34 |
35 |
36 | /*******************************
37 | Variations
38 | *******************************/
39 |
40 |
41 | /*--------------
42 | Internal
43 | ---------------*/
44 |
45 | .ui.left.internal.rail {
46 | left: 0%;
47 | right: auto;
48 | padding: 0em 0em 0em 2rem;
49 | margin: 0em 0em 0em 2rem;
50 | }
51 | .ui.right.internal.rail {
52 | left: auto;
53 | right: 0%;
54 | padding: 0em 2rem 0em 0em;
55 | margin: 0em 2rem 0em 0em;
56 | }
57 |
58 | /*--------------
59 | Dividing
60 | ---------------*/
61 |
62 | .ui.dividing.rail {
63 | width: 302.5px;
64 | }
65 | .ui.left.dividing.rail {
66 | padding: 0em 2.5rem 0em 0em;
67 | margin: 0em 2.5rem 0em 0em;
68 | border-right: 1px solid rgba(34, 36, 38, 0.15);
69 | }
70 | .ui.right.dividing.rail {
71 | border-left: 1px solid rgba(34, 36, 38, 0.15);
72 | padding: 0em 0em 0em 2.5rem;
73 | margin: 0em 0em 0em 2.5rem;
74 | }
75 |
76 | /*--------------
77 | Distance
78 | ---------------*/
79 |
80 | .ui.close.rail {
81 | width: calc( 300px + 1em );
82 | }
83 | .ui.close.left.rail {
84 | padding: 0em 1em 0em 0em;
85 | margin: 0em 1em 0em 0em;
86 | }
87 | .ui.close.right.rail {
88 | padding: 0em 0em 0em 1em;
89 | margin: 0em 0em 0em 1em;
90 | }
91 | .ui.very.close.rail {
92 | width: calc( 300px + 0.5em );
93 | }
94 | .ui.very.close.left.rail {
95 | padding: 0em 0.5em 0em 0em;
96 | margin: 0em 0.5em 0em 0em;
97 | }
98 | .ui.very.close.right.rail {
99 | padding: 0em 0em 0em 0.5em;
100 | margin: 0em 0em 0em 0.5em;
101 | }
102 |
103 | /*--------------
104 | Attached
105 | ---------------*/
106 |
107 | .ui.attached.left.rail,
108 | .ui.attached.right.rail {
109 | padding: 0em;
110 | margin: 0em;
111 | }
112 |
113 | /*--------------
114 | Sizing
115 | ---------------*/
116 |
117 | .ui.mini.rail {
118 | font-size: 0.78571429rem;
119 | }
120 | .ui.tiny.rail {
121 | font-size: 0.85714286rem;
122 | }
123 | .ui.small.rail {
124 | font-size: 0.92857143rem;
125 | }
126 | .ui.rail {
127 | font-size: 1rem;
128 | }
129 | .ui.large.rail {
130 | font-size: 1.14285714rem;
131 | }
132 | .ui.big.rail {
133 | font-size: 1.28571429rem;
134 | }
135 | .ui.huge.rail {
136 | font-size: 1.42857143rem;
137 | }
138 | .ui.massive.rail {
139 | font-size: 1.71428571rem;
140 | }
141 |
142 |
143 | /*******************************
144 | Theme Overrides
145 | *******************************/
146 |
147 |
148 |
149 | /*******************************
150 | Site Overrides
151 | *******************************/
152 |
153 |
--------------------------------------------------------------------------------
/public/css/components/site.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Site
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 |
11 |
12 | /*******************************
13 | Page
14 | *******************************/
15 |
16 | @import url('https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic&subset=latin');
17 | html,
18 | body {
19 | height: 100%;
20 | }
21 | html {
22 | font-size: 14px;
23 | }
24 | body {
25 | margin: 0px;
26 | padding: 0px;
27 | overflow-x: hidden;
28 | min-width: 320px;
29 | background: #FFFFFF;
30 | font-family: 'Lato', 'Helvetica Neue', Arial, Helvetica, sans-serif;
31 | font-size: 14px;
32 | line-height: 1.4285em;
33 | color: rgba(0, 0, 0, 0.87);
34 | font-smoothing: antialiased;
35 | }
36 |
37 |
38 | /*******************************
39 | Headers
40 | *******************************/
41 |
42 | h1,
43 | h2,
44 | h3,
45 | h4,
46 | h5 {
47 | font-family: 'Lato', 'Helvetica Neue', Arial, Helvetica, sans-serif;
48 | line-height: 1.28571429em;
49 | margin: calc(2rem - 0.14285714em ) 0em 1rem;
50 | font-weight: bold;
51 | padding: 0em;
52 | }
53 | h1 {
54 | min-height: 1rem;
55 | font-size: 2rem;
56 | }
57 | h2 {
58 | font-size: 1.71428571rem;
59 | }
60 | h3 {
61 | font-size: 1.28571429rem;
62 | }
63 | h4 {
64 | font-size: 1.07142857rem;
65 | }
66 | h5 {
67 | font-size: 1rem;
68 | }
69 | h1:first-child,
70 | h2:first-child,
71 | h3:first-child,
72 | h4:first-child,
73 | h5:first-child {
74 | margin-top: 0em;
75 | }
76 | h1:last-child,
77 | h2:last-child,
78 | h3:last-child,
79 | h4:last-child,
80 | h5:last-child {
81 | margin-bottom: 0em;
82 | }
83 |
84 |
85 | /*******************************
86 | Text
87 | *******************************/
88 |
89 | p {
90 | margin: 0em 0em 1em;
91 | line-height: 1.4285em;
92 | }
93 | p:first-child {
94 | margin-top: 0em;
95 | }
96 | p:last-child {
97 | margin-bottom: 0em;
98 | }
99 |
100 | /*-------------------
101 | Links
102 | --------------------*/
103 |
104 | a {
105 | color: #4183C4;
106 | text-decoration: none;
107 | }
108 | a:hover {
109 | color: #1e70bf;
110 | text-decoration: none;
111 | }
112 |
113 |
114 | /*******************************
115 | Highlighting
116 | *******************************/
117 |
118 |
119 | /* Site */
120 | ::-webkit-selection {
121 | background-color: #CCE2FF;
122 | color: rgba(0, 0, 0, 0.87);
123 | }
124 | ::-moz-selection {
125 | background-color: #CCE2FF;
126 | color: rgba(0, 0, 0, 0.87);
127 | }
128 | ::selection {
129 | background-color: #CCE2FF;
130 | color: rgba(0, 0, 0, 0.87);
131 | }
132 |
133 | /* Form */
134 | textarea::-webkit-selection,
135 | input::-webkit-selection {
136 | background-color: rgba(100, 100, 100, 0.4);
137 | color: rgba(0, 0, 0, 0.87);
138 | }
139 | textarea::-moz-selection,
140 | input::-moz-selection {
141 | background-color: rgba(100, 100, 100, 0.4);
142 | color: rgba(0, 0, 0, 0.87);
143 | }
144 | textarea::selection,
145 | input::selection {
146 | background-color: rgba(100, 100, 100, 0.4);
147 | color: rgba(0, 0, 0, 0.87);
148 | }
149 |
150 |
151 | /*******************************
152 | Global Overrides
153 | *******************************/
154 |
155 |
156 |
157 | /*******************************
158 | Site Overrides
159 | *******************************/
160 |
161 |
--------------------------------------------------------------------------------
/public/css/components/feed.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Feed
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.feed{margin:1em 0}.ui.feed:first-child{margin-top:0}.ui.feed:last-child{margin-bottom:0}.ui.feed>.event{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;width:100%;padding:.21428571rem 0;margin:0;background:0 0;border-top:none}.ui.feed>.event:first-child{border-top:0;padding-top:0}.ui.feed>.event:last-child{padding-bottom:0}.ui.feed>.event>.label{display:block;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:2.5em;height:auto;-ms-flex-item-align:stretch;-ms-grid-row-align:stretch;align-self:stretch;text-align:left}.ui.feed>.event>.label .icon{opacity:1;font-size:1.5em;width:100%;padding:.25em;background:0 0;border:none;border-radius:none;color:rgba(0,0,0,.6)}.ui.feed>.event>.label img{width:100%;height:auto;border-radius:500rem}.ui.feed>.event>.label+.content{margin:.5em 0 .35714286em 1.14285714em}.ui.feed>.event>.content{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;-ms-flex-item-align:stretch;-ms-grid-row-align:stretch;align-self:stretch;text-align:left;word-wrap:break-word}.ui.feed>.event:last-child>.content{padding-bottom:0}.ui.feed>.event>.content a{cursor:pointer}.ui.feed>.event>.content .date{margin:-.5rem 0 0;padding:0;font-weight:400;font-size:1em;font-style:normal;color:rgba(0,0,0,.4)}.ui.feed>.event>.content .summary{margin:0;font-size:1em;font-weight:700;color:rgba(0,0,0,.87)}.ui.feed>.event>.content .summary img{display:inline-block;width:auto;height:10em;margin:-.25em .25em 0 0;border-radius:.25em;vertical-align:middle}.ui.feed>.event>.content .user{display:inline-block;font-weight:700;margin-right:0;vertical-align:baseline}.ui.feed>.event>.content .user img{margin:-.25em .25em 0 0;width:auto;height:10em;vertical-align:middle}.ui.feed>.event>.content .summary>.date{display:inline-block;float:none;font-weight:400;font-size:.85714286em;font-style:normal;margin:0 0 0 .5em;padding:0;color:rgba(0,0,0,.4)}.ui.feed>.event>.content .extra{margin:.5em 0 0;background:0 0;padding:0;color:rgba(0,0,0,.87)}.ui.feed>.event>.content .extra.images img{display:inline-block;margin:0 .25em 0 0;width:6em}.ui.feed>.event>.content .extra.text{padding:0;border-left:none;font-size:1em;max-width:500px;line-height:1.4285em}.ui.feed>.event>.content .meta{display:inline-block;font-size:.85714286em;margin:.5em 0 0;background:0 0;border:none;border-radius:0;box-shadow:none;padding:0;color:rgba(0,0,0,.6)}.ui.feed>.event>.content .meta>*{position:relative;margin-left:.75em}.ui.feed>.event>.content .meta>:after{content:'';color:rgba(0,0,0,.2);top:0;left:-1em;opacity:1;position:absolute;vertical-align:top}.ui.feed>.event>.content .meta .like{color:'';-webkit-transition:.2s color ease;transition:.2s color ease}.ui.feed>.event>.content .meta .like:hover .icon{color:#ff2733}.ui.feed>.event>.content .meta .active.like .icon{color:#ef404a}.ui.feed>.event>.content .meta>:first-child{margin-left:0}.ui.feed>.event>.content .meta>:first-child::after{display:none}.ui.feed>.event>.content .meta a,.ui.feed>.event>.content .meta>.icon{cursor:pointer;opacity:1;color:rgba(0,0,0,.5);-webkit-transition:color .1s ease;transition:color .1s ease}.ui.feed>.event>.content .meta a:hover,.ui.feed>.event>.content .meta a:hover .icon,.ui.feed>.event>.content .meta>.icon:hover{color:rgba(0,0,0,.95)}.ui.small.feed{font-size:.92857143rem}.ui.feed{font-size:1rem}.ui.large.feed{font-size:1.14285714rem}
--------------------------------------------------------------------------------
/public/css/components/image.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Image
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.image{position:relative;display:inline-block;vertical-align:middle;max-width:100%;background-color:transparent}img.ui.image{display:block}.ui.image img,.ui.image svg{display:block;max-width:100%;height:auto}.ui.hidden.image,.ui.hidden.images{display:none}.ui.hidden.transition.image,.ui.hidden.transition.images{display:block;visibility:hidden}.ui.disabled.image,.ui.disabled.images{cursor:default;opacity:.45}.ui.inline.image,.ui.inline.image img,.ui.inline.image svg{display:inline-block}.ui.top.aligned.image,.ui.top.aligned.image img,.ui.top.aligned.image svg,.ui.top.aligned.images .image{display:inline-block;vertical-align:top}.ui.middle.aligned.image,.ui.middle.aligned.image img,.ui.middle.aligned.image svg,.ui.middle.aligned.images .image{display:inline-block;vertical-align:middle}.ui.bottom.aligned.image,.ui.bottom.aligned.image img,.ui.bottom.aligned.image svg,.ui.bottom.aligned.images .image{display:inline-block;vertical-align:bottom}.ui.rounded.image,.ui.rounded.image>*,.ui.rounded.images .image,.ui.rounded.images .image>*{border-radius:.3125em}.ui.bordered.image img,.ui.bordered.image svg,.ui.bordered.images .image,.ui.bordered.images img,.ui.bordered.images svg,img.ui.bordered.image{border:1px solid rgba(0,0,0,.1)}.ui.circular.image,.ui.circular.images{overflow:hidden}.ui.circular.image,.ui.circular.image>*,.ui.circular.images .image,.ui.circular.images .image>*{border-radius:500rem}.ui.fluid.image,.ui.fluid.image img,.ui.fluid.image svg,.ui.fluid.images,.ui.fluid.images img,.ui.fluid.images svg{display:block;width:100%;height:auto}.ui.avatar.image,.ui.avatar.image img,.ui.avatar.image svg,.ui.avatar.images .image,.ui.avatar.images img,.ui.avatar.images svg{margin-right:.25em;display:inline-block;width:2em;height:2em;border-radius:500rem}.ui.spaced.image{display:inline-block!important;margin-left:.5em;margin-right:.5em}.ui[class*="left spaced"].image{margin-left:.5em;margin-right:0}.ui[class*="right spaced"].image{margin-left:0;margin-right:.5em}.ui.floated.image,.ui.floated.images{float:left;margin-right:1em;margin-bottom:1em}.ui.right.floated.image,.ui.right.floated.images{float:right;margin-right:0;margin-bottom:1em;margin-left:1em}.ui.floated.image:last-child,.ui.floated.images:last-child{margin-bottom:0}.ui.centered.image,.ui.centered.images{margin-left:auto;margin-right:auto}.ui.mini.image,.ui.mini.images .image,.ui.mini.images img,.ui.mini.images svg{width:35px;height:auto;font-size:.78571429rem}.ui.tiny.image,.ui.tiny.images .image,.ui.tiny.images img,.ui.tiny.images svg{width:80px;height:auto;font-size:.85714286rem}.ui.small.image,.ui.small.images .image,.ui.small.images img,.ui.small.images svg{width:150px;height:auto;font-size:.92857143rem}.ui.medium.image,.ui.medium.images .image,.ui.medium.images img,.ui.medium.images svg{width:300px;height:auto;font-size:1rem}.ui.large.image,.ui.large.images .image,.ui.large.images img,.ui.large.images svg{width:450px;height:auto;font-size:1.14285714rem}.ui.big.image,.ui.big.images .image,.ui.big.images img,.ui.big.images svg{width:600px;height:auto;font-size:1.28571429rem}.ui.huge.image,.ui.huge.images .image,.ui.huge.images img,.ui.huge.images svg{width:800px;height:auto;font-size:1.42857143rem}.ui.massive.image,.ui.massive.images .image,.ui.massive.images img,.ui.massive.images svg{width:960px;height:auto;font-size:1.71428571rem}.ui.images{font-size:0;margin:0 -.25rem 0}.ui.images .image,.ui.images img,.ui.images svg{display:inline-block;margin:0 .25rem .5rem}
--------------------------------------------------------------------------------
/public/css/components/container.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Container
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 |
11 |
12 | /*******************************
13 | Container
14 | *******************************/
15 |
16 |
17 | /* All Sizes */
18 | .ui.container {
19 | display: block;
20 | max-width: 100% !important;
21 | }
22 |
23 | /* Mobile */
24 | @media only screen and (max-width: 767px) {
25 | .ui.container {
26 | width: auto !important;
27 | margin-left: 1em !important;
28 | margin-right: 1em !important;
29 | }
30 | .ui.grid.container {
31 | width: auto !important;
32 | }
33 | .ui.relaxed.grid.container {
34 | width: auto !important;
35 | }
36 | .ui.very.relaxed.grid.container {
37 | width: auto !important;
38 | }
39 | }
40 |
41 | /* Tablet */
42 | @media only screen and (min-width: 768px) and (max-width: 991px) {
43 | .ui.container {
44 | width: 723px;
45 | margin-left: auto !important;
46 | margin-right: auto !important;
47 | }
48 | .ui.grid.container {
49 | width: calc( 723px + 2rem ) !important;
50 | }
51 | .ui.relaxed.grid.container {
52 | width: calc( 723px + 3rem ) !important;
53 | }
54 | .ui.very.relaxed.grid.container {
55 | width: calc( 723px + 5rem ) !important;
56 | }
57 | }
58 |
59 | /* Small Monitor */
60 | @media only screen and (min-width: 992px) and (max-width: 1199px) {
61 | .ui.container {
62 | width: 933px;
63 | margin-left: auto !important;
64 | margin-right: auto !important;
65 | }
66 | .ui.grid.container {
67 | width: calc( 933px + 2rem ) !important;
68 | }
69 | .ui.relaxed.grid.container {
70 | width: calc( 933px + 3rem ) !important;
71 | }
72 | .ui.very.relaxed.grid.container {
73 | width: calc( 933px + 5rem ) !important;
74 | }
75 | }
76 |
77 | /* Large Monitor */
78 | @media only screen and (min-width: 1200px) {
79 | .ui.container {
80 | width: 1127px;
81 | margin-left: auto !important;
82 | margin-right: auto !important;
83 | }
84 | .ui.grid.container {
85 | width: calc( 1127px + 2rem ) !important;
86 | }
87 | .ui.relaxed.grid.container {
88 | width: calc( 1127px + 3rem ) !important;
89 | }
90 | .ui.very.relaxed.grid.container {
91 | width: calc( 1127px + 5rem ) !important;
92 | }
93 | }
94 |
95 |
96 | /*******************************
97 | Types
98 | *******************************/
99 |
100 |
101 | /* Text Container */
102 | .ui.text.container {
103 | font-family: 'Lato', 'Helvetica Neue', Arial, Helvetica, sans-serif;
104 | max-width: 700px !important;
105 | line-height: 1.5;
106 | }
107 | .ui.text.container {
108 | font-size: 1.14285714rem;
109 | }
110 |
111 | /* Fluid */
112 | .ui.fluid.container {
113 | width: 100%;
114 | }
115 |
116 |
117 | /*******************************
118 | Variations
119 | *******************************/
120 |
121 | .ui[class*="left aligned"].container {
122 | text-align: left;
123 | }
124 | .ui[class*="center aligned"].container {
125 | text-align: center;
126 | }
127 | .ui[class*="right aligned"].container {
128 | text-align: right;
129 | }
130 | .ui.justified.container {
131 | text-align: justify;
132 | -webkit-hyphens: auto;
133 | -ms-hyphens: auto;
134 | hyphens: auto;
135 | }
136 |
137 |
138 | /*******************************
139 | Theme Overrides
140 | *******************************/
141 |
142 |
143 |
144 | /*******************************
145 | Site Overrides
146 | *******************************/
147 |
148 |
--------------------------------------------------------------------------------
/models/posts.js:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * 与文章相关的操作
4 | */
5 | let posts = require('../lib/mongo').Post;
6 | let CommentModel = require('./comments');
7 | const marked = require('marked');
8 |
9 | //将post的content 从 markdown 转换成 html
10 | posts.plugin('contentToHtml',{
11 | afterFind: function(posts){
12 | return posts.map(function (post){
13 | post.content = marked(post.content);
14 | return post;
15 | });
16 | },
17 | afterFindOne: function(post){
18 | if(post){
19 | post.content = marked(post.content);
20 | }
21 | return post;
22 | }
23 | });
24 |
25 | //给post添加留言数 commentsCount
26 | posts.plugin('addCommentsCount',{
27 | afterFind: function(posts){
28 | return Promise.all(posts.map(function(post){
29 | return CommentModel.getCommentsCount(post._id).then(function (commentsCount){
30 | post.commentsCount = commentsCount;
31 | return post;
32 | });
33 | }));
34 | },
35 | afterFindOne: function(post){
36 | if(post){
37 | return CommentModel.getCommentsCount(post._id).then(function(count){
38 | post.commentsCount = count;
39 | return post;
40 | });
41 | }
42 | return post;
43 | }
44 | });
45 |
46 | module.exports = {
47 | //创建一篇文章
48 | create : function create(post){
49 | return posts.create(post).exec();
50 | },
51 |
52 | //通过文章id来获取文章
53 | getPostById: function getPostById(postId){
54 | return posts.findOne({_id:postId})
55 | .populate({path:'author',model:'User'}) //联表查询(通过path,表是User)
56 | .addCreatedAt() //创建时间插件
57 | .addCommentsCount()
58 | .contentToHtml() //markdown内容转化为html
59 | .exec();
60 | },
61 |
62 | //按创建时间降序获取所有用户文章或者某个特定用户的所有文章
63 | getPosts : function getPosts(author){
64 | let query = {};
65 | //如果query为空,查询所有用户的文章,否则查询指定用户的文章
66 | if(query){
67 | query.author = author;
68 | }
69 | console.log(query);
70 | if(query.author === undefined){
71 | query = {};
72 | }
73 | return posts.find(query)
74 | .populate({path:'author',model:'User'})
75 | .sort({_id: -1}) //倒序
76 | .addCreatedAt()
77 | .addCommentsCount()
78 | .contentToHtml()
79 | .exec();
80 | },
81 |
82 | //通过文章id 给pv 加1
83 | incPv : function incPv(postId){
84 | return posts.update({_id:postId},{$inc:{pv: 1}})
85 | .exec();
86 | },
87 |
88 | //通过文章id 获取一篇原生文章
89 | getRawPostById: function getRawPostById(postId){
90 | return posts.findOne({_id:postId})
91 | .populate({path:'author',model:'User'})
92 | .exec();
93 | },
94 |
95 | //通过用户id 和文章 id 更新一篇文章
96 | updatePostById: function updatePostById(postId,author,data){
97 | return posts.update({author:author,_id:postId},{$set: data}).exec();
98 | },
99 |
100 | //通过用户id和文章id删除一篇文章
101 | delPostById: function delPostById(postId,author){
102 | return posts.remove({author:author,_id:postId})
103 | .exec()
104 | .then(function (res){
105 | //文章删除后,再删除该文章下的所有留言
106 | if(res.result.ok && res.result.n > 0){
107 | return CommentModel.delCommentsByPostId(postId);
108 | }
109 | });
110 | },
111 |
112 | };
113 |
--------------------------------------------------------------------------------
/public/css/components/embed.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Video
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 |
11 |
12 | /*******************************
13 | Types
14 | *******************************/
15 |
16 | .ui.embed {
17 | position: relative;
18 | max-width: 100%;
19 | height: 0px;
20 | overflow: hidden;
21 | background: #DCDDDE;
22 | padding-bottom: 56.25%;
23 | }
24 |
25 | /*-----------------
26 | Embedded Content
27 | ------------------*/
28 |
29 | .ui.embed iframe,
30 | .ui.embed embed,
31 | .ui.embed object {
32 | position: absolute;
33 | border: none;
34 | width: 100%;
35 | height: 100%;
36 | top: 0px;
37 | left: 0px;
38 | margin: 0em;
39 | padding: 0em;
40 | }
41 |
42 | /*-----------------
43 | Embed
44 | ------------------*/
45 |
46 | .ui.embed > .embed {
47 | display: none;
48 | }
49 |
50 | /*--------------
51 | Placeholder
52 | ---------------*/
53 |
54 | .ui.embed > .placeholder {
55 | position: absolute;
56 | cursor: pointer;
57 | top: 0px;
58 | left: 0px;
59 | display: block;
60 | width: 100%;
61 | height: 100%;
62 | background-color: radial-gradient(transparent 45%, rgba(0, 0, 0, 0.3));
63 | }
64 |
65 | /*--------------
66 | Icon
67 | ---------------*/
68 |
69 | .ui.embed > .icon {
70 | cursor: pointer;
71 | position: absolute;
72 | top: 0px;
73 | left: 0px;
74 | width: 100%;
75 | height: 100%;
76 | z-index: 2;
77 | }
78 | .ui.embed > .icon:after {
79 | position: absolute;
80 | top: 0%;
81 | left: 0%;
82 | width: 100%;
83 | height: 100%;
84 | z-index: 3;
85 | content: '';
86 | background: -webkit-radial-gradient(transparent 45%, rgba(0, 0, 0, 0.3));
87 | background: radial-gradient(transparent 45%, rgba(0, 0, 0, 0.3));
88 | opacity: 0.5;
89 | -webkit-transition: opacity 0.5s ease;
90 | transition: opacity 0.5s ease;
91 | }
92 | .ui.embed > .icon:before {
93 | position: absolute;
94 | top: 50%;
95 | left: 50%;
96 | z-index: 4;
97 | -webkit-transform: translateX(-50%) translateY(-50%);
98 | transform: translateX(-50%) translateY(-50%);
99 | color: #FFFFFF;
100 | font-size: 6rem;
101 | text-shadow: 0px 2px 10px rgba(34, 36, 38, 0.2);
102 | -webkit-transition: opacity 0.5s ease, color 0.5s ease;
103 | transition: opacity 0.5s ease, color 0.5s ease;
104 | z-index: 10;
105 | }
106 |
107 |
108 | /*******************************
109 | States
110 | *******************************/
111 |
112 |
113 | /*--------------
114 | Hover
115 | ---------------*/
116 |
117 | .ui.embed .icon:hover:after {
118 | background: -webkit-radial-gradient(transparent 45%, rgba(0, 0, 0, 0.3));
119 | background: radial-gradient(transparent 45%, rgba(0, 0, 0, 0.3));
120 | opacity: 1;
121 | }
122 | .ui.embed .icon:hover:before {
123 | color: #FFFFFF;
124 | }
125 |
126 | /*--------------
127 | Active
128 | ---------------*/
129 |
130 | .ui.active.embed > .icon,
131 | .ui.active.embed > .placeholder {
132 | display: none;
133 | }
134 | .ui.active.embed > .embed {
135 | display: block;
136 | }
137 |
138 |
139 | /*******************************
140 | Video Overrides
141 | *******************************/
142 |
143 |
144 |
145 | /*******************************
146 | Site Overrides
147 | *******************************/
148 |
149 |
150 |
151 | /*******************************
152 | Variations
153 | *******************************/
154 |
155 | .ui.square.embed {
156 | padding-bottom: 100%;
157 | }
158 | .ui[class*="4:3"].embed {
159 | padding-bottom: 75%;
160 | }
161 | .ui[class*="16:9"].embed {
162 | padding-bottom: 56.25%;
163 | }
164 | .ui[class*="21:9"].embed {
165 | padding-bottom: 42.85714286%;
166 | }
167 |
--------------------------------------------------------------------------------
/public/css/components/shape.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Shape
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 |
11 |
12 | /*******************************
13 | Shape
14 | *******************************/
15 |
16 | .ui.shape {
17 | position: relative;
18 | vertical-align: top;
19 | display: inline-block;
20 | -webkit-perspective: 2000px;
21 | perspective: 2000px;
22 | -webkit-transition: left 0.6s ease-in-out, width 0.6s ease-in-out, height 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;
23 | transition: left 0.6s ease-in-out, width 0.6s ease-in-out, height 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;
24 | transition: transform 0.6s ease-in-out, left 0.6s ease-in-out, width 0.6s ease-in-out, height 0.6s ease-in-out;
25 | transition: transform 0.6s ease-in-out, left 0.6s ease-in-out, width 0.6s ease-in-out, height 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;
26 | }
27 | .ui.shape .sides {
28 | -webkit-transform-style: preserve-3d;
29 | transform-style: preserve-3d;
30 | }
31 | .ui.shape .side {
32 | opacity: 1;
33 | width: 100%;
34 | margin: 0em !important;
35 | -webkit-backface-visibility: hidden;
36 | backface-visibility: hidden;
37 | }
38 | .ui.shape .side {
39 | display: none;
40 | }
41 | .ui.shape .side * {
42 | -webkit-backface-visibility: visible !important;
43 | backface-visibility: visible !important;
44 | }
45 |
46 |
47 | /*******************************
48 | Types
49 | *******************************/
50 |
51 | .ui.cube.shape .side {
52 | min-width: 15em;
53 | height: 15em;
54 | padding: 2em;
55 | background-color: #E6E6E6;
56 | color: rgba(0, 0, 0, 0.87);
57 | box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.3);
58 | }
59 | .ui.cube.shape .side > .content {
60 | width: 100%;
61 | height: 100%;
62 | display: table;
63 | text-align: center;
64 | -webkit-user-select: text;
65 | -moz-user-select: text;
66 | -ms-user-select: text;
67 | user-select: text;
68 | }
69 | .ui.cube.shape .side > .content > div {
70 | display: table-cell;
71 | vertical-align: middle;
72 | font-size: 2em;
73 | }
74 |
75 |
76 | /*******************************
77 | Variations
78 | *******************************/
79 |
80 | .ui.text.shape.animating .sides {
81 | position: static;
82 | }
83 | .ui.text.shape .side {
84 | white-space: nowrap;
85 | }
86 | .ui.text.shape .side > * {
87 | white-space: normal;
88 | }
89 |
90 |
91 | /*******************************
92 | States
93 | *******************************/
94 |
95 |
96 | /*--------------
97 | Loading
98 | ---------------*/
99 |
100 | .ui.loading.shape {
101 | position: absolute;
102 | top: -9999px;
103 | left: -9999px;
104 | }
105 |
106 | /*--------------
107 | Animating
108 | ---------------*/
109 |
110 | .ui.shape .animating.side {
111 | position: absolute;
112 | top: 0px;
113 | left: 0px;
114 | display: block;
115 | z-index: 100;
116 | }
117 | .ui.shape .hidden.side {
118 | opacity: 0.6;
119 | }
120 |
121 | /*--------------
122 | CSS
123 | ---------------*/
124 |
125 | .ui.shape.animating .sides {
126 | position: absolute;
127 | }
128 | .ui.shape.animating .sides {
129 | -webkit-transition: left 0.6s ease-in-out, width 0.6s ease-in-out, height 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;
130 | transition: left 0.6s ease-in-out, width 0.6s ease-in-out, height 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;
131 | transition: transform 0.6s ease-in-out, left 0.6s ease-in-out, width 0.6s ease-in-out, height 0.6s ease-in-out;
132 | transition: transform 0.6s ease-in-out, left 0.6s ease-in-out, width 0.6s ease-in-out, height 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;
133 | }
134 | .ui.shape.animating .side {
135 | -webkit-transition: opacity 0.6s ease-in-out;
136 | transition: opacity 0.6s ease-in-out;
137 | }
138 |
139 | /*--------------
140 | Active
141 | ---------------*/
142 |
143 | .ui.shape .active.side {
144 | display: block;
145 | }
146 |
147 |
148 | /*******************************
149 | Theme Overrides
150 | *******************************/
151 |
152 |
153 |
154 | /*******************************
155 | User Overrides
156 | *******************************/
157 |
158 |
--------------------------------------------------------------------------------
/public/css/components/loader.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Loader
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.loader{display:none;position:absolute;top:50%;left:50%;margin:0;text-align:center;z-index:1000;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%)}.ui.loader:before{position:absolute;content:'';top:0;left:50%;width:100%;height:100%;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.loader:after{position:absolute;content:'';top:0;left:50%;width:100%;height:100%;-webkit-animation:loader .6s linear;animation:loader .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 transparent transparent;border-style:solid;border-width:.2em;box-shadow:0 0 0 1px transparent}@-webkit-keyframes loader{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loader{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.ui.mini.loader:after,.ui.mini.loader:before{width:1rem;height:1rem;margin:0 0 0 -.5rem}.ui.tiny.loader:after,.ui.tiny.loader:before{width:1.14285714rem;height:1.14285714rem;margin:0 0 0 -.57142857rem}.ui.small.loader:after,.ui.small.loader:before{width:1.71428571rem;height:1.71428571rem;margin:0 0 0 -.85714286rem}.ui.loader:after,.ui.loader:before{width:2.28571429rem;height:2.28571429rem;margin:0 0 0 -1.14285714rem}.ui.large.loader:after,.ui.large.loader:before{width:3.42857143rem;height:3.42857143rem;margin:0 0 0 -1.71428571rem}.ui.big.loader:after,.ui.big.loader:before{width:3.71428571rem;height:3.71428571rem;margin:0 0 0 -1.85714286rem}.ui.huge.loader:after,.ui.huge.loader:before{width:4.14285714rem;height:4.14285714rem;margin:0 0 0 -2.07142857rem}.ui.massive.loader:after,.ui.massive.loader:before{width:4.57142857rem;height:4.57142857rem;margin:0 0 0 -2.28571429rem}.ui.dimmer .loader{display:block}.ui.dimmer .ui.loader{color:rgba(255,255,255,.9)}.ui.dimmer .ui.loader:before{border-color:rgba(255,255,255,.15)}.ui.dimmer .ui.loader:after{border-color:#fff transparent transparent}.ui.inverted.dimmer .ui.loader{color:rgba(0,0,0,.87)}.ui.inverted.dimmer .ui.loader:before{border-color:rgba(0,0,0,.1)}.ui.inverted.dimmer .ui.loader:after{border-color:#767676 transparent transparent}.ui.text.loader{width:auto!important;height:auto!important;text-align:center;font-style:normal}.ui.indeterminate.loader:after{-webkit-animation-direction:reverse;animation-direction:reverse;-webkit-animation-duration:1.2s;animation-duration:1.2s}.ui.loader.active,.ui.loader.visible{display:block}.ui.loader.disabled,.ui.loader.hidden{display:none}.ui.inverted.dimmer .ui.mini.loader,.ui.mini.loader{width:1rem;height:1rem;font-size:.78571429em}.ui.inverted.dimmer .ui.tiny.loader,.ui.tiny.loader{width:1.14285714rem;height:1.14285714rem;font-size:.85714286em}.ui.inverted.dimmer .ui.small.loader,.ui.small.loader{width:1.71428571rem;height:1.71428571rem;font-size:.92857143em}.ui.inverted.dimmer .ui.loader,.ui.loader{width:2.28571429rem;height:2.28571429rem;font-size:1em}.ui.inverted.dimmer .ui.large.loader,.ui.large.loader{width:3.42857143rem;height:3.42857143rem;font-size:1.14285714em}.ui.big.loader,.ui.inverted.dimmer .ui.big.loader{width:3.71428571rem;height:3.71428571rem;font-size:1.28571429em}.ui.huge.loader,.ui.inverted.dimmer .ui.huge.loader{width:4.14285714rem;height:4.14285714rem;font-size:1.42857143em}.ui.inverted.dimmer .ui.massive.loader,.ui.massive.loader{width:4.57142857rem;height:4.57142857rem;font-size:1.71428571em}.ui.mini.text.loader{min-width:1rem;padding-top:1.78571429rem}.ui.tiny.text.loader{min-width:1.14285714rem;padding-top:1.92857143rem}.ui.small.text.loader{min-width:1.71428571rem;padding-top:2.5rem}.ui.text.loader{min-width:2.28571429rem;padding-top:3.07142857rem}.ui.large.text.loader{min-width:3.42857143rem;padding-top:4.21428571rem}.ui.big.text.loader{min-width:3.71428571rem;padding-top:4.5rem}.ui.huge.text.loader{min-width:4.14285714rem;padding-top:4.92857143rem}.ui.massive.text.loader{min-width:4.57142857rem;padding-top:5.35714286rem}.ui.inverted.loader{color:rgba(255,255,255,.9)}.ui.inverted.loader:before{border-color:rgba(255,255,255,.15)}.ui.inverted.loader:after{border-top-color:#fff}.ui.inline.loader{position:relative;vertical-align:middle;margin:0;left:0;top:0;-webkit-transform:none;transform:none}.ui.inline.loader.active,.ui.inline.loader.visible{display:inline-block}.ui.centered.inline.loader.active,.ui.centered.inline.loader.visible{display:block;margin-left:auto;margin-right:auto}
--------------------------------------------------------------------------------
/public/css/components/dimmer.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Dimmer
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 |
11 |
12 | /*******************************
13 | Dimmer
14 | *******************************/
15 |
16 | .dimmable:not(.body) {
17 | position: relative;
18 | }
19 | .ui.dimmer {
20 | display: none;
21 | position: absolute;
22 | top: 0em !important;
23 | left: 0em !important;
24 | width: 100%;
25 | height: 100%;
26 | text-align: center;
27 | vertical-align: middle;
28 | background-color: rgba(0, 0, 0, 0.85);
29 | opacity: 0;
30 | line-height: 1;
31 | -webkit-animation-fill-mode: both;
32 | animation-fill-mode: both;
33 | -webkit-animation-duration: 0.5s;
34 | animation-duration: 0.5s;
35 | -webkit-transition: background-color 0.5s linear;
36 | transition: background-color 0.5s linear;
37 | -webkit-user-select: none;
38 | -moz-user-select: none;
39 | -ms-user-select: none;
40 | user-select: none;
41 | will-change: opacity;
42 | z-index: 1000;
43 | }
44 |
45 | /* Dimmer Content */
46 | .ui.dimmer > .content {
47 | width: 100%;
48 | height: 100%;
49 | display: table;
50 | -webkit-user-select: text;
51 | -moz-user-select: text;
52 | -ms-user-select: text;
53 | user-select: text;
54 | }
55 | .ui.dimmer > .content > * {
56 | display: table-cell;
57 | vertical-align: middle;
58 | color: #FFFFFF;
59 | }
60 |
61 | /* Loose Coupling */
62 | .ui.segment > .ui.dimmer {
63 | border-radius: inherit !important;
64 | }
65 |
66 |
67 | /*******************************
68 | States
69 | *******************************/
70 |
71 | .animating.dimmable:not(body),
72 | .dimmed.dimmable:not(body) {
73 | overflow: hidden;
74 | }
75 | .dimmed.dimmable > .ui.animating.dimmer,
76 | .dimmed.dimmable > .ui.visible.dimmer,
77 | .ui.active.dimmer {
78 | display: block;
79 | opacity: 1;
80 | }
81 | .ui.disabled.dimmer {
82 | width: 0 !important;
83 | height: 0 !important;
84 | }
85 |
86 |
87 | /*******************************
88 | Variations
89 | *******************************/
90 |
91 |
92 | /*--------------
93 | Page
94 | ---------------*/
95 |
96 | .ui.page.dimmer {
97 | position: fixed;
98 | -webkit-transform-style: '';
99 | transform-style: '';
100 | -webkit-perspective: 2000px;
101 | perspective: 2000px;
102 | -webkit-transform-origin: center center;
103 | transform-origin: center center;
104 | }
105 | body.animating.in.dimmable,
106 | body.dimmed.dimmable {
107 | overflow: hidden;
108 | }
109 | body.dimmable > .dimmer {
110 | position: fixed;
111 | }
112 |
113 | /*--------------
114 | Blurring
115 | ---------------*/
116 |
117 | .blurring.dimmable > :not(.dimmer) {
118 | -webkit-filter: blur(0px) grayscale(0);
119 | filter: blur(0px) grayscale(0);
120 | -webkit-transition: 800ms -webkit-filter ease;
121 | transition: 800ms -webkit-filter ease;
122 | transition: 800ms filter ease;
123 | transition: 800ms filter ease, 800ms -webkit-filter ease;
124 | }
125 | .blurring.dimmed.dimmable > :not(.dimmer) {
126 | -webkit-filter: blur(5px) grayscale(0.7);
127 | filter: blur(5px) grayscale(0.7);
128 | }
129 |
130 | /* Dimmer Color */
131 | .blurring.dimmable > .dimmer {
132 | background-color: rgba(0, 0, 0, 0.6);
133 | }
134 | .blurring.dimmable > .inverted.dimmer {
135 | background-color: rgba(255, 255, 255, 0.6);
136 | }
137 |
138 | /*--------------
139 | Aligned
140 | ---------------*/
141 |
142 | .ui.dimmer > .top.aligned.content > * {
143 | vertical-align: top;
144 | }
145 | .ui.dimmer > .bottom.aligned.content > * {
146 | vertical-align: bottom;
147 | }
148 |
149 | /*--------------
150 | Inverted
151 | ---------------*/
152 |
153 | .ui.inverted.dimmer {
154 | background-color: rgba(255, 255, 255, 0.85);
155 | }
156 | .ui.inverted.dimmer > .content > * {
157 | color: #FFFFFF;
158 | }
159 |
160 | /*--------------
161 | Simple
162 | ---------------*/
163 |
164 |
165 | /* Displays without javascript */
166 | .ui.simple.dimmer {
167 | display: block;
168 | overflow: hidden;
169 | opacity: 1;
170 | width: 0%;
171 | height: 0%;
172 | z-index: -100;
173 | background-color: rgba(0, 0, 0, 0);
174 | }
175 | .dimmed.dimmable > .ui.simple.dimmer {
176 | overflow: visible;
177 | opacity: 1;
178 | width: 100%;
179 | height: 100%;
180 | background-color: rgba(0, 0, 0, 0.85);
181 | z-index: 1;
182 | }
183 | .ui.simple.inverted.dimmer {
184 | background-color: rgba(255, 255, 255, 0);
185 | }
186 | .dimmed.dimmable > .ui.simple.inverted.dimmer {
187 | background-color: rgba(255, 255, 255, 0.85);
188 | }
189 |
190 |
191 | /*******************************
192 | Theme Overrides
193 | *******************************/
194 |
195 |
196 |
197 | /*******************************
198 | User Overrides
199 | *******************************/
200 |
201 |
--------------------------------------------------------------------------------
/public/css/components/ad.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Ad
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Copyright 2013 Contributors
7 | * Released under the MIT license
8 | * http://opensource.org/licenses/MIT
9 | *
10 | */
11 |
12 |
13 | /*******************************
14 | Advertisement
15 | *******************************/
16 |
17 | .ui.ad {
18 | display: block;
19 | overflow: hidden;
20 | margin: 1em 0em;
21 | }
22 | .ui.ad:first-child {
23 | margin: 0em;
24 | }
25 | .ui.ad:last-child {
26 | margin: 0em;
27 | }
28 | .ui.ad iframe {
29 | margin: 0em;
30 | padding: 0em;
31 | border: none;
32 | overflow: hidden;
33 | }
34 |
35 | /*--------------
36 | Common
37 | ---------------*/
38 |
39 |
40 | /* Leaderboard */
41 | .ui.leaderboard.ad {
42 | width: 728px;
43 | height: 90px;
44 | }
45 |
46 | /* Medium Rectangle */
47 | .ui[class*="medium rectangle"].ad {
48 | width: 300px;
49 | height: 250px;
50 | }
51 |
52 | /* Large Rectangle */
53 | .ui[class*="large rectangle"].ad {
54 | width: 336px;
55 | height: 280px;
56 | }
57 |
58 | /* Half Page */
59 | .ui[class*="half page"].ad {
60 | width: 300px;
61 | height: 600px;
62 | }
63 |
64 | /*--------------
65 | Square
66 | ---------------*/
67 |
68 |
69 | /* Square */
70 | .ui.square.ad {
71 | width: 250px;
72 | height: 250px;
73 | }
74 |
75 | /* Small Square */
76 | .ui[class*="small square"].ad {
77 | width: 200px;
78 | height: 200px;
79 | }
80 |
81 | /*--------------
82 | Rectangle
83 | ---------------*/
84 |
85 |
86 | /* Small Rectangle */
87 | .ui[class*="small rectangle"].ad {
88 | width: 180px;
89 | height: 150px;
90 | }
91 |
92 | /* Vertical Rectangle */
93 | .ui[class*="vertical rectangle"].ad {
94 | width: 240px;
95 | height: 400px;
96 | }
97 |
98 | /*--------------
99 | Button
100 | ---------------*/
101 |
102 | .ui.button.ad {
103 | width: 120px;
104 | height: 90px;
105 | }
106 | .ui[class*="square button"].ad {
107 | width: 125px;
108 | height: 125px;
109 | }
110 | .ui[class*="small button"].ad {
111 | width: 120px;
112 | height: 60px;
113 | }
114 |
115 | /*--------------
116 | Skyscrapers
117 | ---------------*/
118 |
119 |
120 | /* Skyscraper */
121 | .ui.skyscraper.ad {
122 | width: 120px;
123 | height: 600px;
124 | }
125 |
126 | /* Wide Skyscraper */
127 | .ui[class*="wide skyscraper"].ad {
128 | width: 160px;
129 | }
130 |
131 | /*--------------
132 | Banners
133 | ---------------*/
134 |
135 |
136 | /* Banner */
137 | .ui.banner.ad {
138 | width: 468px;
139 | height: 60px;
140 | }
141 |
142 | /* Vertical Banner */
143 | .ui[class*="vertical banner"].ad {
144 | width: 120px;
145 | height: 240px;
146 | }
147 |
148 | /* Top Banner */
149 | .ui[class*="top banner"].ad {
150 | width: 930px;
151 | height: 180px;
152 | }
153 |
154 | /* Half Banner */
155 | .ui[class*="half banner"].ad {
156 | width: 234px;
157 | height: 60px;
158 | }
159 |
160 | /*--------------
161 | Boards
162 | ---------------*/
163 |
164 |
165 | /* Leaderboard */
166 | .ui[class*="large leaderboard"].ad {
167 | width: 970px;
168 | height: 90px;
169 | }
170 |
171 | /* Billboard */
172 | .ui.billboard.ad {
173 | width: 970px;
174 | height: 250px;
175 | }
176 |
177 | /*--------------
178 | Panorama
179 | ---------------*/
180 |
181 |
182 | /* Panorama */
183 | .ui.panorama.ad {
184 | width: 980px;
185 | height: 120px;
186 | }
187 |
188 | /*--------------
189 | Netboard
190 | ---------------*/
191 |
192 |
193 | /* Netboard */
194 | .ui.netboard.ad {
195 | width: 580px;
196 | height: 400px;
197 | }
198 |
199 | /*--------------
200 | Mobile
201 | ---------------*/
202 |
203 |
204 | /* Large Mobile Banner */
205 | .ui[class*="large mobile banner"].ad {
206 | width: 320px;
207 | height: 100px;
208 | }
209 |
210 | /* Mobile Leaderboard */
211 | .ui[class*="mobile leaderboard"].ad {
212 | width: 320px;
213 | height: 50px;
214 | }
215 |
216 |
217 | /*******************************
218 | Types
219 | *******************************/
220 |
221 |
222 | /* Mobile Sizes */
223 | .ui.mobile.ad {
224 | display: none;
225 | }
226 | @media only screen and (max-width: 767px) {
227 | .ui.mobile.ad {
228 | display: block;
229 | }
230 | }
231 |
232 |
233 | /*******************************
234 | Variations
235 | *******************************/
236 |
237 | .ui.centered.ad {
238 | margin-left: auto;
239 | margin-right: auto;
240 | }
241 | .ui.test.ad {
242 | position: relative;
243 | background: #545454;
244 | }
245 | .ui.test.ad:after {
246 | position: absolute;
247 | top: 50%;
248 | left: 50%;
249 | width: 100%;
250 | text-align: center;
251 | -webkit-transform: translateX(-50%) translateY(-50%);
252 | transform: translateX(-50%) translateY(-50%);
253 | content: 'Ad';
254 | color: #FFFFFF;
255 | font-size: 1em;
256 | font-weight: bold;
257 | }
258 | .ui.mobile.test.ad:after {
259 | font-size: 0.85714286em;
260 | }
261 | .ui.test.ad[data-text]:after {
262 | content: attr(data-text);
263 | }
264 |
265 |
266 | /*******************************
267 | Theme Overrides
268 | *******************************/
269 |
270 |
271 |
272 | /*******************************
273 | User Variable Overrides
274 | *******************************/
275 |
276 |
--------------------------------------------------------------------------------
/public/css/components/rating.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Rating
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 | !function(e,n,t,i){"use strict";n="undefined"!=typeof n&&n.Math==Math?n:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")(),e.fn.rating=function(n){var t,a=e(this),o=a.selector||"",r=(new Date).getTime(),s=[],l=arguments[0],c="string"==typeof l,u=[].slice.call(arguments,1);return a.each(function(){var d,g,m=e.isPlainObject(n)?e.extend(!0,{},e.fn.rating.settings,n):e.extend({},e.fn.rating.settings),f=m.namespace,v=m.className,p=m.metadata,b=m.selector,h=(m.error,"."+f),y="module-"+f,x=this,R=e(this).data(y),C=e(this),T=C.find(b.icon);g={initialize:function(){g.verbose("Initializing rating module",m),0===T.length&&g.setup.layout(),m.interactive?g.enable():g.disable(),g.set.initialLoad(),g.set.rating(g.get.initialRating()),g.remove.initialLoad(),g.instantiate()},instantiate:function(){g.verbose("Instantiating module",m),R=g,C.data(y,g)},destroy:function(){g.verbose("Destroying previous instance",R),g.remove.events(),C.removeData(y)},refresh:function(){T=C.find(b.icon)},setup:{layout:function(){var n=g.get.maxRating(),t=e.fn.rating.settings.templates.icon(n);g.debug("Generating icon html dynamically"),C.html(t),g.refresh()}},event:{mouseenter:function(){var n=e(this);n.nextAll().removeClass(v.selected),C.addClass(v.selected),n.addClass(v.selected).prevAll().addClass(v.selected)},mouseleave:function(){C.removeClass(v.selected),T.removeClass(v.selected)},click:function(){var n=e(this),t=g.get.rating(),i=T.index(n)+1,a="auto"==m.clearable?1===T.length:m.clearable;a&&t==i?g.clearRating():g.set.rating(i)}},clearRating:function(){g.debug("Clearing current rating"),g.set.rating(0)},bind:{events:function(){g.verbose("Binding events"),C.on("mouseenter"+h,b.icon,g.event.mouseenter).on("mouseleave"+h,b.icon,g.event.mouseleave).on("click"+h,b.icon,g.event.click)}},remove:{events:function(){g.verbose("Removing events"),C.off(h)},initialLoad:function(){d=!1}},enable:function(){g.debug("Setting rating to interactive mode"),g.bind.events(),C.removeClass(v.disabled)},disable:function(){g.debug("Setting rating to read-only mode"),g.remove.events(),C.addClass(v.disabled)},is:{initialLoad:function(){return d}},get:{initialRating:function(){return C.data(p.rating)!==i?(C.removeData(p.rating),C.data(p.rating)):m.initialRating},maxRating:function(){return C.data(p.maxRating)!==i?(C.removeData(p.maxRating),C.data(p.maxRating)):m.maxRating},rating:function(){var e=T.filter("."+v.active).length;return g.verbose("Current rating retrieved",e),e}},set:{rating:function(e){var n=e-1>=0?e-1:0,t=T.eq(n);C.removeClass(v.selected),T.removeClass(v.selected).removeClass(v.active),e>0&&(g.verbose("Setting current rating to",e),t.prevAll().addBack().addClass(v.active)),g.is.initialLoad()||m.onRate.call(x,e)},initialLoad:function(){d=!0}},setting:function(n,t){if(g.debug("Changing setting",n,t),e.isPlainObject(n))e.extend(!0,m,n);else{if(t===i)return m[n];e.isPlainObject(m[n])?e.extend(!0,m[n],t):m[n]=t}},internal:function(n,t){if(e.isPlainObject(n))e.extend(!0,g,n);else{if(t===i)return g[n];g[n]=t}},debug:function(){!m.silent&&m.debug&&(m.performance?g.performance.log(arguments):(g.debug=Function.prototype.bind.call(console.info,console,m.name+":"),g.debug.apply(console,arguments)))},verbose:function(){!m.silent&&m.verbose&&m.debug&&(m.performance?g.performance.log(arguments):(g.verbose=Function.prototype.bind.call(console.info,console,m.name+":"),g.verbose.apply(console,arguments)))},error:function(){m.silent||(g.error=Function.prototype.bind.call(console.error,console,m.name+":"),g.error.apply(console,arguments))},performance:{log:function(e){var n,t,i;m.performance&&(n=(new Date).getTime(),i=r||n,t=n-i,r=n,s.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:x,"Execution Time":t})),clearTimeout(g.performance.timer),g.performance.timer=setTimeout(g.performance.display,500)},display:function(){var n=m.name+":",t=0;r=!1,clearTimeout(g.performance.timer),e.each(s,function(e,n){t+=n["Execution Time"]}),n+=" "+t+"ms",o&&(n+=" '"+o+"'"),a.length>1&&(n+=" ("+a.length+")"),(console.group!==i||console.table!==i)&&s.length>0&&(console.groupCollapsed(n),console.table?console.table(s):e.each(s,function(e,n){console.log(n.Name+": "+n["Execution Time"]+"ms")}),console.groupEnd()),s=[]}},invoke:function(n,a,o){var r,s,l,c=R;return a=a||u,o=x||o,"string"==typeof n&&c!==i&&(n=n.split(/[\. ]/),r=n.length-1,e.each(n,function(t,a){var o=t!=r?a+n[t+1].charAt(0).toUpperCase()+n[t+1].slice(1):n;if(e.isPlainObject(c[o])&&t!=r)c=c[o];else{if(c[o]!==i)return s=c[o],!1;if(!e.isPlainObject(c[a])||t==r)return c[a]!==i&&(s=c[a],!1);c=c[a]}})),e.isFunction(s)?l=s.apply(o,a):s!==i&&(l=s),e.isArray(t)?t.push(l):t!==i?t=[t,l]:l!==i&&(t=l),s}},c?(R===i&&g.initialize(),g.invoke(l)):(R!==i&&R.invoke("destroy"),g.initialize())}),t!==i?t:this},e.fn.rating.settings={name:"Rating",namespace:"rating",slent:!1,debug:!1,verbose:!1,performance:!0,initialRating:0,interactive:!0,maxRating:4,clearable:"auto",fireOnInit:!1,onRate:function(e){},error:{method:"The method you called is not defined",noMaximum:"No maximum rating specified. Cannot generate HTML automatically"},metadata:{rating:"rating",maxRating:"maxRating"},className:{active:"active",disabled:"disabled",selected:"selected",loading:"loading"},selector:{icon:".icon"},templates:{icon:function(e){for(var n=1,t="";n<=e;)t+='',n++;return t}}}}(jQuery,window,document);
--------------------------------------------------------------------------------
/public/css/components/reveal.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Reveal
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.reveal{display:inherit;position:relative!important;font-size:0!important}.ui.reveal>.visible.content{position:absolute!important;top:0!important;left:0!important;z-index:3!important;-webkit-transition:all .5s ease .1s;transition:all .5s ease .1s}.ui.reveal>.hidden.content{position:relative!important;z-index:2!important}.ui.active.reveal .visible.content,.ui.reveal:hover .visible.content{z-index:4!important}.ui.slide.reveal{position:relative!important;overflow:hidden!important;white-space:nowrap}.ui.slide.reveal>.content{display:block;width:100%;float:left;margin:0;-webkit-transition:-webkit-transform .5s ease .1s;transition:-webkit-transform .5s ease .1s;transition:transform .5s ease .1s;transition:transform .5s ease .1s,-webkit-transform .5s ease .1s}.ui.slide.reveal>.visible.content{position:relative!important}.ui.slide.reveal>.hidden.content{position:absolute!important;left:0!important;width:100%!important;-webkit-transform:translateX(100%)!important;transform:translateX(100%)!important}.ui.slide.active.reveal>.visible.content,.ui.slide.reveal:hover>.visible.content{-webkit-transform:translateX(-100%)!important;transform:translateX(-100%)!important}.ui.slide.active.reveal>.hidden.content,.ui.slide.reveal:hover>.hidden.content{-webkit-transform:translateX(0)!important;transform:translateX(0)!important}.ui.slide.right.reveal>.visible.content{-webkit-transform:translateX(0)!important;transform:translateX(0)!important}.ui.slide.right.reveal>.hidden.content{-webkit-transform:translateX(-100%)!important;transform:translateX(-100%)!important}.ui.slide.right.active.reveal>.visible.content,.ui.slide.right.reveal:hover>.visible.content{-webkit-transform:translateX(100%)!important;transform:translateX(100%)!important}.ui.slide.right.active.reveal>.hidden.content,.ui.slide.right.reveal:hover>.hidden.content{-webkit-transform:translateX(0)!important;transform:translateX(0)!important}.ui.slide.up.reveal>.hidden.content{-webkit-transform:translateY(100%)!important;transform:translateY(100%)!important}.ui.slide.up.active.reveal>.visible.content,.ui.slide.up.reveal:hover>.visible.content{-webkit-transform:translateY(-100%)!important;transform:translateY(-100%)!important}.ui.slide.up.active.reveal>.hidden.content,.ui.slide.up.reveal:hover>.hidden.content{-webkit-transform:translateY(0)!important;transform:translateY(0)!important}.ui.slide.down.reveal>.hidden.content{-webkit-transform:translateY(-100%)!important;transform:translateY(-100%)!important}.ui.slide.down.active.reveal>.visible.content,.ui.slide.down.reveal:hover>.visible.content{-webkit-transform:translateY(100%)!important;transform:translateY(100%)!important}.ui.slide.down.active.reveal>.hidden.content,.ui.slide.down.reveal:hover>.hidden.content{-webkit-transform:translateY(0)!important;transform:translateY(0)!important}.ui.fade.reveal>.visible.content{opacity:1}.ui.fade.active.reveal>.visible.content,.ui.fade.reveal:hover>.visible.content{opacity:0}.ui.move.reveal{position:relative!important;overflow:hidden!important;white-space:nowrap}.ui.move.reveal>.content{display:block;float:left;margin:0;-webkit-transition:-webkit-transform .5s cubic-bezier(.175,.885,.32,1) .1s;transition:-webkit-transform .5s cubic-bezier(.175,.885,.32,1) .1s;transition:transform .5s cubic-bezier(.175,.885,.32,1) .1s;transition:transform .5s cubic-bezier(.175,.885,.32,1) .1s,-webkit-transform .5s cubic-bezier(.175,.885,.32,1) .1s}.ui.move.reveal>.visible.content{position:relative!important}.ui.move.reveal>.hidden.content{position:absolute!important;left:0!important;width:100%!important}.ui.move.active.reveal>.visible.content,.ui.move.reveal:hover>.visible.content{-webkit-transform:translateX(-100%)!important;transform:translateX(-100%)!important}.ui.move.right.active.reveal>.visible.content,.ui.move.right.reveal:hover>.visible.content{-webkit-transform:translateX(100%)!important;transform:translateX(100%)!important}.ui.move.up.active.reveal>.visible.content,.ui.move.up.reveal:hover>.visible.content{-webkit-transform:translateY(-100%)!important;transform:translateY(-100%)!important}.ui.move.down.active.reveal>.visible.content,.ui.move.down.reveal:hover>.visible.content{-webkit-transform:translateY(100%)!important;transform:translateY(100%)!important}.ui.rotate.reveal>.visible.content{-webkit-transition-duration:.5s;transition-duration:.5s;-webkit-transform:rotate(0);transform:rotate(0)}.ui.rotate.reveal>.visible.content,.ui.rotate.right.reveal>.visible.content{-webkit-transform-origin:bottom right;transform-origin:bottom right}.ui.rotate.active.reveal>.visible.content,.ui.rotate.reveal:hover>.visible.content,.ui.rotate.right.active.reveal>.visible.content,.ui.rotate.right.reveal:hover>.visible.content{-webkit-transform:rotate(110deg);transform:rotate(110deg)}.ui.rotate.left.reveal>.visible.content{-webkit-transform-origin:bottom left;transform-origin:bottom left}.ui.rotate.left.active.reveal>.visible.content,.ui.rotate.left.reveal:hover>.visible.content{-webkit-transform:rotate(-110deg);transform:rotate(-110deg)}.ui.disabled.reveal:hover>.visible.visible.content{position:static!important;display:block!important;opacity:1!important;top:0!important;left:0!important;right:auto!important;bottom:auto!important;-webkit-transform:none!important;transform:none!important}.ui.disabled.reveal:hover>.hidden.hidden.content{display:none!important}.ui.visible.reveal{overflow:visible}.ui.instant.reveal>.content{-webkit-transition-delay:0s!important;transition-delay:0s!important}.ui.reveal>.content{font-size:1rem!important}
--------------------------------------------------------------------------------
/public/css/components/item.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Item
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.items>.item{display:-webkit-box;display:-ms-flexbox;display:flex;margin:1em 0;width:100%;min-height:0;background:0 0;padding:0;border:none;border-radius:0;box-shadow:none;-webkit-transition:box-shadow .1s ease;transition:box-shadow .1s ease;z-index:''}.ui.items>.item a{cursor:pointer}.ui.items{margin:1.5em 0}.ui.items:first-child{margin-top:0!important}.ui.items:last-child{margin-bottom:0!important}.ui.items>.item:after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item:first-child{margin-top:0}.ui.items>.item:last-child{margin-bottom:0}.ui.items>.item>.image{position:relative;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;display:block;float:none;margin:0;padding:0;max-height:'';-ms-flex-item-align:top;-ms-grid-row-align:top;align-self:top}.ui.items>.item>.image>img{display:block;width:100%;height:auto;border-radius:.125rem;border:none}.ui.items>.item>.image:only-child>img{border-radius:0}.ui.items>.item>.content{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;background:0 0;margin:0;padding:0;box-shadow:none;font-size:1em;border:none;border-radius:0}.ui.items>.item>.content:after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image+.content{min-width:0;width:auto;display:block;margin-left:0;-ms-flex-item-align:top;-ms-grid-row-align:top;align-self:top;padding-left:1.5em}.ui.items>.item>.content>.header{display:inline-block;margin:-.21425em 0 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-weight:700;color:rgba(0,0,0,.85)}.ui.items>.item>.content>.header:not(.ui){font-size:1.28571429em}.ui.items>.item [class*="left floated"]{float:left}.ui.items>.item [class*="right floated"]{float:right}.ui.items>.item .content img{-ms-flex-item-align:middle;-ms-grid-row-align:middle;align-self:middle;width:''}.ui.items>.item .avatar img,.ui.items>.item img.avatar{width:'';height:'';border-radius:500rem}.ui.items>.item>.content>.description{margin-top:.6em;max-width:auto;font-size:1em;line-height:1.4285em;color:rgba(0,0,0,.87)}.ui.items>.item>.content p{margin:0 0 .5em}.ui.items>.item>.content p:last-child{margin-bottom:0}.ui.items>.item .meta{margin:.5em 0 .5em;font-size:1em;line-height:1em;color:rgba(0,0,0,.6)}.ui.items>.item .meta *{margin-right:.3em}.ui.items>.item .meta :last-child{margin-right:0}.ui.items>.item .meta [class*="right floated"]{margin-right:0;margin-left:.3em}.ui.items>.item>.content a:not(.ui){color:'';-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content a:not(.ui):hover{color:''}.ui.items>.item>.content>a.header{color:rgba(0,0,0,.85)}.ui.items>.item>.content>a.header:hover{color:#1e70bf}.ui.items>.item .meta>a:not(.ui){color:rgba(0,0,0,.4)}.ui.items>.item .meta>a:not(.ui):hover{color:rgba(0,0,0,.87)}.ui.items>.item>.content .favorite.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content .favorite.icon:hover{opacity:1;color:#ffb70a}.ui.items>.item>.content .active.favorite.icon{color:#ffe623}.ui.items>.item>.content .like.icon{cursor:pointer;opacity:.75;-webkit-transition:color .1s ease;transition:color .1s ease}.ui.items>.item>.content .like.icon:hover{opacity:1;color:#ff2733}.ui.items>.item>.content .active.like.icon{color:#ff2733}.ui.items>.item .extra{display:block;position:relative;background:0 0;margin:.5rem 0 0;width:100%;padding:0 0 0;top:0;left:0;color:rgba(0,0,0,.4);box-shadow:none;-webkit-transition:color .1s ease;transition:color .1s ease;border-top:none}.ui.items>.item .extra>*{margin:.25rem .5rem .25rem 0}.ui.items>.item .extra>[class*="right floated"]{margin:.25rem 0 .25rem .5rem}.ui.items>.item .extra:after{display:block;content:' ';height:0;clear:both;overflow:hidden;visibility:hidden}.ui.items>.item>.image:not(.ui){width:175px}@media only screen and (min-width:768px) and (max-width:991px){.ui.items>.item{margin:1em 0}.ui.items>.item>.image:not(.ui){width:150px}.ui.items>.item>.image+.content{display:block;padding:0 0 0 1em}}@media only screen and (max-width:767px){.ui.items:not(.unstackable)>.item{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:2em 0}.ui.items:not(.unstackable)>.item>.image{display:block;margin-left:auto;margin-right:auto}.ui.items:not(.unstackable)>.item>.image,.ui.items:not(.unstackable)>.item>.image>img{max-width:100%!important;width:auto!important;max-height:250px!important}.ui.items:not(.unstackable)>.item>.image+.content{display:block;padding:1.5em 0 0}}.ui.items>.item>.image+[class*="top aligned"].content{-ms-flex-item-align:start;align-self:flex-start}.ui.items>.item>.image+[class*="middle aligned"].content{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.ui.items>.item>.image+[class*="bottom aligned"].content{-ms-flex-item-align:end;align-self:flex-end}.ui.relaxed.items>.item{margin:1.5em 0}.ui[class*="very relaxed"].items>.item{margin:2em 0}.ui.divided.items>.item{border-top:1px solid rgba(34,36,38,.15);margin:0;padding:1em 0}.ui.divided.items>.item:first-child{border-top:none;margin-top:0!important;padding-top:0!important}.ui.divided.items>.item:last-child{margin-bottom:0!important;padding-bottom:0!important}.ui.relaxed.divided.items>.item{margin:0;padding:1.5em 0}.ui[class*="very relaxed"].divided.items>.item{margin:0;padding:2em 0}.ui.items a.item:hover,.ui.link.items>.item:hover{cursor:pointer}.ui.items a.item:hover .content .header,.ui.link.items>.item:hover .content .header{color:#1e70bf}.ui.items>.item{font-size:1em}@media only screen and (max-width:767px){.ui.unstackable.items>.item>.image,.ui.unstackable.items>.item>.image>img{width:125px!important}}
--------------------------------------------------------------------------------
/public/css/components/nag.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Nag
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 | !function(e,o,t,n){"use strict";o="undefined"!=typeof o&&o.Math==Math?o:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")(),e.fn.nag=function(t){var i,s=e(this),a=s.selector||"",r=(new Date).getTime(),l=[],c=arguments[0],g="string"==typeof c,u=[].slice.call(arguments,1);return s.each(function(){var s,d=e.isPlainObject(t)?e.extend(!0,{},e.fn.nag.settings,t):e.extend({},e.fn.nag.settings),m=(d.className,d.selector),f=d.error,p=d.namespace,h="."+p,b=p+"-module",v=e(this),y=(v.find(m.close),e(d.context?d.context:"body")),k=this,S=v.data(b);o.requestAnimationFrame||o.mozRequestAnimationFrame||o.webkitRequestAnimationFrame||o.msRequestAnimationFrame||function(e){setTimeout(e,0)};s={initialize:function(){s.verbose("Initializing element"),v.on("click"+h,m.close,s.dismiss).data(b,s),d.detachable&&v.parent()[0]!==y[0]&&v.detach().prependTo(y),d.displayTime>0&&setTimeout(s.hide,d.displayTime),s.show()},destroy:function(){s.verbose("Destroying instance"),v.removeData(b).off(h)},show:function(){s.should.show()&&!v.is(":visible")&&(s.debug("Showing nag",d.animation.show),"fade"==d.animation.show?v.fadeIn(d.duration,d.easing):v.slideDown(d.duration,d.easing))},hide:function(){s.debug("Showing nag",d.animation.hide),"fade"==d.animation.show?v.fadeIn(d.duration,d.easing):v.slideUp(d.duration,d.easing)},onHide:function(){s.debug("Removing nag",d.animation.hide),v.remove(),d.onHide&&d.onHide()},dismiss:function(e){d.storageMethod&&s.storage.set(d.key,d.value),s.hide(),e.stopImmediatePropagation(),e.preventDefault()},should:{show:function(){return d.persist?(s.debug("Persistent nag is set, can show nag"),!0):s.storage.get(d.key)!=d.value.toString()?(s.debug("Stored value is not set, can show nag",s.storage.get(d.key)),!0):(s.debug("Stored value is set, cannot show nag",s.storage.get(d.key)),!1)}},get:{storageOptions:function(){var e={};return d.expires&&(e.expires=d.expires),d.domain&&(e.domain=d.domain),d.path&&(e.path=d.path),e}},clear:function(){s.storage.remove(d.key)},storage:{set:function(t,i){var a=s.get.storageOptions();if("localstorage"==d.storageMethod&&o.localStorage!==n)o.localStorage.setItem(t,i),s.debug("Value stored using local storage",t,i);else if("sessionstorage"==d.storageMethod&&o.sessionStorage!==n)o.sessionStorage.setItem(t,i),s.debug("Value stored using session storage",t,i);else{if(e.cookie===n)return void s.error(f.noCookieStorage);e.cookie(t,i,a),s.debug("Value stored using cookie",t,i,a)}},get:function(t,i){var a;return"localstorage"==d.storageMethod&&o.localStorage!==n?a=o.localStorage.getItem(t):"sessionstorage"==d.storageMethod&&o.sessionStorage!==n?a=o.sessionStorage.getItem(t):e.cookie!==n?a=e.cookie(t):s.error(f.noCookieStorage),"undefined"!=a&&"null"!=a&&a!==n&&null!==a||(a=n),a},remove:function(t){var i=s.get.storageOptions();"localstorage"==d.storageMethod&&o.localStorage!==n?o.localStorage.removeItem(t):"sessionstorage"==d.storageMethod&&o.sessionStorage!==n?o.sessionStorage.removeItem(t):e.cookie!==n?e.removeCookie(t,i):s.error(f.noStorage)}},setting:function(o,t){if(s.debug("Changing setting",o,t),e.isPlainObject(o))e.extend(!0,d,o);else{if(t===n)return d[o];e.isPlainObject(d[o])?e.extend(!0,d[o],t):d[o]=t}},internal:function(o,t){if(e.isPlainObject(o))e.extend(!0,s,o);else{if(t===n)return s[o];s[o]=t}},debug:function(){!d.silent&&d.debug&&(d.performance?s.performance.log(arguments):(s.debug=Function.prototype.bind.call(console.info,console,d.name+":"),s.debug.apply(console,arguments)))},verbose:function(){!d.silent&&d.verbose&&d.debug&&(d.performance?s.performance.log(arguments):(s.verbose=Function.prototype.bind.call(console.info,console,d.name+":"),s.verbose.apply(console,arguments)))},error:function(){d.silent||(s.error=Function.prototype.bind.call(console.error,console,d.name+":"),s.error.apply(console,arguments))},performance:{log:function(e){var o,t,n;d.performance&&(o=(new Date).getTime(),n=r||o,t=o-n,r=o,l.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:k,"Execution Time":t})),clearTimeout(s.performance.timer),s.performance.timer=setTimeout(s.performance.display,500)},display:function(){var o=d.name+":",t=0;r=!1,clearTimeout(s.performance.timer),e.each(l,function(e,o){t+=o["Execution Time"]}),o+=" "+t+"ms",a&&(o+=" '"+a+"'"),(console.group!==n||console.table!==n)&&l.length>0&&(console.groupCollapsed(o),console.table?console.table(l):e.each(l,function(e,o){console.log(o.Name+": "+o["Execution Time"]+"ms")}),console.groupEnd()),l=[]}},invoke:function(o,t,a){var r,l,c,g=S;return t=t||u,a=k||a,"string"==typeof o&&g!==n&&(o=o.split(/[\. ]/),r=o.length-1,e.each(o,function(t,i){var a=t!=r?i+o[t+1].charAt(0).toUpperCase()+o[t+1].slice(1):o;if(e.isPlainObject(g[a])&&t!=r)g=g[a];else{if(g[a]!==n)return l=g[a],!1;if(!e.isPlainObject(g[i])||t==r)return g[i]!==n?(l=g[i],!1):(s.error(f.method,o),!1);g=g[i]}})),e.isFunction(l)?c=l.apply(a,t):l!==n&&(c=l),e.isArray(i)?i.push(c):i!==n?i=[i,c]:c!==n&&(i=c),l}},g?(S===n&&s.initialize(),s.invoke(c)):(S!==n&&S.invoke("destroy"),s.initialize())}),i!==n?i:this},e.fn.nag.settings={name:"Nag",silent:!1,debug:!1,verbose:!1,performance:!0,namespace:"Nag",persist:!1,displayTime:0,animation:{show:"slide",hide:"slide"},context:!1,detachable:!1,expires:30,domain:!1,path:"/",storageMethod:"cookie",key:"nag",value:"dismiss",error:{noCookieStorage:"$.cookie is not included. A storage solution is required.",noStorage:"Neither $.cookie or store is defined. A storage solution is required for storing state",method:"The method you called is not defined."},className:{bottom:"bottom",fixed:"fixed"},selector:{close:".close.icon"},speed:500,easing:"easeOutQuad",onHide:function(){}},e.extend(e.easing,{easeOutQuad:function(e,o,t,n,i){return-n*(o/=i)*(o-2)+t}})}(jQuery,window,document);
--------------------------------------------------------------------------------
/routes/posts.js:
--------------------------------------------------------------------------------
1 | //处理所有以/post/开始的请求
2 |
3 | const koaRouter = require('koa-router');
4 | const checkLogin = require('../middlewares/check').checkLogin;
5 | const postModel = require('../models/posts');
6 | const commentModel = require('../models/comments');
7 |
8 | //设定路由前缀
9 | const router = new koaRouter({
10 | prefix: '/posts'
11 | });
12 |
13 | //GET /posts 所有用户或者特定用户的文章页
14 | router.get('/', async (ctx,next) => {
15 | console.log('所有用户或者特定用户的文章页');
16 | let author = ctx.query.author;
17 | let posts = await postModel.getPosts(author);
18 | console.log(posts);
19 | try {
20 | await ctx.render('posts', {title: '首页',posts: posts});
21 | }catch(e){
22 | console.log(e.message);
23 | }
24 | });
25 |
26 | //GET /posts/create 发表文章页
27 | router.get('/create',checkLogin,async (ctx,next) => {
28 | console.log('发表文章页');
29 | await ctx.render('create',{title: '写文章'});
30 | });
31 |
32 | //POST /posts 发表一篇文章
33 | router.post('/',checkLogin,async (ctx,next) => {
34 | console.log('发表一篇文章');
35 | let author = ctx.session.user._id;
36 | let title = ctx.request.body.title;
37 | let content = ctx.request.body.content;
38 |
39 | //校检参数
40 | try{
41 | console.log('校检参数');
42 | if(!title.length){
43 | throw new Error('请填写标题');
44 | }
45 | if(!content.length){
46 | throw new Error('请填写内容');
47 | }
48 | }catch(e){
49 | console.log('校检参数出错');
50 | ctx.flash('error',e.message);
51 | return ctx.redirect('back');
52 | }
53 |
54 | let post = {
55 | author : author,
56 | title : title,
57 | content : content,
58 | pv: 0 //点击量
59 | };
60 |
61 | try{
62 | console.log('post data to mongodb');
63 | let result = await postModel.create(post);
64 | //result是插入mongodb后的值,包含_id;
65 | post = result.ops[0];
66 | ctx.flash('success','发表成功');
67 | ctx.redirect(`/posts/${post._id}`);
68 | }catch(e){
69 | //handler error
70 | console.log('post error : ' + e.message);
71 | }
72 |
73 | });
74 |
75 | //GET /posts/:postId 单独一篇文章页
76 | router.get('/:postId',async (ctx,next) => {
77 | console.log('单独一篇文章页');
78 | let postId = ctx.params.postId;
79 |
80 | try{
81 | let result = await Promise.all([postModel.getPostById(postId),postModel.incPv(postId),commentModel.getComments(postId)]);
82 | let post = result[0];
83 | let comments = result[2];
84 | console.log(comments);
85 | if(!post){
86 | throw new Error('该文章不存在');
87 | }
88 | await ctx.render('post',{item : post , comments : comments , title: post.title});
89 | }catch(e){
90 | console.log(e.message);
91 | }
92 | });
93 |
94 | //GET /posts/:postId/edit 更新文章页
95 | router.get('/:postId/edit',checkLogin,async (ctx,next) => {
96 | console.log('更新文章页');
97 | let postId = ctx.params.postId;
98 | let author = ctx.session.user._id;
99 |
100 | try{
101 | let post = await postModel.getRawPostById(postId,author);
102 | if(!post){
103 | throw new Error('该文章不存在');
104 | }
105 | if(author.toString() !== post.author._id.toString()){
106 | throw new Error('权限不足');
107 | }
108 | await ctx.render('edit',{
109 | post: post,
110 | title:'编辑文章'
111 | });
112 | }catch(e){
113 | console.log(e.message);
114 | }
115 |
116 | }) ;
117 |
118 | //POST /posts/:postId/edit 更新一篇文章
119 | router.post('/:postId/edit',checkLogin,async (ctx,next) => {
120 | console.log('更新一篇文章');
121 | let postId = ctx.params.postId;
122 | let author = ctx.session.user._id;
123 | let title = ctx.request.body.title;
124 | let content = ctx.request.body.content;
125 | try{
126 | await postModel.updatePostById(postId,author,{title: title,content: content});
127 | ctx.flash('success','更新成功');
128 | ctx.redirect(`/posts/${postId}`);
129 | }catch(e){
130 | console.log(e.message);
131 | }
132 | });
133 |
134 | //DEL /posts/:postId/remove 删除一篇文章
135 | router.get('/:postId/remove',checkLogin,async (ctx,next) => {
136 | console.log('删除一篇文章');
137 | let postId = ctx.params.postId;
138 | let author = ctx.session.user._id;
139 |
140 | try{
141 | await postModel.delPostById(postId,author);
142 | ctx.flash('success','删除文章成功');
143 | //转到主页
144 | ctx.redirect('/posts');
145 | }catch(e){
146 | console.log(e.message);
147 | }
148 | });
149 |
150 | //POST /posts/:postId/comment 创建一条留言
151 | router.post('/:postId/comment',checkLogin,async (ctx,next) => {
152 | console.log('创建一条留言');
153 | let author = ctx.session.user._id;
154 | let postId = ctx.params.postId;
155 | let content = ctx.request.body.content;
156 | let comment = {
157 | author: author,
158 | postId: postId,
159 | content: content
160 | };
161 | try{
162 | let result = await commentModel.create(comment);
163 | ctx.flash('success','留言成功');
164 | ctx.redirect('back');
165 | }catch(e){
166 | console.log(e.message);
167 | }
168 | });
169 |
170 | //DELETE /posts/:postId/comment/:commentId/remove 删除一条留言
171 | router.get('/:postId/comment/:commentId/remove',checkLogin,async (ctx,next) => {
172 | console.log('删除一条留言');
173 | let commentId = ctx.params.commentId;
174 | let author = ctx.session.user._id;
175 | try{
176 | await commentModel.delCommentById(commentId,author);
177 | //删除成功后跳转到上一页
178 | ctx.redirect('back');
179 | }catch(e){
180 | console.log(e.message);
181 | }
182 | });
183 |
184 | //输出
185 | module.exports = router;
186 |
--------------------------------------------------------------------------------
/public/css/components/divider.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Divider
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.divider{margin:1rem 0;line-height:1;height:0;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:rgba(0,0,0,.85);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.ui.divider:not(.vertical):not(.horizontal){border-top:1px solid rgba(34,36,38,.15);border-bottom:1px solid rgba(255,255,255,.1)}.ui.grid>.column+.divider,.ui.grid>.row>.column+.divider{left:auto}.ui.horizontal.divider{display:table;white-space:nowrap;height:auto;margin:'';line-height:1;text-align:center}.ui.horizontal.divider:after,.ui.horizontal.divider:before{content:'';display:table-cell;position:relative;top:50%;width:50%;background-repeat:no-repeat}.ui.horizontal.divider:before{background-position:right 1em top 50%}.ui.horizontal.divider:after{background-position:left 1em top 50%}.ui.vertical.divider{position:absolute;z-index:2;top:50%;left:50%;margin:0;padding:0;width:auto;height:50%;line-height:0;text-align:center;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.ui.vertical.divider:after,.ui.vertical.divider:before{position:absolute;left:50%;content:'';z-index:3;border-left:1px solid rgba(34,36,38,.15);border-right:1px solid rgba(255,255,255,.1);width:0;height:calc(100% - 1rem)}.ui.vertical.divider:before{top:-100%}.ui.vertical.divider:after{top:auto;bottom:0}@media only screen and (max-width:767px){.ui.grid .stackable.row .ui.vertical.divider,.ui.stackable.grid .ui.vertical.divider{display:table;white-space:nowrap;height:auto;margin:'';overflow:hidden;line-height:1;text-align:center;position:static;top:0;left:0;-webkit-transform:none;transform:none}.ui.grid .stackable.row .ui.vertical.divider:after,.ui.grid .stackable.row .ui.vertical.divider:before,.ui.stackable.grid .ui.vertical.divider:after,.ui.stackable.grid .ui.vertical.divider:before{position:static;left:0;border-left:none;border-right:none;content:'';display:table-cell;position:relative;top:50%;width:50%;background-repeat:no-repeat}.ui.grid .stackable.row .ui.vertical.divider:before,.ui.stackable.grid .ui.vertical.divider:before{background-position:right 1em top 50%}.ui.grid .stackable.row .ui.vertical.divider:after,.ui.stackable.grid .ui.vertical.divider:after{background-position:left 1em top 50%}}.ui.divider>.icon{margin:0;font-size:1rem;height:1em;vertical-align:middle}.ui.hidden.divider{border-color:transparent!important}.ui.hidden.divider:after,.ui.hidden.divider:before{display:none}.ui.divider.inverted,.ui.horizontal.inverted.divider,.ui.vertical.inverted.divider{color:#fff}.ui.divider.inverted,.ui.divider.inverted:after,.ui.divider.inverted:before{border-top-color:rgba(34,36,38,.15)!important;border-left-color:rgba(34,36,38,.15)!important;border-bottom-color:rgba(255,255,255,.15)!important;border-right-color:rgba(255,255,255,.15)!important}.ui.fitted.divider{margin:0}.ui.clearing.divider{clear:both}.ui.section.divider{margin-top:2rem;margin-bottom:2rem}.ui.divider{font-size:1rem}.ui.horizontal.divider:after,.ui.horizontal.divider:before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAACCAYAAACuTHuKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1OThBRDY4OUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1OThBRDY4QUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjU5OEFENjg3Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjU5OEFENjg4Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+VU513gAAADVJREFUeNrs0DENACAQBDBIWLGBJQby/mUcJn5sJXQmOQMAAAAAAJqt+2prAAAAAACg2xdgANk6BEVuJgyMAAAAAElFTkSuQmCC)}@media only screen and (max-width:767px){.ui.grid .stackable.row .ui.vertical.divider:after,.ui.grid .stackable.row .ui.vertical.divider:before,.ui.stackable.grid .ui.vertical.divider:after,.ui.stackable.grid .ui.vertical.divider:before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAACCAYAAACuTHuKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1OThBRDY4OUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1OThBRDY4QUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjU5OEFENjg3Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjU5OEFENjg4Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+VU513gAAADVJREFUeNrs0DENACAQBDBIWLGBJQby/mUcJn5sJXQmOQMAAAAAAJqt+2prAAAAAACg2xdgANk6BEVuJgyMAAAAAElFTkSuQmCC)}}
--------------------------------------------------------------------------------
/public/css/components/search.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Search
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.search{position:relative}.ui.search>.prompt{margin:0;outline:0;-webkit-appearance:none;-webkit-tap-highlight-color:rgba(255,255,255,0);text-shadow:none;font-style:normal;font-weight:400;line-height:1.21428571em;padding:.67857143em 1em;font-size:1em;background:#fff;border:1px solid rgba(34,36,38,.15);color:rgba(0,0,0,.87);box-shadow:0 0 0 0 transparent inset;-webkit-transition:background-color .1s ease,color .1s ease,box-shadow .1s ease,border-color .1s ease;transition:background-color .1s ease,color .1s ease,box-shadow .1s ease,border-color .1s ease}.ui.search .prompt{border-radius:500rem}.ui.search .prompt~.search.icon{cursor:pointer}.ui.search>.results{display:none;position:absolute;top:100%;left:0;-webkit-transform-origin:center top;transform-origin:center top;white-space:normal;background:#fff;margin-top:.5em;width:18em;border-radius:.28571429rem;box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);border:1px solid #d4d4d5;z-index:998}.ui.search>.results>:first-child{border-radius:.28571429rem .28571429rem 0 0}.ui.search>.results>:last-child{border-radius:0 0 .28571429rem .28571429rem}.ui.search>.results .result{cursor:pointer;display:block;overflow:hidden;font-size:1em;padding:.85714286em 1.14285714em;color:rgba(0,0,0,.87);line-height:1.33;border-bottom:1px solid rgba(34,36,38,.1)}.ui.search>.results .result:last-child{border-bottom:none!important}.ui.search>.results .result .image{float:right;overflow:hidden;background:0 0;width:5em;height:3em;border-radius:.25em}.ui.search>.results .result .image img{display:block;width:auto;height:100%}.ui.search>.results .result .image+.content{margin:0 6em 0 0}.ui.search>.results .result .title{margin:-.14285714em 0 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-weight:700;font-size:1em;color:rgba(0,0,0,.85)}.ui.search>.results .result .description{margin-top:0;font-size:.92857143em;color:rgba(0,0,0,.4)}.ui.search>.results .result .price{float:right;color:#21ba45}.ui.search>.results>.message{padding:1em 1em}.ui.search>.results>.message .header{font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1rem;font-weight:700;color:rgba(0,0,0,.87)}.ui.search>.results>.message .description{margin-top:.25rem;font-size:1em;color:rgba(0,0,0,.87)}.ui.search>.results>.action{display:block;border-top:none;background:#f3f4f5;padding:.92857143em 1em;color:rgba(0,0,0,.87);font-weight:700;text-align:center}.ui.search>.prompt:focus{border-color:rgba(34,36,38,.35);background:#fff;color:rgba(0,0,0,.95)}.ui.loading.search .input>i.icon:before{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.loading.search .input>i.icon:after{position:absolute;content:'';top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;-webkit-animation:button-spin .6s linear;animation:button-spin .6s linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;border-radius:500rem;border-color:#767676 transparent transparent;border-style:solid;border-width:.2em;box-shadow:0 0 0 1px transparent}.ui.category.search>.results .category .result:hover,.ui.search>.results .result:hover{background:#f9fafb}.ui.search .action:hover{background:#e0e0e0}.ui.category.search>.results .category.active{background:#f3f4f5}.ui.category.search>.results .category.active>.name{color:rgba(0,0,0,.87)}.ui.category.search>.results .category .result.active,.ui.search>.results .result.active{position:relative;border-left-color:rgba(34,36,38,.1);background:#f3f4f5;box-shadow:none}.ui.search>.results .result.active .title{color:rgba(0,0,0,.85)}.ui.search>.results .result.active .description{color:rgba(0,0,0,.85)}.ui.search.selection .prompt{border-radius:.28571429rem}.ui.search.selection>.icon.input>.remove.icon{pointer-events:none;position:absolute;left:auto;opacity:0;color:'';top:0;right:0;-webkit-transition:color .1s ease,opacity .1s ease;transition:color .1s ease,opacity .1s ease}.ui.search.selection>.icon.input>.active.remove.icon{cursor:pointer;opacity:.8;pointer-events:auto}.ui.search.selection>.icon.input:not([class*="left icon"])>.icon~.remove.icon{right:1.85714em}.ui.search.selection>.icon.input>.remove.icon:hover{opacity:1;color:#db2828}.ui.category.search .results{width:28em}.ui.category.search>.results .category{background:#f3f4f5;box-shadow:none;border-bottom:1px solid rgba(34,36,38,.1);-webkit-transition:background .1s ease,border-color .1s ease;transition:background .1s ease,border-color .1s ease}.ui.category.search>.results .category:last-child{border-bottom:none}.ui.category.search>.results .category:first-child .name+.result{border-radius:0 .28571429rem 0 0}.ui.category.search>.results .category:last-child .result:last-child{border-radius:0 0 .28571429rem 0}.ui.category.search>.results .category .result{background:#fff;margin-left:100px;border-left:1px solid rgba(34,36,38,.15);border-bottom:1px solid rgba(34,36,38,.1);-webkit-transition:background .1s ease,border-color .1s ease;transition:background .1s ease,border-color .1s ease;padding:.85714286em 1.14285714em}.ui.category.search>.results .category:last-child .result:last-child{border-bottom:none}.ui.category.search>.results .category>.name{width:100px;background:0 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1em;float:1em;float:left;padding:.4em 1em;font-weight:700;color:rgba(0,0,0,.4)}.ui[class*="left aligned"].search>.results{right:auto;left:0}.ui[class*="right aligned"].search>.results{right:0;left:auto}.ui.fluid.search .results{width:100%}.ui.mini.search{font-size:.78571429em}.ui.small.search{font-size:.92857143em}.ui.search{font-size:1em}.ui.large.search{font-size:1.14285714em}.ui.big.search{font-size:1.28571429em}.ui.huge.search{font-size:1.42857143em}.ui.massive.search{font-size:1.71428571em}
--------------------------------------------------------------------------------
/public/css/components/site.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Site
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 | !function(e,n,o,i){e.site=e.fn.site=function(t){var s,r,a=(new Date).getTime(),c=[],l=arguments[0],u="string"==typeof l,d=[].slice.call(arguments,1),f=e.isPlainObject(t)?e.extend(!0,{},e.site.settings,t):e.extend({},e.site.settings),m=f.namespace,g=f.error,b="module-"+m,p=e(o),v=p,h=this,y=v.data(b);return s={initialize:function(){s.instantiate()},instantiate:function(){s.verbose("Storing instance of site",s),y=s,v.data(b,s)},normalize:function(){s.fix.console(),s.fix.requestAnimationFrame()},fix:{console:function(){s.debug("Normalizing window.console"),console!==i&&console.log!==i||(s.verbose("Console not available, normalizing events"),s.disable.console()),"undefined"!=typeof console.group&&"undefined"!=typeof console.groupEnd&&"undefined"!=typeof console.groupCollapsed||(s.verbose("Console group not available, normalizing events"),n.console.group=function(){},n.console.groupEnd=function(){},n.console.groupCollapsed=function(){}),"undefined"==typeof console.markTimeline&&(s.verbose("Mark timeline not available, normalizing events"),n.console.markTimeline=function(){})},consoleClear:function(){s.debug("Disabling programmatic console clearing"),n.console.clear=function(){}},requestAnimationFrame:function(){s.debug("Normalizing requestAnimationFrame"),n.requestAnimationFrame===i&&(s.debug("RequestAnimationFrame not available, normalizing event"),n.requestAnimationFrame=n.requestAnimationFrame||n.mozRequestAnimationFrame||n.webkitRequestAnimationFrame||n.msRequestAnimationFrame||function(e){setTimeout(e,0)})}},moduleExists:function(n){return e.fn[n]!==i&&e.fn[n].settings!==i},enabled:{modules:function(n){var o=[];return n=n||f.modules,e.each(n,function(e,n){s.moduleExists(n)&&o.push(n)}),o}},disabled:{modules:function(n){var o=[];return n=n||f.modules,e.each(n,function(e,n){s.moduleExists(n)||o.push(n)}),o}},change:{setting:function(n,o,t,r){t="string"==typeof t?"all"===t?f.modules:[t]:t||f.modules,r=r===i||r,e.each(t,function(i,t){var a,c=!s.moduleExists(t)||(e.fn[t].settings.namespace||!1);s.moduleExists(t)&&(s.verbose("Changing default setting",n,o,t),e.fn[t].settings[n]=o,r&&c&&(a=e(":data(module-"+c+")"),a.length>0&&(s.verbose("Modifying existing settings",a),a[t]("setting",n,o))))})},settings:function(n,o,t){o="string"==typeof o?[o]:o||f.modules,t=t===i||t,e.each(o,function(o,i){var r;s.moduleExists(i)&&(s.verbose("Changing default setting",n,i),e.extend(!0,e.fn[i].settings,n),t&&m&&(r=e(":data(module-"+m+")"),r.length>0&&(s.verbose("Modifying existing settings",r),r[i]("setting",n))))})}},enable:{console:function(){s.console(!0)},debug:function(e,n){e=e||f.modules,s.debug("Enabling debug for modules",e),s.change.setting("debug",!0,e,n)},verbose:function(e,n){e=e||f.modules,s.debug("Enabling verbose debug for modules",e),s.change.setting("verbose",!0,e,n)}},disable:{console:function(){s.console(!1)},debug:function(e,n){e=e||f.modules,s.debug("Disabling debug for modules",e),s.change.setting("debug",!1,e,n)},verbose:function(e,n){e=e||f.modules,s.debug("Disabling verbose debug for modules",e),s.change.setting("verbose",!1,e,n)}},console:function(e){if(e){if(y.cache.console===i)return void s.error(g.console);s.debug("Restoring console function"),n.console=y.cache.console}else s.debug("Disabling console function"),y.cache.console=n.console,n.console={clear:function(){},error:function(){},group:function(){},groupCollapsed:function(){},groupEnd:function(){},info:function(){},log:function(){},markTimeline:function(){},warn:function(){}}},destroy:function(){s.verbose("Destroying previous site for",v),v.removeData(b)},cache:{},setting:function(n,o){if(e.isPlainObject(n))e.extend(!0,f,n);else{if(o===i)return f[n];f[n]=o}},internal:function(n,o){if(e.isPlainObject(n))e.extend(!0,s,n);else{if(o===i)return s[n];s[n]=o}},debug:function(){f.debug&&(f.performance?s.performance.log(arguments):(s.debug=Function.prototype.bind.call(console.info,console,f.name+":"),s.debug.apply(console,arguments)))},verbose:function(){f.verbose&&f.debug&&(f.performance?s.performance.log(arguments):(s.verbose=Function.prototype.bind.call(console.info,console,f.name+":"),s.verbose.apply(console,arguments)))},error:function(){s.error=Function.prototype.bind.call(console.error,console,f.name+":"),s.error.apply(console,arguments)},performance:{log:function(e){var n,o,i;f.performance&&(n=(new Date).getTime(),i=a||n,o=n-i,a=n,c.push({Element:h,Name:e[0],Arguments:[].slice.call(e,1)||"","Execution Time":o})),clearTimeout(s.performance.timer),s.performance.timer=setTimeout(s.performance.display,500)},display:function(){var n=f.name+":",o=0;a=!1,clearTimeout(s.performance.timer),e.each(c,function(e,n){o+=n["Execution Time"]}),n+=" "+o+"ms",(console.group!==i||console.table!==i)&&c.length>0&&(console.groupCollapsed(n),console.table?console.table(c):e.each(c,function(e,n){console.log(n.Name+": "+n["Execution Time"]+"ms")}),console.groupEnd()),c=[]}},invoke:function(n,o,t){var a,c,l,u=y;return o=o||d,t=h||t,"string"==typeof n&&u!==i&&(n=n.split(/[\. ]/),a=n.length-1,e.each(n,function(o,t){var r=o!=a?t+n[o+1].charAt(0).toUpperCase()+n[o+1].slice(1):n;if(e.isPlainObject(u[r])&&o!=a)u=u[r];else{if(u[r]!==i)return c=u[r],!1;if(!e.isPlainObject(u[t])||o==a)return u[t]!==i?(c=u[t],!1):(s.error(g.method,n),!1);u=u[t]}})),e.isFunction(c)?l=c.apply(t,o):c!==i&&(l=c),e.isArray(r)?r.push(l):r!==i?r=[r,l]:l!==i&&(r=l),c}},u?(y===i&&s.initialize(),s.invoke(l)):(y!==i&&s.destroy(),s.initialize()),r!==i?r:this},e.site.settings={name:"Site",namespace:"site",error:{console:"Console cannot be restored, most likely it was overwritten outside of module",method:"The method you called is not defined."},debug:!1,verbose:!1,performance:!0,modules:["accordion","api","checkbox","dimmer","dropdown","embed","form","modal","nag","popup","rating","shape","sidebar","state","sticky","tab","transition","visit","visibility"],siteNamespace:"site",namespaceStub:{cache:{},config:{},sections:{},section:{},utilities:{}}},e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(n){return function(o){return!!e.data(o,n)}}):function(n,o,i){return!!e.data(n,i[3])}})}(jQuery,window,document);
--------------------------------------------------------------------------------
/public/css/components/comment.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Comment
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 |
11 |
12 | /*******************************
13 | Standard
14 | *******************************/
15 |
16 |
17 | /*--------------
18 | Comments
19 | ---------------*/
20 |
21 | .ui.comments {
22 | margin: 1.5em 0em;
23 | max-width: 650px;
24 | }
25 | .ui.comments:first-child {
26 | margin-top: 0em;
27 | }
28 | .ui.comments:last-child {
29 | margin-bottom: 0em;
30 | }
31 |
32 | /*--------------
33 | Comment
34 | ---------------*/
35 |
36 | .ui.comments .comment {
37 | position: relative;
38 | background: none;
39 | margin: 0.5em 0em 0em;
40 | padding: 0.5em 0em 0em;
41 | border: none;
42 | border-top: none;
43 | line-height: 1.2;
44 | }
45 | .ui.comments .comment:first-child {
46 | margin-top: 0em;
47 | padding-top: 0em;
48 | }
49 |
50 | /*--------------------
51 | Nested Comments
52 | ---------------------*/
53 |
54 | .ui.comments .comment .comments {
55 | margin: 0em 0em 0.5em 0.5em;
56 | padding: 1em 0em 1em 1em;
57 | }
58 | .ui.comments .comment .comments:before {
59 | position: absolute;
60 | top: 0px;
61 | left: 0px;
62 | }
63 | .ui.comments .comment .comments .comment {
64 | border: none;
65 | border-top: none;
66 | background: none;
67 | }
68 |
69 | /*--------------
70 | Avatar
71 | ---------------*/
72 |
73 | .ui.comments .comment .avatar {
74 | display: block;
75 | width: 2.5em;
76 | height: auto;
77 | float: left;
78 | margin: 0.2em 0em 0em;
79 | }
80 | .ui.comments .comment img.avatar,
81 | .ui.comments .comment .avatar img {
82 | display: block;
83 | margin: 0em auto;
84 | width: 100%;
85 | height: 100%;
86 | border-radius: 0.25rem;
87 | }
88 |
89 | /*--------------
90 | Content
91 | ---------------*/
92 |
93 | .ui.comments .comment > .content {
94 | display: block;
95 | }
96 |
97 | /* If there is an avatar move content over */
98 | .ui.comments .comment > .avatar ~ .content {
99 | margin-left: 3.5em;
100 | }
101 |
102 | /*--------------
103 | Author
104 | ---------------*/
105 |
106 | .ui.comments .comment .author {
107 | font-size: 1em;
108 | color: rgba(0, 0, 0, 0.87);
109 | font-weight: bold;
110 | }
111 | .ui.comments .comment a.author {
112 | cursor: pointer;
113 | }
114 | .ui.comments .comment a.author:hover {
115 | color: #1e70bf;
116 | }
117 |
118 | /*--------------
119 | Metadata
120 | ---------------*/
121 |
122 | .ui.comments .comment .metadata {
123 | display: inline-block;
124 | margin-left: 0.5em;
125 | color: rgba(0, 0, 0, 0.4);
126 | font-size: 0.875em;
127 | }
128 | .ui.comments .comment .metadata > * {
129 | display: inline-block;
130 | margin: 0em 0.5em 0em 0em;
131 | }
132 | .ui.comments .comment .metadata > :last-child {
133 | margin-right: 0em;
134 | }
135 |
136 | /*--------------------
137 | Comment Text
138 | ---------------------*/
139 |
140 | .ui.comments .comment .text {
141 | margin: 0.25em 0em 0.5em;
142 | font-size: 1em;
143 | word-wrap: break-word;
144 | color: rgba(0, 0, 0, 0.87);
145 | line-height: 1.3;
146 | }
147 |
148 | /*--------------------
149 | User Actions
150 | ---------------------*/
151 |
152 | .ui.comments .comment .actions {
153 | font-size: 0.875em;
154 | }
155 | .ui.comments .comment .actions a {
156 | cursor: pointer;
157 | display: inline-block;
158 | margin: 0em 0.75em 0em 0em;
159 | color: rgba(0, 0, 0, 0.4);
160 | }
161 | .ui.comments .comment .actions a:last-child {
162 | margin-right: 0em;
163 | }
164 | .ui.comments .comment .actions a.active,
165 | .ui.comments .comment .actions a:hover {
166 | color: rgba(0, 0, 0, 0.8);
167 | }
168 |
169 | /*--------------------
170 | Reply Form
171 | ---------------------*/
172 |
173 | .ui.comments > .reply.form {
174 | margin-top: 1em;
175 | }
176 | .ui.comments .comment .reply.form {
177 | width: 100%;
178 | margin-top: 1em;
179 | }
180 | .ui.comments .reply.form textarea {
181 | font-size: 1em;
182 | height: 12em;
183 | }
184 |
185 |
186 | /*******************************
187 | State
188 | *******************************/
189 |
190 | .ui.collapsed.comments,
191 | .ui.comments .collapsed.comments,
192 | .ui.comments .collapsed.comment {
193 | display: none;
194 | }
195 |
196 |
197 | /*******************************
198 | Variations
199 | *******************************/
200 |
201 |
202 | /*--------------------
203 | Threaded
204 | ---------------------*/
205 |
206 | .ui.threaded.comments .comment .comments {
207 | margin: -1.5em 0 -1em 1.25em;
208 | padding: 3em 0em 2em 2.25em;
209 | box-shadow: -1px 0px 0px rgba(34, 36, 38, 0.15);
210 | }
211 |
212 | /*--------------------
213 | Minimal
214 | ---------------------*/
215 |
216 | .ui.minimal.comments .comment .actions {
217 | opacity: 0;
218 | position: absolute;
219 | top: 0px;
220 | right: 0px;
221 | left: auto;
222 | -webkit-transition: opacity 0.2s ease;
223 | transition: opacity 0.2s ease;
224 | -webkit-transition-delay: 0.1s;
225 | transition-delay: 0.1s;
226 | }
227 | .ui.minimal.comments .comment > .content:hover > .actions {
228 | opacity: 1;
229 | }
230 |
231 | /*-------------------
232 | Sizes
233 | --------------------*/
234 |
235 | .ui.mini.comments {
236 | font-size: 0.78571429rem;
237 | }
238 | .ui.tiny.comments {
239 | font-size: 0.85714286rem;
240 | }
241 | .ui.small.comments {
242 | font-size: 0.92857143rem;
243 | }
244 | .ui.comments {
245 | font-size: 1rem;
246 | }
247 | .ui.large.comments {
248 | font-size: 1.14285714rem;
249 | }
250 | .ui.big.comments {
251 | font-size: 1.28571429rem;
252 | }
253 | .ui.huge.comments {
254 | font-size: 1.42857143rem;
255 | }
256 | .ui.massive.comments {
257 | font-size: 1.71428571rem;
258 | }
259 |
260 |
261 | /*******************************
262 | Theme Overrides
263 | *******************************/
264 |
265 |
266 |
267 | /*******************************
268 | User Variable Overrides
269 | *******************************/
270 |
271 |
--------------------------------------------------------------------------------
/public/css/components/modal.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Modal
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.modal{display:none;position:fixed;z-index:1001;top:50%;left:50%;text-align:left;background:#fff;border:none;box-shadow:1px 3px 3px 0 rgba(0,0,0,.2),1px 3px 15px 2px rgba(0,0,0,.2);-webkit-transform-origin:50% 25%;transform-origin:50% 25%;border-radius:.28571429rem;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text;will-change:top,left,margin,transform,opacity}.ui.modal>.icon:first-child+*,.ui.modal>:first-child:not(.icon){border-top-left-radius:.28571429rem;border-top-right-radius:.28571429rem}.ui.modal>:last-child{border-bottom-left-radius:.28571429rem;border-bottom-right-radius:.28571429rem}.ui.modal>.close{cursor:pointer;position:absolute;top:-2.5rem;right:-2.5rem;z-index:1;opacity:.8;font-size:1.25em;color:#fff;width:2.25rem;height:2.25rem;padding:.625rem 0 0 0}.ui.modal>.close:hover{opacity:1}.ui.modal>.header{display:block;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;background:#fff;margin:0;padding:1.25rem 1.5rem;box-shadow:none;color:rgba(0,0,0,.85);border-bottom:1px solid rgba(34,36,38,.15)}.ui.modal>.header:not(.ui){font-size:1.42857143rem;line-height:1.28571429em;font-weight:700}.ui.modal>.content{display:block;width:100%;font-size:1em;line-height:1.4;padding:1.5rem;background:#fff}.ui.modal>.image.content{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.ui.modal>.content>.image{display:block;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;width:'';-ms-flex-item-align:top;-ms-grid-row-align:top;align-self:top}.ui.modal>[class*="top aligned"]{-ms-flex-item-align:top;-ms-grid-row-align:top;align-self:top}.ui.modal>[class*="middle aligned"]{-ms-flex-item-align:middle;-ms-grid-row-align:middle;align-self:middle}.ui.modal>[class*=stretched]{-ms-flex-item-align:stretch;-ms-grid-row-align:stretch;align-self:stretch}.ui.modal>.content>.description{display:block;-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto;min-width:0;-ms-flex-item-align:top;-ms-grid-row-align:top;align-self:top}.ui.modal>.content>.icon+.description,.ui.modal>.content>.image+.description{-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;min-width:'';width:auto;padding-left:2em}.ui.modal>.content>.image>i.icon{margin:0;opacity:1;width:auto;line-height:1;font-size:8rem}.ui.modal>.actions{background:#f9fafb;padding:1rem 1rem;border-top:1px solid rgba(34,36,38,.15);text-align:right}.ui.modal .actions>.button{margin-left:.75em}@media only screen and (max-width:767px){.ui.modal{width:95%;margin:0 0 0 -47.5%}}@media only screen and (min-width:768px){.ui.modal{width:88%;margin:0 0 0 -44%}}@media only screen and (min-width:992px){.ui.modal{width:850px;margin:0 0 0 -425px}}@media only screen and (min-width:1200px){.ui.modal{width:900px;margin:0 0 0 -450px}}@media only screen and (min-width:1920px){.ui.modal{width:950px;margin:0 0 0 -475px}}@media only screen and (max-width:991px){.ui.modal>.header{padding-right:2.25rem}.ui.modal>.close{top:1.0535rem;right:1rem;color:rgba(0,0,0,.87)}}@media only screen and (max-width:767px){.ui.modal>.header{padding:.75rem 1rem!important;padding-right:2.25rem!important}.ui.modal>.content{display:block;padding:1rem!important}.ui.modal>.close{top:.5rem!important;right:.5rem!important}.ui.modal .image.content{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ui.modal .content>.image{display:block;max-width:100%;margin:0 auto!important;text-align:center;padding:0 0 1rem!important}.ui.modal>.content>.image>i.icon{font-size:5rem;text-align:center}.ui.modal .content>.description{display:block;width:100%!important;margin:0!important;padding:1rem 0!important;box-shadow:none}.ui.modal>.actions{padding:1rem 1rem 0!important}.ui.modal .actions>.button,.ui.modal .actions>.buttons{margin-bottom:1rem}}.ui.inverted.dimmer>.ui.modal{box-shadow:1px 3px 10px 2px rgba(0,0,0,.2)}.ui.basic.modal{background-color:transparent;border:none;border-radius:0;box-shadow:none!important;color:#fff}.ui.basic.modal>.actions,.ui.basic.modal>.content,.ui.basic.modal>.header{background-color:transparent}.ui.basic.modal>.header{color:#fff}.ui.basic.modal>.close{top:1rem;right:1.5rem}.ui.inverted.dimmer>.basic.modal{color:rgba(0,0,0,.87)}.ui.inverted.dimmer>.ui.basic.modal>.header{color:rgba(0,0,0,.85)}@media only screen and (max-width:991px){.ui.basic.modal>.close{color:#fff}}.ui.active.modal{display:block}.scrolling.dimmable.dimmed{overflow:hidden}.scrolling.dimmable.dimmed>.dimmer{overflow:auto;-webkit-overflow-scrolling:touch}.scrolling.dimmable>.dimmer{position:fixed}.modals.dimmer .ui.scrolling.modal{position:static!important;margin:3.5rem auto!important}.scrolling.undetached.dimmable.dimmed{overflow:auto;-webkit-overflow-scrolling:touch}.scrolling.undetached.dimmable.dimmed>.dimmer{overflow:hidden}.scrolling.undetached.dimmable .ui.scrolling.modal{position:absolute;left:50%;margin-top:3.5rem!important}.undetached.dimmable.dimmed>.pusher{z-index:auto}@media only screen and (max-width:991px){.modals.dimmer .ui.scrolling.modal{margin-top:1rem!important;margin-bottom:1rem!important}}.ui.fullscreen.modal{width:95%!important;left:2.5%!important;margin:1em auto}.ui.fullscreen.scrolling.modal{left:0!important}.ui.fullscreen.modal>.header{padding-right:2.25rem}.ui.fullscreen.modal>.close{top:1.0535rem;right:1rem;color:rgba(0,0,0,.87)}.ui.modal{font-size:1rem}.ui.small.modal>.header:not(.ui){font-size:1.3em}@media only screen and (max-width:767px){.ui.small.modal{width:95%;margin:0 0 0 -47.5%}}@media only screen and (min-width:768px){.ui.small.modal{width:70.4%;margin:0 0 0 -35.2%}}@media only screen and (min-width:992px){.ui.small.modal{width:680px;margin:0 0 0 -340px}}@media only screen and (min-width:1200px){.ui.small.modal{width:720px;margin:0 0 0 -360px}}@media only screen and (min-width:1920px){.ui.small.modal{width:760px;margin:0 0 0 -380px}}.ui.large.modal>.header{font-size:1.6em}@media only screen and (max-width:767px){.ui.large.modal{width:95%;margin:0 0 0 -47.5%}}@media only screen and (min-width:768px){.ui.large.modal{width:88%;margin:0 0 0 -44%}}@media only screen and (min-width:992px){.ui.large.modal{width:1020px;margin:0 0 0 -510px}}@media only screen and (min-width:1200px){.ui.large.modal{width:1080px;margin:0 0 0 -540px}}@media only screen and (min-width:1920px){.ui.large.modal{width:1140px;margin:0 0 0 -570px}}
--------------------------------------------------------------------------------
/public/css/components/message.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Message
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.message{position:relative;min-height:1em;margin:1em 0;background:#f8f8f9;padding:1em 1.5em;line-height:1.4285em;color:rgba(0,0,0,.87);-webkit-transition:opacity .1s ease,color .1s ease,background .1s ease,box-shadow .1s ease;transition:opacity .1s ease,color .1s ease,background .1s ease,box-shadow .1s ease;border-radius:.28571429rem;box-shadow:0 0 0 1px rgba(34,36,38,.22) inset,0 0 0 0 transparent}.ui.message:first-child{margin-top:0}.ui.message:last-child{margin-bottom:0}.ui.message .header{display:block;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-weight:700;margin:-.14285714em 0 0 0}.ui.message .header:not(.ui){font-size:1.14285714em}.ui.message p{opacity:.85;margin:.75em 0}.ui.message p:first-child{margin-top:0}.ui.message p:last-child{margin-bottom:0}.ui.message .header+p{margin-top:.25em}.ui.message .list:not(.ui){text-align:left;padding:0;opacity:.85;list-style-position:inside;margin:.5em 0 0}.ui.message .list:not(.ui):first-child{margin-top:0}.ui.message .list:not(.ui):last-child{margin-bottom:0}.ui.message .list:not(.ui) li{position:relative;list-style-type:none;margin:0 0 .3em 1em;padding:0}.ui.message .list:not(.ui) li:before{position:absolute;content:'•';left:-1em;height:100%;vertical-align:baseline}.ui.message .list:not(.ui) li:last-child{margin-bottom:0}.ui.message>.icon{margin-right:.6em}.ui.message>.close.icon{cursor:pointer;position:absolute;margin:0;top:.78575em;right:.5em;opacity:.7;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.ui.message>.close.icon:hover{opacity:1}.ui.message>:first-child{margin-top:0}.ui.message>:last-child{margin-bottom:0}.ui.dropdown .menu>.message{margin:0 -1px}.ui.visible.visible.visible.visible.message{display:block}.ui.icon.visible.visible.visible.visible.message{display:-webkit-box;display:-ms-flexbox;display:flex}.ui.hidden.hidden.hidden.hidden.message{display:none}.ui.compact.message{display:inline-block}.ui.attached.message{margin-bottom:-1px;border-radius:.28571429rem .28571429rem 0 0;box-shadow:0 0 0 1px rgba(34,36,38,.15) inset;margin-left:-1px;margin-right:-1px}.ui.attached+.ui.attached.message:not(.top):not(.bottom){margin-top:-1px;border-radius:0}.ui.bottom.attached.message{margin-top:-1px;border-radius:0 0 .28571429rem .28571429rem;box-shadow:0 0 0 1px rgba(34,36,38,.15) inset,0 1px 2px 0 rgba(34,36,38,.15)}.ui.bottom.attached.message:not(:last-child){margin-bottom:1em}.ui.attached.icon.message{width:auto}.ui.icon.message{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ui.icon.message>.icon:not(.close){display:block;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;line-height:1;vertical-align:middle;font-size:3em;opacity:.8}.ui.icon.message>.content{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;vertical-align:middle}.ui.icon.message .icon:not(.close)+.content{padding-left:0}.ui.icon.message .circular.icon{width:1em}.ui.floating.message{box-shadow:0 0 0 1px rgba(34,36,38,.22) inset,0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)}.ui.black.message{background-color:#1b1c1d;color:rgba(255,255,255,.9)}.ui.positive.message{background-color:#fcfff5;color:#2c662d}.ui.attached.positive.message,.ui.positive.message{box-shadow:0 0 0 1px #a3c293 inset,0 0 0 0 transparent}.ui.positive.message .header{color:#1a531b}.ui.negative.message{background-color:#fff6f6;color:#9f3a38}.ui.attached.negative.message,.ui.negative.message{box-shadow:0 0 0 1px #e0b4b4 inset,0 0 0 0 transparent}.ui.negative.message .header{color:#912d2b}.ui.info.message{background-color:#f8ffff;color:#276f86}.ui.attached.info.message,.ui.info.message{box-shadow:0 0 0 1px #a9d5de inset,0 0 0 0 transparent}.ui.info.message .header{color:#0e566c}.ui.warning.message{background-color:#fffaf3;color:#573a08}.ui.attached.warning.message,.ui.warning.message{box-shadow:0 0 0 1px #c9ba9b inset,0 0 0 0 transparent}.ui.warning.message .header{color:#794b02}.ui.error.message{background-color:#fff6f6;color:#9f3a38}.ui.attached.error.message,.ui.error.message{box-shadow:0 0 0 1px #e0b4b4 inset,0 0 0 0 transparent}.ui.error.message .header{color:#912d2b}.ui.success.message{background-color:#fcfff5;color:#2c662d}.ui.attached.success.message,.ui.success.message{box-shadow:0 0 0 1px #a3c293 inset,0 0 0 0 transparent}.ui.success.message .header{color:#1a531b}.ui.black.message,.ui.inverted.message{background-color:#1b1c1d;color:rgba(255,255,255,.9)}.ui.red.message{background-color:#ffe8e6;color:#db2828;box-shadow:0 0 0 1px #db2828 inset,0 0 0 0 transparent}.ui.red.message .header{color:#c82121}.ui.orange.message{background-color:#ffedde;color:#f2711c;box-shadow:0 0 0 1px #f2711c inset,0 0 0 0 transparent}.ui.orange.message .header{color:#e7640d}.ui.yellow.message{background-color:#fff8db;color:#b58105;box-shadow:0 0 0 1px #b58105 inset,0 0 0 0 transparent}.ui.yellow.message .header{color:#9c6f04}.ui.olive.message{background-color:#fbfdef;color:#8abc1e;box-shadow:0 0 0 1px #8abc1e inset,0 0 0 0 transparent}.ui.olive.message .header{color:#7aa61a}.ui.green.message{background-color:#e5f9e7;color:#1ebc30;box-shadow:0 0 0 1px #1ebc30 inset,0 0 0 0 transparent}.ui.green.message .header{color:#1aa62a}.ui.teal.message{background-color:#e1f7f7;color:#10a3a3;box-shadow:0 0 0 1px #10a3a3 inset,0 0 0 0 transparent}.ui.teal.message .header{color:#0e8c8c}.ui.blue.message{background-color:#dff0ff;color:#2185d0;box-shadow:0 0 0 1px #2185d0 inset,0 0 0 0 transparent}.ui.blue.message .header{color:#1e77ba}.ui.violet.message{background-color:#eae7ff;color:#6435c9;box-shadow:0 0 0 1px #6435c9 inset,0 0 0 0 transparent}.ui.violet.message .header{color:#5a30b5}.ui.purple.message{background-color:#f6e7ff;color:#a333c8;box-shadow:0 0 0 1px #a333c8 inset,0 0 0 0 transparent}.ui.purple.message .header{color:#922eb4}.ui.pink.message{background-color:#ffe3fb;color:#e03997;box-shadow:0 0 0 1px #e03997 inset,0 0 0 0 transparent}.ui.pink.message .header{color:#dd238b}.ui.brown.message{background-color:#f1e2d3;color:#a5673f;box-shadow:0 0 0 1px #a5673f inset,0 0 0 0 transparent}.ui.brown.message .header{color:#935b38}.ui.mini.message{font-size:.78571429em}.ui.tiny.message{font-size:.85714286em}.ui.small.message{font-size:.92857143em}.ui.message{font-size:1em}.ui.large.message{font-size:1.14285714em}.ui.big.message{font-size:1.28571429em}.ui.huge.message{font-size:1.42857143em}.ui.massive.message{font-size:1.71428571em}
--------------------------------------------------------------------------------
/public/css/components/accordion.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Accordion
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.accordion,.ui.accordion .accordion{max-width:100%}.ui.accordion .accordion{margin:1em 0 0;padding:0}.ui.accordion .accordion .title,.ui.accordion .title{cursor:pointer}.ui.accordion .title:not(.ui){padding:.5em 0;font-family:Lato,'Helvetica Neue',Arial,Helvetica,sans-serif;font-size:1em;color:rgba(0,0,0,.87)}.ui.accordion .accordion .title~.content,.ui.accordion .title~.content{display:none}.ui.accordion:not(.styled) .accordion .title~.content:not(.ui),.ui.accordion:not(.styled) .title~.content:not(.ui){margin:'';padding:.5em 0 1em}.ui.accordion:not(.styled) .title~.content:not(.ui):last-child{padding-bottom:0}.ui.accordion .accordion .title .dropdown.icon,.ui.accordion .title .dropdown.icon{display:inline-block;float:none;opacity:1;width:1.25em;height:1em;margin:0 .25rem 0 0;padding:0;font-size:1em;-webkit-transition:opacity .1s ease,-webkit-transform .1s ease;transition:opacity .1s ease,-webkit-transform .1s ease;transition:transform .1s ease,opacity .1s ease;transition:transform .1s ease,opacity .1s ease,-webkit-transform .1s ease;vertical-align:baseline;-webkit-transform:none;transform:none}.ui.accordion.menu .item .title{display:block;padding:0}.ui.accordion.menu .item .title>.dropdown.icon{float:right;margin:.21425em 0 0 1em;-webkit-transform:rotate(180deg);transform:rotate(180deg)}.ui.accordion .ui.header .dropdown.icon{font-size:1em;margin:0 .25rem 0 0}.ui.accordion .accordion .active.title .dropdown.icon,.ui.accordion .active.title .dropdown.icon{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.ui.accordion.menu .item .active.title>.dropdown.icon{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.ui.styled.accordion{width:600px}.ui.styled.accordion,.ui.styled.accordion .accordion{border-radius:.28571429rem;background:#fff;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15)}.ui.styled.accordion .accordion .title,.ui.styled.accordion .title{margin:0;padding:.75em 1em;color:rgba(0,0,0,.4);font-weight:700;border-top:1px solid rgba(34,36,38,.15);-webkit-transition:background .1s ease,color .1s ease;transition:background .1s ease,color .1s ease}.ui.styled.accordion .accordion .title:first-child,.ui.styled.accordion>.title:first-child{border-top:none}.ui.styled.accordion .accordion .content,.ui.styled.accordion .content{margin:0;padding:.5em 1em 1.5em}.ui.styled.accordion .accordion .content{padding:0;padding:.5em 1em 1.5em}.ui.styled.accordion .accordion .active.title,.ui.styled.accordion .accordion .title:hover,.ui.styled.accordion .active.title,.ui.styled.accordion .title:hover{background:0 0;color:rgba(0,0,0,.87)}.ui.styled.accordion .accordion .active.title,.ui.styled.accordion .accordion .title:hover{background:0 0;color:rgba(0,0,0,.87)}.ui.styled.accordion .active.title{background:0 0;color:rgba(0,0,0,.95)}.ui.styled.accordion .accordion .active.title{background:0 0;color:rgba(0,0,0,.95)}.ui.accordion .accordion .active.content,.ui.accordion .active.content{display:block}.ui.fluid.accordion,.ui.fluid.accordion .accordion{width:100%}.ui.inverted.accordion .title:not(.ui){color:rgba(255,255,255,.9)}@font-face{font-family:Accordion;src:url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMggjB5AAAAC8AAAAYGNtYXAPfOIKAAABHAAAAExnYXNwAAAAEAAAAWgAAAAIZ2x5Zryj6HgAAAFwAAAAyGhlYWT/0IhHAAACOAAAADZoaGVhApkB5wAAAnAAAAAkaG10eAJuABIAAAKUAAAAGGxvY2EAjABWAAACrAAAAA5tYXhwAAgAFgAAArwAAAAgbmFtZfC1n04AAALcAAABPHBvc3QAAwAAAAAEGAAAACAAAwIAAZAABQAAAUwBZgAAAEcBTAFmAAAA9QAZAIQAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADw2gHg/+D/4AHgACAAAAABAAAAAAAAAAAAAAAgAAAAAAACAAAAAwAAABQAAwABAAAAFAAEADgAAAAKAAgAAgACAAEAIPDa//3//wAAAAAAIPDZ//3//wAB/+MPKwADAAEAAAAAAAAAAAAAAAEAAf//AA8AAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQASAEkAtwFuABMAADc0PwE2FzYXFh0BFAcGJwYvASY1EgaABQgHBQYGBQcIBYAG2wcGfwcBAQcECf8IBAcBAQd/BgYAAAAAAQAAAEkApQFuABMAADcRNDc2MzIfARYVFA8BBiMiJyY1AAUGBwgFgAYGgAUIBwYFWwEACAUGBoAFCAcFgAYGBQcAAAABAAAAAQAAqWYls18PPPUACwIAAAAAAM/9o+4AAAAAz/2j7gAAAAAAtwFuAAAACAACAAAAAAAAAAEAAAHg/+AAAAIAAAAAAAC3AAEAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAQAAAAC3ABIAtwAAAAAAAAAKABQAHgBCAGQAAAABAAAABgAUAAEAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADAAAAAEAAAAAAAIADgBAAAEAAAAAAAMADAAiAAEAAAAAAAQADABOAAEAAAAAAAUAFgAMAAEAAAAAAAYABgAuAAEAAAAAAAoANABaAAMAAQQJAAEADAAAAAMAAQQJAAIADgBAAAMAAQQJAAMADAAiAAMAAQQJAAQADABOAAMAAQQJAAUAFgAMAAMAAQQJAAYADAA0AAMAAQQJAAoANABaAHIAYQB0AGkAbgBnAFYAZQByAHMAaQBvAG4AIAAxAC4AMAByAGEAdABpAG4AZ3JhdGluZwByAGEAdABpAG4AZwBSAGUAZwB1AGwAYQByAHIAYQB0AGkAbgBnAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format('truetype'),url(data:application/font-woff;charset=utf-8;base64,d09GRk9UVE8AAASwAAoAAAAABGgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAAA9AAAAS0AAAEtFpovuE9TLzIAAAIkAAAAYAAAAGAIIweQY21hcAAAAoQAAABMAAAATA984gpnYXNwAAAC0AAAAAgAAAAIAAAAEGhlYWQAAALYAAAANgAAADb/0IhHaGhlYQAAAxAAAAAkAAAAJAKZAedobXR4AAADNAAAABgAAAAYAm4AEm1heHAAAANMAAAABgAAAAYABlAAbmFtZQAAA1QAAAE8AAABPPC1n05wb3N0AAAEkAAAACAAAAAgAAMAAAEABAQAAQEBB3JhdGluZwABAgABADr4HAL4GwP4GAQeCgAZU/+Lix4KABlT/4uLDAeLa/iU+HQFHQAAAHkPHQAAAH4RHQAAAAkdAAABJBIABwEBBw0PERQZHnJhdGluZ3JhdGluZ3UwdTF1MjB1RjBEOXVGMERBAAACAYkABAAGAQEEBwoNVp38lA78lA78lA77lA773Z33bxWLkI2Qj44I9xT3FAWOj5CNkIuQi4+JjoePiI2Gi4YIi/uUBYuGiYeHiIiHh4mGi4aLho2Ijwj7FPcUBYeOiY+LkAgO+92L5hWL95QFi5CNkI6Oj4+PjZCLkIuQiY6HCPcU+xQFj4iNhouGi4aJh4eICPsU+xQFiIeGiYaLhouHjYePiI6Jj4uQCA74lBT4lBWLDAoAAAAAAwIAAZAABQAAAUwBZgAAAEcBTAFmAAAA9QAZAIQAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADw2gHg/+D/4AHgACAAAAABAAAAAAAAAAAAAAAgAAAAAAACAAAAAwAAABQAAwABAAAAFAAEADgAAAAKAAgAAgACAAEAIPDa//3//wAAAAAAIPDZ//3//wAB/+MPKwADAAEAAAAAAAAAAAAAAAEAAf//AA8AAQAAAAEAADfYOJZfDzz1AAsCAAAAAADP/aPuAAAAAM/9o+4AAAAAALcBbgAAAAgAAgAAAAAAAAABAAAB4P/gAAACAAAAAAAAtwABAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAEAAAAAtwASALcAAAAAUAAABgAAAAAADgCuAAEAAAAAAAEADAAAAAEAAAAAAAIADgBAAAEAAAAAAAMADAAiAAEAAAAAAAQADABOAAEAAAAAAAUAFgAMAAEAAAAAAAYABgAuAAEAAAAAAAoANABaAAMAAQQJAAEADAAAAAMAAQQJAAIADgBAAAMAAQQJAAMADAAiAAMAAQQJAAQADABOAAMAAQQJAAUAFgAMAAMAAQQJAAYADAA0AAMAAQQJAAoANABaAHIAYQB0AGkAbgBnAFYAZQByAHMAaQBvAG4AIAAxAC4AMAByAGEAdABpAG4AZ3JhdGluZwByAGEAdABpAG4AZwBSAGUAZwB1AGwAYQByAHIAYQB0AGkAbgBnAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) format('woff');font-weight:400;font-style:normal}.ui.accordion .accordion .title .dropdown.icon,.ui.accordion .title .dropdown.icon{font-family:Accordion;line-height:1;-webkit-backface-visibility:hidden;backface-visibility:hidden;font-weight:400;font-style:normal;text-align:center}.ui.accordion .accordion .title .dropdown.icon:before,.ui.accordion .title .dropdown.icon:before{content:'\f0da'}
--------------------------------------------------------------------------------
/public/css/components/image.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Image
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 |
11 |
12 | /*******************************
13 | Image
14 | *******************************/
15 |
16 | .ui.image {
17 | position: relative;
18 | display: inline-block;
19 | vertical-align: middle;
20 | max-width: 100%;
21 | background-color: transparent;
22 | }
23 | img.ui.image {
24 | display: block;
25 | }
26 | .ui.image svg,
27 | .ui.image img {
28 | display: block;
29 | max-width: 100%;
30 | height: auto;
31 | }
32 |
33 |
34 | /*******************************
35 | States
36 | *******************************/
37 |
38 | .ui.hidden.images,
39 | .ui.hidden.image {
40 | display: none;
41 | }
42 | .ui.hidden.transition.images,
43 | .ui.hidden.transition.image {
44 | display: block;
45 | visibility: hidden;
46 | }
47 | .ui.disabled.images,
48 | .ui.disabled.image {
49 | cursor: default;
50 | opacity: 0.45;
51 | }
52 |
53 |
54 | /*******************************
55 | Variations
56 | *******************************/
57 |
58 |
59 | /*--------------
60 | Inline
61 | ---------------*/
62 |
63 | .ui.inline.image,
64 | .ui.inline.image svg,
65 | .ui.inline.image img {
66 | display: inline-block;
67 | }
68 |
69 | /*------------------
70 | Vertical Aligned
71 | -------------------*/
72 |
73 | .ui.top.aligned.images .image,
74 | .ui.top.aligned.image,
75 | .ui.top.aligned.image svg,
76 | .ui.top.aligned.image img {
77 | display: inline-block;
78 | vertical-align: top;
79 | }
80 | .ui.middle.aligned.images .image,
81 | .ui.middle.aligned.image,
82 | .ui.middle.aligned.image svg,
83 | .ui.middle.aligned.image img {
84 | display: inline-block;
85 | vertical-align: middle;
86 | }
87 | .ui.bottom.aligned.images .image,
88 | .ui.bottom.aligned.image,
89 | .ui.bottom.aligned.image svg,
90 | .ui.bottom.aligned.image img {
91 | display: inline-block;
92 | vertical-align: bottom;
93 | }
94 |
95 | /*--------------
96 | Rounded
97 | ---------------*/
98 |
99 | .ui.rounded.images .image,
100 | .ui.rounded.image,
101 | .ui.rounded.images .image > *,
102 | .ui.rounded.image > * {
103 | border-radius: 0.3125em;
104 | }
105 |
106 | /*--------------
107 | Bordered
108 | ---------------*/
109 |
110 | .ui.bordered.images .image,
111 | .ui.bordered.images img,
112 | .ui.bordered.images svg,
113 | .ui.bordered.image img,
114 | .ui.bordered.image svg,
115 | img.ui.bordered.image {
116 | border: 1px solid rgba(0, 0, 0, 0.1);
117 | }
118 |
119 | /*--------------
120 | Circular
121 | ---------------*/
122 |
123 | .ui.circular.images,
124 | .ui.circular.image {
125 | overflow: hidden;
126 | }
127 | .ui.circular.images .image,
128 | .ui.circular.image,
129 | .ui.circular.images .image > *,
130 | .ui.circular.image > * {
131 | border-radius: 500rem;
132 | }
133 |
134 | /*--------------
135 | Fluid
136 | ---------------*/
137 |
138 | .ui.fluid.images,
139 | .ui.fluid.image,
140 | .ui.fluid.images img,
141 | .ui.fluid.images svg,
142 | .ui.fluid.image svg,
143 | .ui.fluid.image img {
144 | display: block;
145 | width: 100%;
146 | height: auto;
147 | }
148 |
149 | /*--------------
150 | Avatar
151 | ---------------*/
152 |
153 | .ui.avatar.images .image,
154 | .ui.avatar.images img,
155 | .ui.avatar.images svg,
156 | .ui.avatar.image img,
157 | .ui.avatar.image svg,
158 | .ui.avatar.image {
159 | margin-right: 0.25em;
160 | display: inline-block;
161 | width: 2em;
162 | height: 2em;
163 | border-radius: 500rem;
164 | }
165 |
166 | /*-------------------
167 | Spaced
168 | --------------------*/
169 |
170 | .ui.spaced.image {
171 | display: inline-block !important;
172 | margin-left: 0.5em;
173 | margin-right: 0.5em;
174 | }
175 | .ui[class*="left spaced"].image {
176 | margin-left: 0.5em;
177 | margin-right: 0em;
178 | }
179 | .ui[class*="right spaced"].image {
180 | margin-left: 0em;
181 | margin-right: 0.5em;
182 | }
183 |
184 | /*-------------------
185 | Floated
186 | --------------------*/
187 |
188 | .ui.floated.image,
189 | .ui.floated.images {
190 | float: left;
191 | margin-right: 1em;
192 | margin-bottom: 1em;
193 | }
194 | .ui.right.floated.images,
195 | .ui.right.floated.image {
196 | float: right;
197 | margin-right: 0em;
198 | margin-bottom: 1em;
199 | margin-left: 1em;
200 | }
201 | .ui.floated.images:last-child,
202 | .ui.floated.image:last-child {
203 | margin-bottom: 0em;
204 | }
205 | .ui.centered.images,
206 | .ui.centered.image {
207 | margin-left: auto;
208 | margin-right: auto;
209 | }
210 |
211 | /*--------------
212 | Sizes
213 | ---------------*/
214 |
215 | .ui.mini.images .image,
216 | .ui.mini.images img,
217 | .ui.mini.images svg,
218 | .ui.mini.image {
219 | width: 35px;
220 | height: auto;
221 | font-size: 0.78571429rem;
222 | }
223 | .ui.tiny.images .image,
224 | .ui.tiny.images img,
225 | .ui.tiny.images svg,
226 | .ui.tiny.image {
227 | width: 80px;
228 | height: auto;
229 | font-size: 0.85714286rem;
230 | }
231 | .ui.small.images .image,
232 | .ui.small.images img,
233 | .ui.small.images svg,
234 | .ui.small.image {
235 | width: 150px;
236 | height: auto;
237 | font-size: 0.92857143rem;
238 | }
239 | .ui.medium.images .image,
240 | .ui.medium.images img,
241 | .ui.medium.images svg,
242 | .ui.medium.image {
243 | width: 300px;
244 | height: auto;
245 | font-size: 1rem;
246 | }
247 | .ui.large.images .image,
248 | .ui.large.images img,
249 | .ui.large.images svg,
250 | .ui.large.image {
251 | width: 450px;
252 | height: auto;
253 | font-size: 1.14285714rem;
254 | }
255 | .ui.big.images .image,
256 | .ui.big.images img,
257 | .ui.big.images svg,
258 | .ui.big.image {
259 | width: 600px;
260 | height: auto;
261 | font-size: 1.28571429rem;
262 | }
263 | .ui.huge.images .image,
264 | .ui.huge.images img,
265 | .ui.huge.images svg,
266 | .ui.huge.image {
267 | width: 800px;
268 | height: auto;
269 | font-size: 1.42857143rem;
270 | }
271 | .ui.massive.images .image,
272 | .ui.massive.images img,
273 | .ui.massive.images svg,
274 | .ui.massive.image {
275 | width: 960px;
276 | height: auto;
277 | font-size: 1.71428571rem;
278 | }
279 |
280 |
281 | /*******************************
282 | Groups
283 | *******************************/
284 |
285 | .ui.images {
286 | font-size: 0em;
287 | margin: 0em -0.25rem 0rem;
288 | }
289 | .ui.images .image,
290 | .ui.images img,
291 | .ui.images svg {
292 | display: inline-block;
293 | margin: 0em 0.25rem 0.5rem;
294 | }
295 |
296 |
297 | /*******************************
298 | Theme Overrides
299 | *******************************/
300 |
301 |
302 |
303 | /*******************************
304 | Site Overrides
305 | *******************************/
306 |
307 |
--------------------------------------------------------------------------------
/public/css/components/accordion.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Accordion
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 | !function(e,n,t,i){"use strict";n="undefined"!=typeof n&&n.Math==Math?n:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")(),e.fn.accordion=function(t){var o,a=e(this),s=(new Date).getTime(),r=[],c=arguments[0],l="string"==typeof c,u=[].slice.call(arguments,1);n.requestAnimationFrame||n.mozRequestAnimationFrame||n.webkitRequestAnimationFrame||n.msRequestAnimationFrame||function(e){setTimeout(e,0)};return a.each(function(){var d,g,f=e.isPlainObject(t)?e.extend(!0,{},e.fn.accordion.settings,t):e.extend({},e.fn.accordion.settings),m=f.className,p=f.namespace,h=f.selector,v=f.error,b="."+p,y="module-"+p,C=a.selector||"",O=e(this),x=O.find(h.title),F=O.find(h.content),A=this,T=O.data(y);g={initialize:function(){g.debug("Initializing",O),g.bind.events(),f.observeChanges&&g.observeChanges(),g.instantiate()},instantiate:function(){T=g,O.data(y,g)},destroy:function(){g.debug("Destroying previous instance",O),O.off(b).removeData(y)},refresh:function(){x=O.find(h.title),F=O.find(h.content)},observeChanges:function(){"MutationObserver"in n&&(d=new MutationObserver(function(e){g.debug("DOM tree modified, updating selector cache"),g.refresh()}),d.observe(A,{childList:!0,subtree:!0}),g.debug("Setting up mutation observer",d))},bind:{events:function(){g.debug("Binding delegated events"),O.on(f.on+b,h.trigger,g.event.click)}},event:{click:function(){g.toggle.call(this)}},toggle:function(n){var t=n!==i?"number"==typeof n?x.eq(n):e(n).closest(h.title):e(this).closest(h.title),o=t.next(F),a=o.hasClass(m.animating),s=o.hasClass(m.active),r=s&&!a,c=!s&&a;g.debug("Toggling visibility of content",t),r||c?f.collapsible?g.close.call(t):g.debug("Cannot close accordion content collapsing is disabled"):g.open.call(t)},open:function(n){var t=n!==i?"number"==typeof n?x.eq(n):e(n).closest(h.title):e(this).closest(h.title),o=t.next(F),a=o.hasClass(m.animating),s=o.hasClass(m.active),r=s||a;return r?void g.debug("Accordion already open, skipping",o):(g.debug("Opening accordion content",t),f.onOpening.call(o),f.exclusive&&g.closeOthers.call(t),t.addClass(m.active),o.stop(!0,!0).addClass(m.animating),f.animateChildren&&(e.fn.transition!==i&&O.transition("is supported")?o.children().transition({animation:"fade in",queue:!1,useFailSafe:!0,debug:f.debug,verbose:f.verbose,duration:f.duration}):o.children().stop(!0,!0).animate({opacity:1},f.duration,g.resetOpacity)),void o.slideDown(f.duration,f.easing,function(){o.removeClass(m.animating).addClass(m.active),g.reset.display.call(this),f.onOpen.call(this),f.onChange.call(this)}))},close:function(n){var t=n!==i?"number"==typeof n?x.eq(n):e(n).closest(h.title):e(this).closest(h.title),o=t.next(F),a=o.hasClass(m.animating),s=o.hasClass(m.active),r=!s&&a,c=s&&a;!s&&!r||c||(g.debug("Closing accordion content",o),f.onClosing.call(o),t.removeClass(m.active),o.stop(!0,!0).addClass(m.animating),f.animateChildren&&(e.fn.transition!==i&&O.transition("is supported")?o.children().transition({animation:"fade out",queue:!1,useFailSafe:!0,debug:f.debug,verbose:f.verbose,duration:f.duration}):o.children().stop(!0,!0).animate({opacity:0},f.duration,g.resetOpacity)),o.slideUp(f.duration,f.easing,function(){o.removeClass(m.animating).removeClass(m.active),g.reset.display.call(this),f.onClose.call(this),f.onChange.call(this)}))},closeOthers:function(n){var t,o,a,s=n!==i?x.eq(n):e(this).closest(h.title),r=s.parents(h.content).prev(h.title),c=s.closest(h.accordion),l=h.title+"."+m.active+":visible",u=h.content+"."+m.active+":visible";f.closeNested?(t=c.find(l).not(r),a=t.next(F)):(t=c.find(l).not(r),o=c.find(u).find(l).not(r),t=t.not(o),a=t.next(F)),t.length>0&&(g.debug("Exclusive enabled, closing other content",t),t.removeClass(m.active),a.removeClass(m.animating).stop(!0,!0),f.animateChildren&&(e.fn.transition!==i&&O.transition("is supported")?a.children().transition({animation:"fade out",useFailSafe:!0,debug:f.debug,verbose:f.verbose,duration:f.duration}):a.children().stop(!0,!0).animate({opacity:0},f.duration,g.resetOpacity)),a.slideUp(f.duration,f.easing,function(){e(this).removeClass(m.active),g.reset.display.call(this)}))},reset:{display:function(){g.verbose("Removing inline display from element",this),e(this).css("display",""),""===e(this).attr("style")&&e(this).attr("style","").removeAttr("style")},opacity:function(){g.verbose("Removing inline opacity from element",this),e(this).css("opacity",""),""===e(this).attr("style")&&e(this).attr("style","").removeAttr("style")}},setting:function(n,t){if(g.debug("Changing setting",n,t),e.isPlainObject(n))e.extend(!0,f,n);else{if(t===i)return f[n];e.isPlainObject(f[n])?e.extend(!0,f[n],t):f[n]=t}},internal:function(n,t){return g.debug("Changing internal",n,t),t===i?g[n]:void(e.isPlainObject(n)?e.extend(!0,g,n):g[n]=t)},debug:function(){!f.silent&&f.debug&&(f.performance?g.performance.log(arguments):(g.debug=Function.prototype.bind.call(console.info,console,f.name+":"),g.debug.apply(console,arguments)))},verbose:function(){!f.silent&&f.verbose&&f.debug&&(f.performance?g.performance.log(arguments):(g.verbose=Function.prototype.bind.call(console.info,console,f.name+":"),g.verbose.apply(console,arguments)))},error:function(){f.silent||(g.error=Function.prototype.bind.call(console.error,console,f.name+":"),g.error.apply(console,arguments))},performance:{log:function(e){var n,t,i;f.performance&&(n=(new Date).getTime(),i=s||n,t=n-i,s=n,r.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:A,"Execution Time":t})),clearTimeout(g.performance.timer),g.performance.timer=setTimeout(g.performance.display,500)},display:function(){var n=f.name+":",t=0;s=!1,clearTimeout(g.performance.timer),e.each(r,function(e,n){t+=n["Execution Time"]}),n+=" "+t+"ms",C&&(n+=" '"+C+"'"),(console.group!==i||console.table!==i)&&r.length>0&&(console.groupCollapsed(n),console.table?console.table(r):e.each(r,function(e,n){console.log(n.Name+": "+n["Execution Time"]+"ms")}),console.groupEnd()),r=[]}},invoke:function(n,t,a){var s,r,c,l=T;return t=t||u,a=A||a,"string"==typeof n&&l!==i&&(n=n.split(/[\. ]/),s=n.length-1,e.each(n,function(t,o){var a=t!=s?o+n[t+1].charAt(0).toUpperCase()+n[t+1].slice(1):n;if(e.isPlainObject(l[a])&&t!=s)l=l[a];else{if(l[a]!==i)return r=l[a],!1;if(!e.isPlainObject(l[o])||t==s)return l[o]!==i?(r=l[o],!1):(g.error(v.method,n),!1);l=l[o]}})),e.isFunction(r)?c=r.apply(a,t):r!==i&&(c=r),e.isArray(o)?o.push(c):o!==i?o=[o,c]:c!==i&&(o=c),r}},l?(T===i&&g.initialize(),g.invoke(c)):(T!==i&&T.invoke("destroy"),g.initialize())}),o!==i?o:this},e.fn.accordion.settings={name:"Accordion",namespace:"accordion",silent:!1,debug:!1,verbose:!1,performance:!0,on:"click",observeChanges:!0,exclusive:!0,collapsible:!0,closeNested:!1,animateChildren:!0,duration:350,easing:"easeOutQuad",onOpening:function(){},onOpen:function(){},onClosing:function(){},onClose:function(){},onChange:function(){},error:{method:"The method you called is not defined"},className:{active:"active",animating:"animating"},selector:{accordion:".accordion",title:".title",trigger:".title",content:".content"}},e.extend(e.easing,{easeOutQuad:function(e,n,t,i,o){return-i*(n/=o)*(n-2)+t}})}(jQuery,window,document);
--------------------------------------------------------------------------------
/public/css/components/feed.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Feed
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */
10 |
11 |
12 | /*******************************
13 | Activity Feed
14 | *******************************/
15 |
16 | .ui.feed {
17 | margin: 1em 0em;
18 | }
19 | .ui.feed:first-child {
20 | margin-top: 0em;
21 | }
22 | .ui.feed:last-child {
23 | margin-bottom: 0em;
24 | }
25 |
26 |
27 | /*******************************
28 | Content
29 | *******************************/
30 |
31 |
32 | /* Event */
33 | .ui.feed > .event {
34 | display: -webkit-box;
35 | display: -ms-flexbox;
36 | display: flex;
37 | -webkit-box-orient: horizontal;
38 | -webkit-box-direction: normal;
39 | -ms-flex-direction: row;
40 | flex-direction: row;
41 | width: 100%;
42 | padding: 0.21428571rem 0em;
43 | margin: 0em;
44 | background: none;
45 | border-top: none;
46 | }
47 | .ui.feed > .event:first-child {
48 | border-top: 0px;
49 | padding-top: 0em;
50 | }
51 | .ui.feed > .event:last-child {
52 | padding-bottom: 0em;
53 | }
54 |
55 | /* Event Label */
56 | .ui.feed > .event > .label {
57 | display: block;
58 | -webkit-box-flex: 0;
59 | -ms-flex: 0 0 auto;
60 | flex: 0 0 auto;
61 | width: 2.5em;
62 | height: auto;
63 | -ms-flex-item-align: stretch;
64 | -ms-grid-row-align: stretch;
65 | align-self: stretch;
66 | text-align: left;
67 | }
68 | .ui.feed > .event > .label .icon {
69 | opacity: 1;
70 | font-size: 1.5em;
71 | width: 100%;
72 | padding: 0.25em;
73 | background: none;
74 | border: none;
75 | border-radius: none;
76 | color: rgba(0, 0, 0, 0.6);
77 | }
78 | .ui.feed > .event > .label img {
79 | width: 100%;
80 | height: auto;
81 | border-radius: 500rem;
82 | }
83 | .ui.feed > .event > .label + .content {
84 | margin: 0.5em 0em 0.35714286em 1.14285714em;
85 | }
86 |
87 | /*--------------
88 | Content
89 | ---------------*/
90 |
91 |
92 | /* Content */
93 | .ui.feed > .event > .content {
94 | display: block;
95 | -webkit-box-flex: 1;
96 | -ms-flex: 1 1 auto;
97 | flex: 1 1 auto;
98 | -ms-flex-item-align: stretch;
99 | -ms-grid-row-align: stretch;
100 | align-self: stretch;
101 | text-align: left;
102 | word-wrap: break-word;
103 | }
104 | .ui.feed > .event:last-child > .content {
105 | padding-bottom: 0em;
106 | }
107 |
108 | /* Link */
109 | .ui.feed > .event > .content a {
110 | cursor: pointer;
111 | }
112 |
113 | /*--------------
114 | Date
115 | ---------------*/
116 |
117 | .ui.feed > .event > .content .date {
118 | margin: -0.5rem 0em 0em;
119 | padding: 0em;
120 | font-weight: normal;
121 | font-size: 1em;
122 | font-style: normal;
123 | color: rgba(0, 0, 0, 0.4);
124 | }
125 |
126 | /*--------------
127 | Summary
128 | ---------------*/
129 |
130 | .ui.feed > .event > .content .summary {
131 | margin: 0em;
132 | font-size: 1em;
133 | font-weight: bold;
134 | color: rgba(0, 0, 0, 0.87);
135 | }
136 |
137 | /* Summary Image */
138 | .ui.feed > .event > .content .summary img {
139 | display: inline-block;
140 | width: auto;
141 | height: 10em;
142 | margin: -0.25em 0.25em 0em 0em;
143 | border-radius: 0.25em;
144 | vertical-align: middle;
145 | }
146 |
147 | /*--------------
148 | User
149 | ---------------*/
150 |
151 | .ui.feed > .event > .content .user {
152 | display: inline-block;
153 | font-weight: bold;
154 | margin-right: 0em;
155 | vertical-align: baseline;
156 | }
157 | .ui.feed > .event > .content .user img {
158 | margin: -0.25em 0.25em 0em 0em;
159 | width: auto;
160 | height: 10em;
161 | vertical-align: middle;
162 | }
163 |
164 | /*--------------
165 | Inline Date
166 | ---------------*/
167 |
168 |
169 | /* Date inside Summary */
170 | .ui.feed > .event > .content .summary > .date {
171 | display: inline-block;
172 | float: none;
173 | font-weight: normal;
174 | font-size: 0.85714286em;
175 | font-style: normal;
176 | margin: 0em 0em 0em 0.5em;
177 | padding: 0em;
178 | color: rgba(0, 0, 0, 0.4);
179 | }
180 |
181 | /*--------------
182 | Extra Summary
183 | ---------------*/
184 |
185 | .ui.feed > .event > .content .extra {
186 | margin: 0.5em 0em 0em;
187 | background: none;
188 | padding: 0em;
189 | color: rgba(0, 0, 0, 0.87);
190 | }
191 |
192 | /* Images */
193 | .ui.feed > .event > .content .extra.images img {
194 | display: inline-block;
195 | margin: 0em 0.25em 0em 0em;
196 | width: 6em;
197 | }
198 |
199 | /* Text */
200 | .ui.feed > .event > .content .extra.text {
201 | padding: 0em;
202 | border-left: none;
203 | font-size: 1em;
204 | max-width: 500px;
205 | line-height: 1.4285em;
206 | }
207 |
208 | /*--------------
209 | Meta
210 | ---------------*/
211 |
212 | .ui.feed > .event > .content .meta {
213 | display: inline-block;
214 | font-size: 0.85714286em;
215 | margin: 0.5em 0em 0em;
216 | background: none;
217 | border: none;
218 | border-radius: 0;
219 | box-shadow: none;
220 | padding: 0em;
221 | color: rgba(0, 0, 0, 0.6);
222 | }
223 | .ui.feed > .event > .content .meta > * {
224 | position: relative;
225 | margin-left: 0.75em;
226 | }
227 | .ui.feed > .event > .content .meta > *:after {
228 | content: '';
229 | color: rgba(0, 0, 0, 0.2);
230 | top: 0em;
231 | left: -1em;
232 | opacity: 1;
233 | position: absolute;
234 | vertical-align: top;
235 | }
236 | .ui.feed > .event > .content .meta .like {
237 | color: '';
238 | -webkit-transition: 0.2s color ease;
239 | transition: 0.2s color ease;
240 | }
241 | .ui.feed > .event > .content .meta .like:hover .icon {
242 | color: #FF2733;
243 | }
244 | .ui.feed > .event > .content .meta .active.like .icon {
245 | color: #EF404A;
246 | }
247 |
248 | /* First element */
249 | .ui.feed > .event > .content .meta > :first-child {
250 | margin-left: 0em;
251 | }
252 | .ui.feed > .event > .content .meta > :first-child::after {
253 | display: none;
254 | }
255 |
256 | /* Action */
257 | .ui.feed > .event > .content .meta a,
258 | .ui.feed > .event > .content .meta > .icon {
259 | cursor: pointer;
260 | opacity: 1;
261 | color: rgba(0, 0, 0, 0.5);
262 | -webkit-transition: color 0.1s ease;
263 | transition: color 0.1s ease;
264 | }
265 | .ui.feed > .event > .content .meta a:hover,
266 | .ui.feed > .event > .content .meta a:hover .icon,
267 | .ui.feed > .event > .content .meta > .icon:hover {
268 | color: rgba(0, 0, 0, 0.95);
269 | }
270 |
271 |
272 | /*******************************
273 | Variations
274 | *******************************/
275 |
276 | .ui.small.feed {
277 | font-size: 0.92857143rem;
278 | }
279 | .ui.feed {
280 | font-size: 1rem;
281 | }
282 | .ui.large.feed {
283 | font-size: 1.14285714rem;
284 | }
285 |
286 |
287 | /*******************************
288 | Theme Overrides
289 | *******************************/
290 |
291 |
292 |
293 | /*******************************
294 | User Variable Overrides
295 | *******************************/
296 |
297 |
--------------------------------------------------------------------------------
/public/css/components/progress.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * # Semantic UI 2.2.9 - Progress Bar
3 | * http://github.com/semantic-org/semantic-ui/
4 | *
5 | *
6 | * Released under the MIT license
7 | * http://opensource.org/licenses/MIT
8 | *
9 | */.ui.progress{position:relative;display:block;max-width:100%;border:none;margin:1em 0 2.5em;box-shadow:none;background:rgba(0,0,0,.1);padding:0;border-radius:.28571429rem}.ui.progress:first-child{margin:0 0 2.5em}.ui.progress:last-child{margin:0 0 1.5em}.ui.progress .bar{display:block;line-height:1;position:relative;width:0;min-width:2em;background:#888;border-radius:.28571429rem;-webkit-transition:width .1s ease,background-color .1s ease;transition:width .1s ease,background-color .1s ease}.ui.progress .bar>.progress{white-space:nowrap;position:absolute;width:auto;font-size:.92857143em;top:50%;right:.5em;left:auto;bottom:auto;color:rgba(255,255,255,.7);text-shadow:none;margin-top:-.5em;font-weight:700;text-align:left}.ui.progress>.label{position:absolute;width:100%;font-size:1em;top:100%;right:auto;left:0;bottom:auto;color:rgba(0,0,0,.87);font-weight:700;text-shadow:none;margin-top:.2em;text-align:center;-webkit-transition:color .4s ease;transition:color .4s ease}.ui.indicating.progress[data-percent^="1"] .bar,.ui.indicating.progress[data-percent^="2"] .bar{background-color:#d95c5c}.ui.indicating.progress[data-percent^="3"] .bar{background-color:#efbc72}.ui.indicating.progress[data-percent^="4"] .bar,.ui.indicating.progress[data-percent^="5"] .bar{background-color:#e6bb48}.ui.indicating.progress[data-percent^="6"] .bar{background-color:#ddc928}.ui.indicating.progress[data-percent^="7"] .bar,.ui.indicating.progress[data-percent^="8"] .bar{background-color:#b4d95c}.ui.indicating.progress[data-percent^="100"] .bar,.ui.indicating.progress[data-percent^="9"] .bar{background-color:#66da81}.ui.indicating.progress[data-percent^="1"] .label,.ui.indicating.progress[data-percent^="2"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent^="3"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent^="4"] .label,.ui.indicating.progress[data-percent^="5"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent^="6"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent^="7"] .label,.ui.indicating.progress[data-percent^="8"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent^="100"] .label,.ui.indicating.progress[data-percent^="9"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress[data-percent="1"] .bar,.ui.indicating.progress[data-percent="2"] .bar,.ui.indicating.progress[data-percent="3"] .bar,.ui.indicating.progress[data-percent="4"] .bar,.ui.indicating.progress[data-percent="5"] .bar,.ui.indicating.progress[data-percent="6"] .bar,.ui.indicating.progress[data-percent="7"] .bar,.ui.indicating.progress[data-percent="8"] .bar,.ui.indicating.progress[data-percent="9"] .bar{background-color:#d95c5c}.ui.indicating.progress[data-percent="1"] .label,.ui.indicating.progress[data-percent="2"] .label,.ui.indicating.progress[data-percent="3"] .label,.ui.indicating.progress[data-percent="4"] .label,.ui.indicating.progress[data-percent="5"] .label,.ui.indicating.progress[data-percent="6"] .label,.ui.indicating.progress[data-percent="7"] .label,.ui.indicating.progress[data-percent="8"] .label,.ui.indicating.progress[data-percent="9"] .label{color:rgba(0,0,0,.87)}.ui.indicating.progress.success .label{color:#1a531b}.ui.progress.success .bar{background-color:#21ba45!important}.ui.progress.success .bar,.ui.progress.success .bar::after{-webkit-animation:none!important;animation:none!important}.ui.progress.success>.label{color:#1a531b}.ui.progress.warning .bar{background-color:#f2c037!important}.ui.progress.warning .bar,.ui.progress.warning .bar::after{-webkit-animation:none!important;animation:none!important}.ui.progress.warning>.label{color:#794b02}.ui.progress.error .bar{background-color:#db2828!important}.ui.progress.error .bar,.ui.progress.error .bar::after{-webkit-animation:none!important;animation:none!important}.ui.progress.error>.label{color:#912d2b}.ui.active.progress .bar{position:relative;min-width:2em}.ui.active.progress .bar::after{content:'';opacity:0;position:absolute;top:0;left:0;right:0;bottom:0;background:#fff;border-radius:.28571429rem;-webkit-animation:progress-active 2s ease infinite;animation:progress-active 2s ease infinite}@-webkit-keyframes progress-active{0%{opacity:.3;width:0}100%{opacity:0;width:100%}}@keyframes progress-active{0%{opacity:.3;width:0}100%{opacity:0;width:100%}}.ui.disabled.progress{opacity:.35}.ui.disabled.progress .bar,.ui.disabled.progress .bar::after{-webkit-animation:none!important;animation:none!important}.ui.inverted.progress{background:rgba(255,255,255,.08);border:none}.ui.inverted.progress .bar{background:#888}.ui.inverted.progress .bar>.progress{color:#f9fafb}.ui.inverted.progress>.label{color:#fff}.ui.inverted.progress.success>.label{color:#21ba45}.ui.inverted.progress.warning>.label{color:#f2c037}.ui.inverted.progress.error>.label{color:#db2828}.ui.progress.attached{background:0 0;position:relative;border:none;margin:0}.ui.progress.attached,.ui.progress.attached .bar{display:block;height:.2rem;padding:0;overflow:hidden;border-radius:0 0 .28571429rem .28571429rem}.ui.progress.attached .bar{border-radius:0}.ui.progress.top.attached,.ui.progress.top.attached .bar{top:0;border-radius:.28571429rem .28571429rem 0 0}.ui.progress.top.attached .bar{border-radius:0}.ui.card>.ui.attached.progress,.ui.segment>.ui.attached.progress{position:absolute;top:auto;left:0;bottom:100%;width:100%}.ui.card>.ui.bottom.attached.progress,.ui.segment>.ui.bottom.attached.progress{top:100%;bottom:auto}.ui.red.progress .bar{background-color:#db2828}.ui.red.inverted.progress .bar{background-color:#ff695e}.ui.orange.progress .bar{background-color:#f2711c}.ui.orange.inverted.progress .bar{background-color:#ff851b}.ui.yellow.progress .bar{background-color:#fbbd08}.ui.yellow.inverted.progress .bar{background-color:#ffe21f}.ui.olive.progress .bar{background-color:#b5cc18}.ui.olive.inverted.progress .bar{background-color:#d9e778}.ui.green.progress .bar{background-color:#21ba45}.ui.green.inverted.progress .bar{background-color:#2ecc40}.ui.teal.progress .bar{background-color:#00b5ad}.ui.teal.inverted.progress .bar{background-color:#6dffff}.ui.blue.progress .bar{background-color:#2185d0}.ui.blue.inverted.progress .bar{background-color:#54c8ff}.ui.violet.progress .bar{background-color:#6435c9}.ui.violet.inverted.progress .bar{background-color:#a291fb}.ui.purple.progress .bar{background-color:#a333c8}.ui.purple.inverted.progress .bar{background-color:#dc73ff}.ui.pink.progress .bar{background-color:#e03997}.ui.pink.inverted.progress .bar{background-color:#ff8edf}.ui.brown.progress .bar{background-color:#a5673f}.ui.brown.inverted.progress .bar{background-color:#d67c1c}.ui.grey.progress .bar{background-color:#767676}.ui.grey.inverted.progress .bar{background-color:#dcddde}.ui.black.progress .bar{background-color:#1b1c1d}.ui.black.inverted.progress .bar{background-color:#545454}.ui.tiny.progress{font-size:.85714286rem}.ui.tiny.progress .bar{height:.5em}.ui.small.progress{font-size:.92857143rem}.ui.small.progress .bar{height:1em}.ui.progress{font-size:1rem}.ui.progress .bar{height:1.75em}.ui.large.progress{font-size:1.14285714rem}.ui.large.progress .bar{height:2.5em}.ui.big.progress{font-size:1.28571429rem}.ui.big.progress .bar{height:3.5em}
--------------------------------------------------------------------------------
留言
8 | 9 | {% for comment in comments %} 10 |