├── .npmignore
├── bin
├── build-dependency-less.sh
├── build-dependency-css.sh
├── build.sh
├── build-dependency-js.sh
└── airpub-bootstrap.less
├── .gitignore
├── src
├── controllers
│ ├── global.js
│ ├── meta.js
│ ├── archive.js
│ ├── base.js
│ ├── single.js
│ └── admin.js
├── services
│ └── share.js
├── filters
│ └── marked.js
├── addons
│ └── meta.js
└── airpub.js
├── configs-sample.js
├── LICENSE
├── index.html
├── bower.json
├── package.json
├── dev.html
├── README.md
├── libs
├── ui-bootstrap-custom-0.12.0.min.js
└── ui-bootstrap-custom-tpls-0.12.0.min.js
└── dist
├── airpub.min.js
├── airpub.min.js.map
└── airpub-dependencies.min.css
/.npmignore:
--------------------------------------------------------------------------------
1 | .DS_*
2 | thumb
3 | node_modules
4 | *.sublime*
5 | *.log
6 | bower_*
7 | configs.js
8 | editor
9 | csrf*
--------------------------------------------------------------------------------
/bin/build-dependency-less.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | node_modules/.bin/lessc -x \
4 | bin/airpub-bootstrap.less \
5 | dist/airpub-bootstrap.min.css
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_*
2 | thumb
3 | node_modules
4 | *.sublime*
5 | *.log
6 | bower_*
7 | configs.js
8 | editor
9 | csrf*
10 | dist/*-bootstrap.min.css
--------------------------------------------------------------------------------
/bin/build-dependency-css.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | node_modules/.bin/cleancss \
4 | dist/airpub-bootstrap.min.css \
5 | bower_components/nprogress/nprogress.css \
6 | bower_components/highlightjs/styles/github.css \
7 | -o dist/airpub-dependencies.min.css \
8 | --s0 \
9 | --debug
--------------------------------------------------------------------------------
/src/controllers/global.js:
--------------------------------------------------------------------------------
1 | ;(function(angular, debug) {
2 | 'use strict';
3 |
4 | angular
5 | .module('airpub')
6 | .controller('global', ['$scope', globalCtrler]);
7 |
8 | function globalCtrler($scope) {
9 | if (!airpubConfigs)
10 | return console.error(new Error('airpub 缺少必要的配置文件!'));
11 |
12 | $scope.configs = airpubConfigs;
13 | }
14 | })(window.angular, window.debug);
15 |
--------------------------------------------------------------------------------
/bin/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | node_modules/.bin/uglifyjs \
4 | src/airpub.js \
5 | src/filters/marked.js \
6 | src/services/share.js \
7 | src/controllers/global.js \
8 | src/controllers/meta.js \
9 | src/controllers/base.js \
10 | src/controllers/archive.js \
11 | src/controllers/single.js \
12 | src/controllers/admin.js \
13 | src/addons/meta.js \
14 | --mangle \
15 | --compress \
16 | -o dist/airpub.min.js \
17 | --source-map dist/airpub.min.js.map \
18 | --source-map-url airpub.min.js.map
--------------------------------------------------------------------------------
/bin/build-dependency-js.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | node_modules/.bin/uglifyjs \
4 | bower_components/angular/angular.min.js \
5 | bower_components/angular-sanitize/angular-sanitize.min.js \
6 | libs/ui-bootstrap-custom-0.12.0.min.js \
7 | libs/ui-bootstrap-custom-tpls-0.12.0.min.js \
8 | bower_components/angular-ui-router/release/angular-ui-router.min.js \
9 | bower_components/oclazyload/dist/ocLazyLoad.min.js \
10 | bower_components/nprogress/nprogress.js \
11 | bower_components/duoshuo/dist/duoshuo.min.js \
12 | bower_components/upyun/dist/upyun.min.js \
13 | --mangle \
14 | --compress \
15 | -o dist/airpub-dependencies.min.js \
16 | --source-map dist/airpub-dependencies.min.js.map \
17 | --source-map-url airpub-dependencies.min.js.map
--------------------------------------------------------------------------------
/configs-sample.js:
--------------------------------------------------------------------------------
1 | var airpubConfigs = {};
2 |
3 | // 博客名称
4 | airpubConfigs.name = 'Airpub';
5 |
6 | // 简单介绍
7 | airpubConfigs.description = '轻如蝉翼的写作工具';
8 |
9 | // 博客首页的固定链接
10 | airpubConfigs.url = 'http://yourUri.com';
11 |
12 | // 又拍云上传配置
13 | // 推荐使用 upyun-sign 生成短期签名的方式,不暴露 key 实现上传
14 | // 具体可以参考 https://github.com/turingou/upyun-sign
15 | airpubConfigs.upyun = {
16 | sign: '', // upyun-sign 生成的签名
17 | policy: '', // upyun-sign 生成的 policy
18 | // bucket: 'mybucket',
19 | // form_api_secret: 'xxxxxx', // 可选参数
20 | // uri: 'http://{{bucketName}}.b0.upaiyun.com', // 可选参数
21 | // endpoint: 'http://v0.api.upyun.com/{{bucketName}}', // 可选参数
22 | };
23 |
24 | // 多说配置
25 | var duoshuoQuery = {
26 | short_name: '{{your_duoshuo_short_name}}'
27 | };
--------------------------------------------------------------------------------
/src/services/share.js:
--------------------------------------------------------------------------------
1 | ;(function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('airpub')
6 | .service('share', [shareService]);
7 |
8 | function shareService() {
9 | var defaults = {
10 | title: 'Airpub',
11 | link: 'http://airpub.io',
12 | desc: '基于 Angular.js 搭建,多说数据驱动的纯前端写作工具。'
13 | };
14 |
15 | this.wechat = wechatShare;
16 |
17 | function wechatShare(article) {
18 | if (!window.wechat)
19 | return;
20 |
21 | var wechat = window.wechat;
22 | var data = {};
23 |
24 | angular.forEach([
25 | 'title',
26 | 'link',
27 | 'desc'
28 | ], function(item){
29 | data[item] = article[item] || defaults[item];
30 | });
31 |
32 | wechat('friend', data);
33 | wechat('timeline', data);
34 | wechat('weibo', data);
35 | }
36 | }
37 | })();
38 |
--------------------------------------------------------------------------------
/src/controllers/meta.js:
--------------------------------------------------------------------------------
1 | ;(function(angular, debug) {
2 | 'use strict';
3 |
4 | angular
5 | .module('airpub')
6 | .controller('meta', [
7 | '$scope',
8 | '$rootScope',
9 | 'share',
10 | metaCtrler
11 | ]);
12 |
13 | function metaCtrler($scope, $rootScope, share) {
14 | $scope.title = $scope.configs.name || 'Airpub';
15 | $scope.description = $scope.configs.description || 'just another Airpub blog';
16 |
17 | // Init service share
18 | share.wechat({
19 | title: $scope.configs.name,
20 | link: $scope.configs.url,
21 | desc: $scope.configs.description
22 | });
23 |
24 | $rootScope.$on('updateMeta', function(eve, data){
25 | if (typeof(data) === 'string')
26 | return $scope.title = data;
27 | angular.forEach(data, function(v, k){
28 | $scope[k] = v;
29 | });
30 | });
31 | }
32 | })(window.angular, window.debug);
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 Guo Yu <o.u.turing@gmail.com>
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "airpub",
3 | "version": "0.4.0",
4 | "homepage": "https://github.com/duoshuo/airpub",
5 | "authors": [
6 | "Guo Yu "
7 | ],
8 | "description": "a pure front-end blog engine powered by duoshuo API",
9 | "main": "index.html",
10 | "keywords": [
11 | "blog",
12 | "cms",
13 | "angular",
14 | "airpub",
15 | "airpress",
16 | "wordpress",
17 | "blog engine",
18 | "blog platform",
19 | "article"
20 | ],
21 | "license": "MIT",
22 | "ignore": [
23 | "**/.*",
24 | "node_modules",
25 | "bower_components",
26 | "test",
27 | "tests",
28 | "editor",
29 | "thumb"
30 | ],
31 | "dependencies": {
32 | "angular": "1.3.8",
33 | "angular-sanitize": "~1.3.8",
34 | "angular-ui-router": "0.2.13",
35 | "bootstrap": "3.3.1",
36 | "nprogress": "~0.1.6",
37 | "node-uuid": "~1.4.1",
38 | "upyun": "0.4.0",
39 | "duoshuo": "0.5.2",
40 | "marked": "~0.3.2",
41 | "highlightjs": "~8.0.0",
42 | "chill": "0.3.0",
43 | "ninja": "0.1.1",
44 | "oclazyload": "~0.5.2"
45 | },
46 | "devDependencies": {
47 | "debug": "git@github.com:visionmedia/debug.git"
48 | },
49 | "resolutions": {
50 | "angular": "1.3.8"
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "airpub",
3 | "version": "0.4.0",
4 | "description": "a pure front-end blog engine powered by duoshuo API",
5 | "main": "index.html",
6 | "author": "turing ",
7 | "license": "MIT",
8 | "scripts": {
9 | "build": "bin/build.sh",
10 | "build-deps": "npm run build-deps-js && npm run build-deps-css",
11 | "build-deps-js": "bin/build-dependency-js.sh",
12 | "build-deps-css": "bin/build-dependency-css.sh",
13 | "build-deps-less": "bin/build-dependency-less.sh",
14 | "serve": "node_modules/.bin/serve --no-less .",
15 | "watch": "node_modules/.bin/rewatch src/*.js src/**/*.js -c 'npm run build'",
16 | "dev": "npm run serve & npm run watch",
17 | "start": "npm run dev"
18 | },
19 | "repository": {
20 | "type": "git",
21 | "url": "https://github.com/duoshuo/airpub.git"
22 | },
23 | "bugs": {
24 | "url": "https://github.com/duoshuo/airpub/issues"
25 | },
26 | "keywords": [
27 | "air",
28 | "publish",
29 | "press",
30 | "airpub",
31 | "cms",
32 | "blog",
33 | "blog platform",
34 | "angular"
35 | ],
36 | "devDependencies": {
37 | "clean-css": "^2.2.13",
38 | "less": "^2.1.2",
39 | "rewatch": "~0.2.2",
40 | "serve": "~1.4.0",
41 | "uglify-js": "^2.4.15"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/bin/airpub-bootstrap.less:
--------------------------------------------------------------------------------
1 | // Core variables and mixins
2 | @import "bower_components/bootstrap/less/variables.less";
3 | @import "bower_components/bootstrap/less/mixins.less";
4 |
5 | // Reset and dependencies
6 | @import "bower_components/bootstrap/less/normalize.less";
7 | @import "bower_components/bootstrap/less/print.less";
8 |
9 | // Core CSS
10 | @import "bower_components/bootstrap/less/scaffolding.less";
11 | @import "bower_components/bootstrap/less/type.less";
12 | @import "bower_components/bootstrap/less/code.less";
13 | @import "bower_components/bootstrap/less/grid.less";
14 | @import "bower_components/bootstrap/less/tables.less";
15 | @import "bower_components/bootstrap/less/forms.less";
16 | @import "bower_components/bootstrap/less/buttons.less";
17 |
18 | // Components
19 | @import "bower_components/bootstrap/less/component-animations.less";
20 | @import "bower_components/bootstrap/less/thumbnails.less";;
21 | @import "bower_components/bootstrap/less/alerts.less";;
22 | @import "bower_components/bootstrap/less/pagination.less";;
23 | @import "bower_components/bootstrap/less/pager.less";;
24 |
25 | // Components w/ JavaScript
26 | @import "bower_components/bootstrap/less/tooltip.less";;
27 |
28 | // Utility classes
29 | @import "bower_components/bootstrap/less/utilities.less";
30 | @import "bower_components/bootstrap/less/responsive-utilities.less";
--------------------------------------------------------------------------------
/src/controllers/archive.js:
--------------------------------------------------------------------------------
1 | ;(function(angular, debug) {
2 | 'use strict';
3 |
4 | angular
5 | .module('airpub')
6 | .controller('archive', [
7 | '$scope',
8 | '$state',
9 | 'duoshuo',
10 | '$rootScope',
11 | archiveCtrler
12 | ]);
13 |
14 | function archiveCtrler($scope, $state, duoshuo, $rootScope) {
15 | $scope.itemsPerPage = 10;
16 | $scope.currentPage = parseNumber($state.params.page) || 1;
17 |
18 | // Update document title
19 | $rootScope.$emit('updateMeta', $scope.configs.name);
20 |
21 | // Read articles from cache
22 | if ($scope.articles && $scope.articles.length > 0)
23 | return;
24 |
25 | // TODO: remove this ugly hack
26 | if ($state.params.page) {
27 | var lock = true;
28 | var currentPage = $scope.currentPage;
29 | }
30 |
31 | // Read data from fresh
32 | fetchFreshArticles();
33 |
34 | // When page changed, go => /#/page/currentPage
35 | // Why the fucking event was trigged twice and return `1` the second time ?!
36 | $scope.pageChanged = pageChanged;
37 |
38 | function fetchFreshArticles() {
39 | var query = {};
40 | query.page = $scope.currentPage;
41 | query.limit = $scope.itemsPerPage;
42 | query.with_content = 1;
43 |
44 | // Open a request
45 | duoshuo.get('threads/list', query, onSuccess, onError);
46 |
47 | function onSuccess(err, result, res) {
48 | if ($state.params.page)
49 | lock = false;
50 | if (err)
51 | return $scope.addAlert('获取信息失败,请重试', 'danger');
52 | if (result.length === 0)
53 | return $state.go('layout.404');
54 |
55 | // Exporse locals to templates
56 | $scope.articles = result || [];
57 | $scope.totalItems = res.cursor.total;
58 |
59 | if ($state.params.page)
60 | $scope.currentPage = currentPage;
61 |
62 | return;
63 | }
64 |
65 | function onError(err) {
66 | return $state.go('layout.404');
67 | }
68 | }
69 |
70 | function pageChanged() {
71 | if (lock)
72 | return;
73 |
74 | $state.go('layout.pager', {
75 | page: $scope.currentPage
76 | });
77 | }
78 |
79 | function parseNumber(str) {
80 | if (str && !isNaN(parseInt(str)))
81 | return parseInt(str);
82 |
83 | return false;
84 | }
85 | }
86 | })(window.angular, window.debug);
87 |
--------------------------------------------------------------------------------
/src/controllers/base.js:
--------------------------------------------------------------------------------
1 | ;(function(angular, debug) {
2 | 'use strict';
3 |
4 | angular
5 | .module('airpub')
6 | .controller('layout', ['$scope', layoutCtrler])
7 | .controller('base', [
8 | '$scope',
9 | '$state',
10 | '$timeout',
11 | '$location',
12 | 'duoshuo',
13 | baseCtrler
14 | ]);
15 |
16 | function baseCtrler($scope, $state, $timeout, $location, duoshuo) {
17 | // Exporse locals to template
18 | $scope.location = $location;
19 | $scope.state = $state;
20 |
21 | // Signin section
22 | $scope.hiddenSigninSection = true;
23 | $scope.toggleSigninSection = toggleSigninSection;
24 |
25 | // Alerts module
26 | $scope.alerts = [];
27 | $scope.addAlert = addAlert;
28 | $scope.closeAlert = closeAlert;
29 |
30 | // Update header backgroud
31 | $scope.updateBackground = updateBackground;
32 |
33 | // Expose copyright year
34 | $scope.copyrightYear = (new Date()).getFullYear();
35 |
36 | // Init account infomation
37 | duoshuo.on('ready', initAccount);
38 |
39 | function initAccount(err, data) {
40 | var isVisitor = (data.user_id === 0);
41 |
42 | if (err || isVisitor) {
43 | $scope.isVisitor = true;
44 | return;
45 | }
46 |
47 | // Expose user data
48 | $scope.user = data;
49 | }
50 |
51 | function toggleSigninSection() {
52 | $scope.hiddenSigninSection = !$scope.hiddenSigninSection;
53 | }
54 |
55 | function addAlert(msg, type, dismiss) {
56 | $scope.alerts.push({
57 | msg: msg,
58 | type: type || 'success'
59 | });
60 | var alertIndex = $scope.alerts.length - 1;
61 | $timeout(function() {
62 | $scope.closeAlert(alertIndex);
63 | }, dismiss ? (dismiss * 1000) : 3000);
64 | return alertIndex;
65 | }
66 |
67 | function closeAlert(index) {
68 | $scope.alerts.splice(index, 1);
69 | }
70 |
71 | function updateBackground(uri, dom) {
72 | if (!uri)
73 | return;
74 | if (uri.indexOf('http') !== 0 && uri.indexOf('https') !== 0)
75 | return;
76 |
77 | var hd = dom || document.getElementsByTagName('header')[0];
78 |
79 | if (!hd)
80 | return;
81 |
82 | angular.element(hd).css({
83 | 'background-image': 'url(' + uri + ')'
84 | });
85 | }
86 | }
87 |
88 | function layoutCtrler() {}
89 |
90 | })(window.angular, window.debug);
91 |
--------------------------------------------------------------------------------
/src/controllers/single.js:
--------------------------------------------------------------------------------
1 | ;
2 | (function(angular, debug) {
3 | 'use strict';
4 |
5 | angular
6 | .module('airpub')
7 | .controller('single', [
8 | '$scope',
9 | '$state',
10 | 'duoshuo',
11 | '$rootScope',
12 | singleArticleCtrler
13 | ]);
14 |
15 | function singleArticleCtrler($scope, $state, duoshuo, $rootScope) {
16 | if (!$state.params.uri)
17 | return $state.go('layout.404');
18 |
19 | // Expose locals to templates
20 | $scope.threadId = $state.params.uri;
21 |
22 | // Read from cache
23 | if ($scope.article)
24 | return;
25 |
26 | // Fetch article details
27 | fetchFreshDetail($state.params.uri);
28 |
29 | function fetchFreshDetail(thread_id) {
30 | var query = {};
31 | query.thread_id = thread_id;
32 |
33 | // Open a request
34 | duoshuo.get(
35 | 'threads/details',
36 | query,
37 | onSuccess,
38 | onError
39 | );
40 |
41 | function onSuccess(err, result) {
42 | if (err)
43 | return $scope.addAlert('文章内容获取失败,请稍后再试...', 'danger');
44 |
45 | // Expose locals to templates
46 | $scope.article = result;
47 |
48 | // Update title and desciption
49 | $rootScope.$emit('updateMeta', {
50 | title: result.title,
51 | description: fetchDesciption(result.content)
52 | });
53 |
54 | // Update background if required.
55 | if (result.meta && result.meta.background)
56 | $scope.updateBackground(result.meta.background);
57 |
58 | // Init wechat share
59 | // if ($scope.article)
60 | // initWeixinShare($scope.article)
61 |
62 | // Fetch authors' profile
63 | if (!result.author_id)
64 | return;
65 |
66 | fetchUserProfile(result);
67 | }
68 |
69 | function onError(err) {
70 | return $state.go('layout.404');
71 | }
72 |
73 | function fetchDesciption(text) {
74 | var maxLength = 80;
75 | if (!text)
76 | return '';
77 |
78 | if (text.length <= maxLength)
79 | return text;
80 |
81 | return text.substr(0, maxLength) + '...';
82 | }
83 | }
84 |
85 | function fetchUserProfile(result) {
86 | var query = {};
87 | query.user_id = result.author_id;
88 |
89 | // Open a request
90 | duoshuo.get('users/profile', query, onSuccess);
91 |
92 | function onSuccess(err, result) {
93 | // Ignore null profile
94 | if (err) return;
95 |
96 | $scope.author = result;
97 | $scope.author.description = result.connected_services.weibo ?
98 | result.connected_services.weibo.description :
99 | null;
100 | }
101 | }
102 | }
103 |
104 | function initWeixinShare(article) {
105 | if (!window.wechat)
106 | return;
107 |
108 | var limit = 42;
109 | var data = {};
110 |
111 | data.link = article.url;
112 | data.title = article.title;
113 | data.desc = article.content.substr(0, limit) + (article.content.length > limit ? '...' : '');
114 |
115 | if (article.meta && article.meta.background)
116 | data.img = article.meta.background;
117 |
118 | // TODO: Remove hardcode here, replace key `wechatSharePic` with a anchor
119 | if (article.meta && article.meta.wechatSharePic)
120 | data.img = article.meta.wechatSharePic;
121 |
122 | if (airpubConfigs.wechat && airpubConfigs.wechat.appId)
123 | data.app = airpubConfigs.wechat.appId;
124 |
125 | window.wechat('friend', data);
126 | window.wechat('timeline', data);
127 | window.wechat('weibo', data);
128 | }
129 | })(window.angular, window.debug);
130 |
--------------------------------------------------------------------------------
/src/filters/marked.js:
--------------------------------------------------------------------------------
1 | ;(function(angular, debug) {
2 | 'use strict';
3 |
4 | angular
5 | .module('airpub')
6 | .filter('marked', ['$sce', '$sanitize', markedFilter]);
7 |
8 | function markedFilter($sce, $sanitize) {
9 | return function(raw) {
10 | if (!raw)
11 | return '';
12 | if (!marked)
13 | throw new Error('Marked.js is required!');
14 |
15 | var wrappers;
16 |
17 | // Check if additional filter params is provided.
18 | if (arguments.length > 1)
19 | wrappers = parseWrapperString(Array.prototype.slice.call(arguments, 1));
20 |
21 | var markedOptions = {};
22 |
23 | // Make a custom Renderer for marked
24 | var render = new marked.Renderer();
25 |
26 | // Extends from code prototye but let user to choose
27 | // Use unescape html or not.
28 | render.code = function(code, lang, escaped) {
29 | var html = marked.Renderer.prototype.code.call(
30 | this,
31 | (lang === 'unsafe-html') ? $sanitize(code) : code,
32 | lang,
33 | escaped
34 | );
35 |
36 | if (wrappers && wrappers.code)
37 | return injectTo(wrappers.code, html)
38 |
39 | return html;
40 | };
41 |
42 | // Extends from other prototypes
43 | angular.forEach([
44 | 'blockquote',
45 | 'html',
46 | 'heading',
47 | 'list',
48 | 'listitem',
49 | 'paragraph',
50 | 'table',
51 | 'tablerow',
52 | 'tablecell',
53 | 'image'
54 | ], function(type){
55 | render[type] = function() {
56 | var html = marked.Renderer.prototype[type].apply(this, arguments);
57 |
58 | if (wrappers && wrappers[type])
59 | return injectTo(wrappers[type], html)
60 |
61 | if (wrappers && wrappers.all)
62 | return injectTo(wrappers.all, html)
63 |
64 | return html;
65 | }
66 | })
67 |
68 | markedOptions.renderer = render;
69 |
70 | // Setting: highlight
71 | if (window.hljs)
72 | markedOptions.highlight = highlightCode;
73 |
74 | marked.setOptions(markedOptions);
75 |
76 | function highlightCode(code) {
77 | return window.hljs.highlightAuto(code).value;
78 | }
79 |
80 | function parseWrapperString(wrappers) {
81 | var parsed = {};
82 |
83 | wrappers.forEach(function(str) {
84 | var key = str.indexOf(':') === -1 ?
85 | 'all' : str.split(':')[0];
86 |
87 | parsed[key] = str.split(':')[1];
88 | });
89 |
90 | return parsed;
91 | }
92 |
93 | function injectTo(str, entryHtml) {
94 | function parseName(str) {
95 | var arr = str.split(' ')
96 | if (arr.length === 1)
97 | return str.substr(1);
98 |
99 | var ret = '';
100 | angular.forEach(arr, function(token) {
101 | ret += token.substr(1) + ' ';
102 | });
103 | return ret;
104 | }
105 |
106 | var domNotes = str.split('>');
107 |
108 | if (!domNotes.length)
109 | return entryHtml;
110 |
111 | var wraps = '';
112 |
113 | angular.forEach(domNotes, function(item) {
114 | var attrName = item.charAt(0) === '.' ?
115 | 'class' : 'id';
116 | wraps += '';
117 | });
118 |
119 | wraps += entryHtml;
120 |
121 | angular.forEach(domNotes, function() {
122 | wraps += '
';
123 | });
124 |
125 | return wraps;
126 | }
127 |
128 | return $sce.trustAsHtml(marked(raw));
129 | }
130 | }
131 | })(window.angular, window.debug);
132 |
--------------------------------------------------------------------------------
/src/addons/meta.js:
--------------------------------------------------------------------------------
1 | ;(function() {
2 | 'use strict';
3 |
4 | // Meta directive
5 | // todo: parse configs obejct to deps
6 | angular
7 | .module('airpub')
8 | .directive('metaBackground', ['upyun', metaBackgroundDirective])
9 | .directive('metaShare', ['duoshuo', metaShareDirective]);
10 |
11 | function metaBackgroundDirective(upyun) {
12 | var directive = {
13 | restrict: 'AE',
14 | require: 'ngModel',
15 | replace: true,
16 | link: link,
17 | template: [
18 | '',
19 | '',
25 | '
'
26 | ].join('\n')
27 | };
28 | return directive;
29 |
30 | function link(scope, element, attrs, ctrl) {
31 | var $ = angular.element;
32 | var uploading = false;
33 |
34 | var inputButton = document.getElementById('uploadBackgroundBtn');
35 | $(inputButton).on('change', bindUpload);
36 |
37 | // model => view
38 | ctrl.$render = function() {
39 | fillBackgroundImage(ctrl.$viewValue);
40 | };
41 |
42 | // upload images and fill uri
43 | function bindUpload(eve) {
44 | // begin upload
45 | if (uploading) return;
46 | uploading = true;
47 | upyun.upload('metaBackgroundForm', function(err, response, image) {
48 | uploading = false;
49 | if (err) {
50 | console.error(err);
51 | return alert('上传失败,请稍后再试...');
52 | }
53 | var uploadOk = image.code === 200 && image.message === 'ok';
54 | if (!uploadOk) return;
55 | // fill image
56 | fillBackgroundImage(image.absUrl);
57 | // view => model
58 | ctrl.$setViewValue(image.absUrl);
59 | });
60 | }
61 |
62 | function fillBackgroundImage(uri) {
63 | if (!uri) return;
64 | if (uri.indexOf('http') !== 0) return;
65 | var hd = document.getElementsByTagName('header')[0];
66 | var self = document.getElementById('metaBackground');
67 | if (!hd) return;
68 | var style = {};
69 | style['background-image'] = 'url(' + uri + ')';
70 | $(hd).css(style);
71 | $(self).css(style);
72 | }
73 | }
74 | }
75 |
76 | function metaShareDirective(duoshuo) {
77 | var directive = {
78 | restrict: 'AE',
79 | require: 'ngModel',
80 | replace: true,
81 | link: link,
82 | template: [
83 | '',
84 | '',
85 | '',
86 | '
'
87 | ].join('\n')
88 | };
89 | return directive;
90 |
91 | function link(scope, element, attrs, ctrl) {
92 | scope.checkToShare = false;
93 | scope.updateCheckStatus = updateCheckingStatus;
94 |
95 | // bind events
96 | scope.on('afterCreate', shareArticle());
97 | scope.on('afterUpdate', shareArticle());
98 |
99 | // view => model
100 | function updateCheckingStatus() {
101 | ctrl.$setViewValue(scope.checkToShare);
102 | }
103 |
104 | // share article
105 | function shareArticle(type) {
106 | return function(article) {
107 | return; // disable for temp
108 | if (!scope.checkToShare) return;
109 | var query = article;
110 | query.sync_to = type || 'weibo';
111 | query.short_name = duoshuoQuery.short_name;
112 | if (query.meta) delete query.meta;
113 | // todo: update this API
114 | return duoshuo.post('threads/sync', query, function(){});
115 | };
116 | }
117 | }
118 | }
119 | })();
120 |
--------------------------------------------------------------------------------
/dev.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](http://airpub.io)
2 |
3 | ## Airpub 
4 |
5 | [Airpub](http://airpub.io) 是基于 Angular.js 搭建,[多说](http://duoshuo.com) 数据驱动的纯前端写作工具。
6 |
7 | 基于多说现有社交网络账户体系与健壮 API,Airpub 能够托管在任何静态资源服务器上,例如 GitHub Pages、又拍云储存、七牛云储存或使用自定义的 FTP 工具上传到任何 VPS 或虚拟主机中使用,为最终用户提供便捷流畅,优质轻量的博客写作与阅读体验。访问[官方网站](http://airpub.io)
8 |
9 | ### 快速开始
10 |
11 | - [如何安装](#%E5%A6%82%E4%BD%95%E5%AE%89%E8%A3%85)
12 | - [配置指南](#%E9%85%8D%E7%BD%AE%E6%8C%87%E5%8D%97)
13 | - [开发指南](#%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97)
14 | - [贡献代码](#%E8%B4%A1%E7%8C%AE%E4%BB%A3%E7%A0%81)
15 |
16 | ### Airpub 功能特色
17 | ---
18 |
19 | 已实现的功能特色:
20 |
21 | - [x] 支持 Markdown 写作
22 | - [x] 支持图片上传,目前支持上传到 又拍云
23 | - [x] 支持插入代码以及代码高亮
24 | - [x] 支持基于多说的社交网络账户登录
25 | - [x] 基于 Angular Directive 规范的 add-on 系统
26 | - [x] 基于 bower 管理的主题系统
27 | - [x] 符合规范的,更好的 Angular SEO 实现
28 | - [x] 更好的移动端登录体验,去掉多说登录中间页面,跳转到相应社交网站登录页面
29 | - [x] 拆分后台文件与逻辑到独立页面,缩减普通用户请求资源大小
30 | - [x] 支持友好地分享到微信信息流、朋友圈
31 |
32 | Todo List:
33 |
34 | - [x] 精细化压缩 `bootstrap.css`,实现更小的页面资源加载。
35 | - [x] 解决前端鉴权产生的冗余依赖问题,消除对 `angular-md5`,`angular-base64` 等库的依赖。
36 | - [ ] 实现单一文章多账户编辑的逻辑与界面,设计基本的 ACL 机制。
37 |
38 | ### 如何安装
39 | ---
40 |
41 | #### 自动安装
42 |
43 | 使用 [Airpub CLI Installer](https://github.com/airpub/installer) 来安装 Airpub 的稳定版本:
44 | ```
45 | $ [sudo] npm install -g airpub-installer
46 | ```
47 | 新建站点目录:
48 | ```
49 | $ mkdir my-airpub-blog && cd my-airpub-blog
50 | ```
51 | 然后执行操作将相关的依赖全部安装完毕:
52 | ```
53 | $ airpub install
54 | ```
55 | airpub installer 将自动新建配置,仅需[简单编辑](#%E9%85%8D%E7%BD%AE%E6%8C%87%E5%8D%97):
56 | ```
57 | $ vi configs.js
58 | ```
59 | 大功告成!即可访问你的站点,开始 Airpub 简洁流畅的书写体验。
60 |
61 | #### 手动安装
62 |
63 | 手动安装 Airpub 也**异常简单**,仅需使用 Git 拉取主干代码,即可直接部署在静态资源服务器上:
64 | ```
65 | // 拉取代码
66 | $ git clone https://github.com/turingou/airpub.git
67 |
68 | // 手动新建配置文件
69 | $ cd airpub
70 | $ cp configs-sample.js configs.js
71 |
72 | // 根据提示编辑配置文件,填入多说配置与站点信息
73 | $ vi configs.js
74 | ```
75 | 配置填写完毕后,我们需要安装 Airpub 依赖的前端资源文件,执行:
76 |
77 | ```
78 | $ bower install
79 | ```
80 | 依赖安装完成后,即可访问你的站点,开始 Airpub 简洁流畅的书写体验。
81 |
82 | ### 配置指南
83 | ---
84 |
85 | Airpub 仅需简单配置,即可达成不错的写作与阅读效果。在 `configs.js` 中,你应该会注意到存在两种配置项:
86 |
87 | - `airpubConfig`: Airpub 博客系统本身的配置,包括站点名称,描述,以及其他元数据。
88 | * `name`: 站点名称
89 | * `description`: 站点描述
90 | * `url`: 线上访问地址,必须是绝对地址,用于分享
91 | * `upyun` 又拍云配置(用于上传图片)
92 | - `bucket`: 又拍云 bucket **名称**,在提供 `policy` 与 `signature` 时不需要提供
93 | - `policy`: 又拍云 policy,可通过 upyun-sign 命令行工具生成
94 | - `signature`: 又拍云 signature,可通过 upyun-sign 命令行工具生成
95 | - `form_api_secret`: 又拍云 `form_api_secret`,不推荐直接暴露在前端
96 | - `host`: 返回的图片的默认主机地址(可选)
97 | - `endpoint`: 默认 API 地址(可选)
98 |
99 | - `duoshuoQuery`: 你的多说站点信息,目前仅需要提供 `short_name`
100 |
101 | Airpub 鉴权基于多说用户系统,这意味着你不需要对 管理员 身份进行任何配置,仅需使用生成该 `short_name` 相应的多说用户登录即可进行文章的新建与管理操作。
102 |
103 | **重要提示**: 如你的多说 `short_name` 之前有在任何服务中使用过,请申请全新的多说站点以获得不同的 `short_name`,我们推荐你采用这样的方式来管理自己不同的多说站点之间的关系,例如 `myname-wordpress` 和 `myname-airpub`。
104 |
105 | **重要提示**: 建议你在多说管理后台(站点管理 => 设置 => 文章信息来源)开启 `只接受来自服务器的文章信息请求` 选项,防止非 API 请求造成的非法数据写入。
106 |
107 | **提示**: 由于表单上传会暴露您的 `form_api_secret`,建议开启防盗链模式,并经常性更换 `form_api_secret`。如果你选择这种方式在前端进行摘要计算,记得在自己的页面上额外引入 `js-base64` 与 `js-md5` 的代码库。
108 |
109 | ### 开发指南
110 | ---
111 |
112 | Airpub 的前端依赖基于 bower 构建,工作流基于 NPM 构建。在进行 Airpub 二次开发之前,确保你有安装 Node.js、NPM 以及 bower,然后执行以下步骤:
113 |
114 | ```
115 | $ cd airpub
116 | $ bower install
117 | $ npm install
118 | $ npm run dev
119 | ```
120 |
121 | 命令 `$ npm run dev` 将再 `localhost:3000` 运行一个静态资源服务器,并实时压缩 dist 文件。需要确保这个端口没有被占用后再执行此操作。
122 |
123 | ### 贡献代码
124 | ---
125 |
126 | 欢迎为 Airpub 贡献代码。如果你有兴趣为 Airpub 贡献代码,请先查阅本项目中的相关代码,fork 项目后,再提交 pull request。
127 | 如果你对 Airpub 计划中的主题系统或 add-on 系统感兴趣,欢迎在 [issue](https://github.com/duoshuo/airpub/issues) 区提交新话题。
128 |
129 | ### MIT license
130 | Copyright (c) 2014 Guo Yu <o.u.turing@gmail.com>
131 |
132 | Permission is hereby granted, free of charge, to any person obtaining a copy
133 | of this software and associated documentation files (the "Software"), to deal
134 | in the Software without restriction, including without limitation the rights
135 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
136 | copies of the Software, and to permit persons to whom the Software is
137 | furnished to do so, subject to the following conditions:
138 |
139 | The above copyright notice and this permission notice shall be included in
140 | all copies or substantial portions of the Software.
141 |
142 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
143 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
144 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
145 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
146 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
147 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
148 | THE SOFTWARE.
149 |
150 | ---
151 | 
152 | generated using [docor](https://github.com/turingou/docor.git) @ 0.1.0. brought to you by [turingou](https://github.com/turingou)
--------------------------------------------------------------------------------
/src/airpub.js:
--------------------------------------------------------------------------------
1 | ;(function(angular, debug) {
2 | 'use strict';
3 |
4 | angular
5 | .module('airpub', [
6 | 'upyun',
7 | 'duoshuo',
8 | 'ui.router',
9 | 'ui.bootstrap',
10 | 'oc.lazyLoad',
11 | 'ngSanitize'
12 | ]).config([
13 | '$stateProvider',
14 | '$urlRouterProvider',
15 | '$locationProvider',
16 | '$ocLazyLoadProvider',
17 | 'upyunProvider',
18 | initAirpub
19 | ]);
20 |
21 | function initAirpub($stateProvider, $urlRouterProvider, $locationProvider, $ocLazyLoadProvider, upyunProvider) {
22 | // Theme configs
23 | var theme = airpubConfigs.theme || 'chill';
24 | var themePath = (airpubConfigs.themePath || 'bower_components') + '/' + theme;
25 | var staticPath = airpubConfigs.staticPath || '';
26 |
27 | // Init Router objects
28 | var routers = defineRoutes(['archive', 'single', 'admin', '404', 'layout']);
29 |
30 | // Routes configs
31 | $urlRouterProvider.otherwise("/404");
32 | // Signup routes uri
33 | $stateProvider
34 | .state('layout', routerMaker('', routers.layout))
35 | .state('layout.home', routerMaker('/', routers.layout)) // alias router for layout
36 | .state('layout.pager', routerMaker('/page/:page', routers.archive))
37 | .state('layout.single', routerMaker('/article/:uri', routers.single))
38 | .state('layout.create', routerMaker('/create', routers.admin, appendTitleToRouter('写新文章')))
39 | .state('layout.update', routerMaker('/article/:uri/update', routers.admin, appendTitleToRouter('更新文章')))
40 | .state('layout.404', routerMaker('/404', routers['404']));
41 |
42 | // Rredefine async loaded scripts
43 | $ocLazyLoadProvider.config({
44 | modules: [{
45 | name: 'EditorNinja',
46 | files: [
47 | staticPath + 'bower_components/ninja/dist/ninja.min.js',
48 | staticPath + 'bower_components/ninja/dist/ninja.min.css'
49 | ]
50 | },{
51 | name: 'EditorNinja.upload',
52 | files: [
53 | staticPath + 'bower_components/ninja/dist/ninja.min.js'
54 | ]
55 | }]
56 | });
57 |
58 | // Hashtag config
59 | $locationProvider
60 | .hashPrefix(airpubConfigs.hashPrefix || '!');
61 |
62 | // Html5 mode should also be supported by server side, check this out:
63 | // http://stackoverflow.com/questions/18452832/angular-route-with-html5mode-giving-not-found-page-after-reload
64 | if (airpubConfigs.html5Mode)
65 | $locationProvider.html5Mode(true);
66 |
67 | if (airpubConfigs.upyun)
68 | upyunProvider.config(airpubConfigs.upyun);
69 |
70 | initWeixinShare();
71 |
72 | function defineRoutes(routes) {
73 | var routers = {};
74 |
75 | angular.forEach(routes, function(route) {
76 | routers[route] = {};
77 | routers[route].templateUrl = themePath + '/' + route + '.html';
78 | if (route !== '404')
79 | routers[route].controller = route;
80 | // Define the LAYOUT router
81 | if (route === 'layout') {
82 | // Define default sub-views of layout
83 | routers[route].views = {
84 | 'layout': routers.layout,
85 | '@layout': routers.archive,
86 | '@layout.home': routers.archive
87 | }
88 | }
89 |
90 | if (['admin', 'single'].indexOf(route) > -1)
91 | routers[route].resolve = lazyloadResources(route);
92 | });
93 |
94 | return routers;
95 | }
96 |
97 | function lazyloadResources(route) {
98 | var map = {
99 | admin: loadEditor,
100 | single: loadSingle
101 | };
102 |
103 | return {
104 | lazyload: ['$ocLazyLoad', map[route]]
105 | }
106 | }
107 |
108 | // Load EditorNinja async
109 | function loadEditor($ocLazyLoad) {
110 | return $ocLazyLoad.load('EditorNinja').then(function(){
111 | // Load ninja addons
112 | $ocLazyLoad.load('EditorNinja.upload');
113 | // Load other deps in `admin.html`
114 | $ocLazyLoad.load({
115 | files: [
116 | staticPath + 'bower_components/node-uuid/uuid.js'
117 | ]
118 | });
119 | });
120 | }
121 |
122 | function loadSingle($ocLazyLoad) {
123 | return $ocLazyLoad.load({
124 | files: [
125 | staticPath + 'bower_components/marked/lib/marked.js',
126 | staticPath + 'bower_components/highlightjs/highlight.pack.js',
127 | ]
128 | });
129 | }
130 |
131 | function routerMaker(url, router, data) {
132 | var obj = angular.copy(router);
133 | obj.url = url;
134 | if (data && typeof(data) === 'object')
135 | obj = angular.extend(obj, data);
136 | return obj;
137 | }
138 |
139 | function appendTitleToRouter(title) {
140 | return {
141 | data: {
142 | title: title
143 | }
144 | }
145 | }
146 |
147 | function initWeixinShare() {
148 | if (!window.wechat)
149 | return;
150 |
151 | var data = {};
152 |
153 | if (airpubConfigs.url)
154 | data.link = airpubConfigs.url;
155 | if (airpubConfigs.description)
156 | data.desc = airpubConfigs.description;
157 | if (airpubConfigs.name)
158 | data.title = airpubConfigs.name;
159 |
160 | window.wechat('friend', data);
161 | window.wechat('timeline', data);
162 | window.wechat('weibo', data);
163 | }
164 | }
165 | })(window.angular, window.debug);
166 |
--------------------------------------------------------------------------------
/src/controllers/admin.js:
--------------------------------------------------------------------------------
1 | ;(function(angular, debug) {
2 | 'use strict';
3 |
4 | angular
5 | .module('airpub')
6 | .controller('admin', [
7 | '$scope',
8 | '$state',
9 | 'duoshuo',
10 | '$location',
11 | '$rootScope',
12 | adminCtrler
13 | ]);
14 |
15 | function adminCtrler($scope, $state, duoshuo, $location, $rootScope) {
16 | // Reset isAdmin status
17 | $scope.isAdmin = false;
18 |
19 | var baseUri = $scope.configs.url || $location.host();
20 | var hashPrefix = $scope.configs.hashPrefix || '!';
21 | var hashTag = '/#' + hashPrefix;
22 |
23 | initAdmin();
24 |
25 | // Expose functions to templates
26 | $scope.createArticle = createArticle;
27 | $scope.updateArticle = updateArticle;
28 | $scope.removeArticle = removeArticle;
29 | $scope.on = eventBinder;
30 |
31 | // Init admin page
32 | function initAdmin() {
33 | $rootScope.$emit('updateMeta', $state.current.data.title);
34 |
35 | // Open a request
36 | duoshuo.get('sites/membership', {}, onSuccess, onError);
37 |
38 | function onSuccess(err, result) {
39 | if (err || result.role !== 'administrator')
40 | return $state.go('layout.home');
41 |
42 | var isUpdatePage = $state.current.name === 'layout.update' && $state.params.uri;
43 |
44 | // If status is `update`, fetch data
45 | if (!isUpdatePage) {
46 | $scope.isAdmin = true;
47 | return;
48 | }
49 |
50 | var query = {};
51 | query.thread_id = $state.params.uri;
52 |
53 | // Fetch article details in edit mode.
54 | duoshuo.get('threads/details', query, response, fail);
55 |
56 | function response(err, result) {
57 | // Now show the page
58 | $scope.isAdmin = true;
59 |
60 | if (err)
61 | return fail(err);
62 |
63 | // Expose article locals to template
64 | $scope.article = result;
65 | }
66 |
67 | function fail(err) {
68 | return $scope.addAlert('文章内容获取失败,请稍后再试...', 'danger');
69 | }
70 | }
71 |
72 | // Error callback
73 | function onError(err) {
74 | $scope.addAlert(err.errorMessage, 'danger');
75 | $state.go('layout.home');
76 | }
77 | }
78 |
79 | // Create a new article
80 | function createArticle() {
81 | if (!$scope.isAdmin)
82 | return false;
83 | if (!$scope.article.title)
84 | return $scope.addAlert('至少写个标题咯...', 'danger');
85 | if (!$scope.article.content)
86 | return $scope.addAlert('至少写点内容咯...', 'danger');
87 |
88 | var baby = {};
89 | baby.format = 'markdown';
90 | baby.title = $scope.article.title;
91 | baby.content = $scope.article.content;
92 | baby.thread_key = uuid.v1();
93 | baby = insertMeta(baby);
94 |
95 | // Trigger events
96 | eventTrigger('beforeCreate', baby);
97 |
98 | // Open a request
99 | duoshuo.post('threads/create', baby, onSuccess, onError);
100 |
101 | function onSuccess(err, result) {
102 | if (err)
103 | return $scope.addAlert('发布失败...', 'danger');
104 |
105 | $scope.addAlert('发布成功');
106 |
107 | // Update article URI
108 | // TODO: Merge this two request in one.
109 | var query = {};
110 | query.thread_id = result.thread_id;
111 | query.url = baseUri + hashTag + '/article/' + result.thread_id;
112 |
113 | // Open a request
114 | duoshuo.post('threads/update', query, response);
115 |
116 | // Trigger events
117 | eventTrigger('afterCreate', result);
118 |
119 | function response(err, res) {
120 | if (err)
121 | console.log(err);
122 |
123 | $state.go('layout.single', {
124 | uri: result.thread_id
125 | });
126 | }
127 | }
128 |
129 | function onError(err) {
130 | return $scope.addAlert('发布失败...', 'danger');
131 | }
132 | };
133 |
134 | // Update a exist article
135 | function updateArticle(id) {
136 | if (!id)
137 | return $scope.createArticle();
138 | if (!$scope.isAdmin)
139 | return false;
140 |
141 | var baby = {};
142 | baby.thread_id = id;
143 | baby.title = $scope.article.title;
144 | baby.content = $scope.article.content;
145 | baby.url = baseUri + hashTag + '/article/' + id;
146 | baby = insertMeta(baby);
147 |
148 | // Trigger events
149 | eventTrigger('beforeUpdate', baby);
150 |
151 | // Open a request
152 | duoshuo.post('threads/update', baby, onSuccess, onError);
153 |
154 | function onSuccess(err, result) {
155 | if (err)
156 | return $scope.addAlert('更新失败,请稍后再试...', 'danger');
157 |
158 | $scope.addAlert('更新成功!');
159 |
160 | // Trigger events
161 | eventTrigger('afterUpdate', result);
162 |
163 | // Goto article details page
164 | $state.go('layout.single', {
165 | uri: id
166 | });
167 | }
168 |
169 | function onError(err) {
170 | return $scope.addAlert('更新失败,请稍后再试...', 'danger');
171 | }
172 | };
173 |
174 | // Remove a exist article
175 | function removeArticle(id) {
176 | if (!id)
177 | return false;
178 | if (!$scope.isAdmin)
179 | return false;
180 |
181 | // Trigger events
182 | eventTrigger('beforeRemove', id);
183 |
184 | // TODO: Confirm delete action
185 | var query = {};
186 | query.thread_id = id;
187 |
188 | // Open a request
189 | duoshuo.post('threads/remove', query, onSuccess, onError);
190 |
191 | function onSuccess(err, result) {
192 | if (err)
193 | return $scope.addAlert('删除失败,请稍后再试...', 'danger');
194 |
195 | // Trigger events
196 | eventTrigger('afterRemove', id);
197 |
198 | $scope.addAlert('删除成功!');
199 | $state.go('layout.home');
200 | }
201 |
202 | function onError(err) {
203 | return $scope.addAlert('删除失败,请稍后再试...', 'danger');
204 | }
205 | };
206 |
207 | // Insert meta to plain text query string.
208 | function insertMeta(qs) {
209 | if (!$scope.article.meta)
210 | return qs;
211 |
212 | angular.forEach($scope.article.meta, function(v, k) {
213 | qs['meta[' + k + ']'] = v;
214 | });
215 |
216 | return qs;
217 | }
218 |
219 | // Bind events
220 | function eventBinder(eventName, func) {
221 | if (!eventName || !func || typeof(func) !== 'function')
222 | return false;
223 |
224 | if (!$scope.bindedEvents)
225 | $scope.bindedEvents = {};
226 |
227 | $scope.bindedEvents[eventName] = func;
228 |
229 | return $scope.bindedEvents;
230 | }
231 |
232 | // Events trigger
233 | function eventTrigger(eventName, data) {
234 | if (!$scope.bindedEvents || !$scope.bindedEvents[eventName])
235 | return;
236 | return $scope.bindedEvents[eventName](data || $scope.article, eventName);
237 | }
238 | }
239 | })(window.angular, window.debug);
240 |
--------------------------------------------------------------------------------
/libs/ui-bootstrap-custom-0.12.0.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * angular-ui-bootstrap
3 | * http://angular-ui.github.io/bootstrap/
4 |
5 | * Version: 0.12.0 - 2014-11-16
6 | * License: MIT
7 | */
8 | angular.module("ui.bootstrap",["ui.bootstrap.transition","ui.bootstrap.alert","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.position","ui.bootstrap.bindHtml","ui.bootstrap.collapse"]),angular.module("ui.bootstrap.transition",[]).factory("$transition",["$q","$timeout","$rootScope",function(t,n,e){function i(t){for(var n in t)if(void 0!==a.style[n])return t[n]}var o=function(i,a,r){r=r||{};var l=t.defer(),s=o[r.animation?"animationEndEventName":"transitionEndEventName"],u=function(){e.$apply(function(){i.unbind(s,u),l.resolve(i)})};return s&&i.bind(s,u),n(function(){angular.isString(a)?i.addClass(a):angular.isFunction(a)?a(i):angular.isObject(a)&&i.css(a),s||l.resolve(i)}),l.promise.cancel=function(){s&&i.unbind(s,u),l.reject("Transition cancelled")},l.promise},a=document.createElement("trans"),r={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",transition:"transitionend"},l={WebkitTransition:"webkitAnimationEnd",MozTransition:"animationend",OTransition:"oAnimationEnd",transition:"animationend"};return o.transitionEndEventName=i(r),o.animationEndEventName=i(l),o}]),angular.module("ui.bootstrap.alert",[]).controller("AlertController",["$scope","$attrs",function(t,n){t.closeable="close"in n,this.close=t.close}]).directive("alert",function(){return{restrict:"EA",controller:"AlertController",templateUrl:"template/alert/alert.html",transclude:!0,replace:!0,scope:{type:"@",close:"&"}}}).directive("dismissOnTimeout",["$timeout",function(t){return{require:"alert",link:function(n,e,i,o){t(function(){o.close()},parseInt(i.dismissOnTimeout,10))}}}]),angular.module("ui.bootstrap.pagination",[]).controller("PaginationController",["$scope","$attrs","$parse",function(t,n,e){var i=this,o={$setViewValue:angular.noop},a=n.numPages?e(n.numPages).assign:angular.noop;this.init=function(a,r){o=a,this.config=r,o.$render=function(){i.render()},n.itemsPerPage?t.$parent.$watch(e(n.itemsPerPage),function(n){i.itemsPerPage=parseInt(n,10),t.totalPages=i.calculateTotalPages()}):this.itemsPerPage=r.itemsPerPage},this.calculateTotalPages=function(){var n=this.itemsPerPage<1?1:Math.ceil(t.totalItems/this.itemsPerPage);return Math.max(n||0,1)},this.render=function(){t.page=parseInt(o.$viewValue,10)||1},t.selectPage=function(n){t.page!==n&&n>0&&n<=t.totalPages&&(o.$setViewValue(n),o.$render())},t.getText=function(n){return t[n+"Text"]||i.config[n+"Text"]},t.noPrevious=function(){return 1===t.page},t.noNext=function(){return t.page===t.totalPages},t.$watch("totalItems",function(){t.totalPages=i.calculateTotalPages()}),t.$watch("totalPages",function(n){a(t.$parent,n),t.page>n?t.selectPage(n):o.$render()})}]).constant("paginationConfig",{itemsPerPage:10,boundaryLinks:!1,directionLinks:!0,firstText:"First",previousText:"Previous",nextText:"Next",lastText:"Last",rotate:!0}).directive("pagination",["$parse","paginationConfig",function(t,n){return{restrict:"EA",scope:{totalItems:"=",firstText:"@",previousText:"@",nextText:"@",lastText:"@"},require:["pagination","?ngModel"],controller:"PaginationController",templateUrl:"template/pagination/pagination.html",replace:!0,link:function(e,i,o,a){function r(t,n,e){return{number:t,text:n,active:e}}function l(t,n){var e=[],i=1,o=n,a=angular.isDefined(c)&&n>c;a&&(p?(i=Math.max(t-Math.floor(c/2),1),o=i+c-1,o>n&&(o=n,i=o-c+1)):(i=(Math.ceil(t/c)-1)*c+1,o=Math.min(i+c-1,n)));for(var l=i;o>=l;l++){var s=r(l,l,l===t);e.push(s)}if(a&&!p){if(i>1){var u=r(i-1,"...",!1);e.unshift(u)}if(n>o){var f=r(o+1,"...",!1);e.push(f)}}return e}var s=a[0],u=a[1];if(u){var c=angular.isDefined(o.maxSize)?e.$parent.$eval(o.maxSize):n.maxSize,p=angular.isDefined(o.rotate)?e.$parent.$eval(o.rotate):n.rotate;e.boundaryLinks=angular.isDefined(o.boundaryLinks)?e.$parent.$eval(o.boundaryLinks):n.boundaryLinks,e.directionLinks=angular.isDefined(o.directionLinks)?e.$parent.$eval(o.directionLinks):n.directionLinks,s.init(u,n),o.maxSize&&e.$parent.$watch(t(o.maxSize),function(t){c=parseInt(t,10),s.render()});var f=s.render;s.render=function(){f(),e.page>0&&e.page<=e.totalPages&&(e.pages=l(e.page,e.totalPages))}}}}}]).constant("pagerConfig",{itemsPerPage:10,previousText:"« Previous",nextText:"Next »",align:!0}).directive("pager",["pagerConfig",function(t){return{restrict:"EA",scope:{totalItems:"=",previousText:"@",nextText:"@"},require:["pager","?ngModel"],controller:"PaginationController",templateUrl:"template/pagination/pager.html",replace:!0,link:function(n,e,i,o){var a=o[0],r=o[1];r&&(n.align=angular.isDefined(i.align)?n.$parent.$eval(i.align):t.align,a.init(r,t))}}}]),angular.module("ui.bootstrap.tooltip",["ui.bootstrap.position","ui.bootstrap.bindHtml"]).provider("$tooltip",function(){function t(t){var n=/[A-Z]/g,e="-";return t.replace(n,function(t,n){return(n?e:"")+t.toLowerCase()})}var n={placement:"top",animation:!0,popupDelay:0},e={mouseenter:"mouseleave",click:"click",focus:"blur"},i={};this.options=function(t){angular.extend(i,t)},this.setTriggers=function(t){angular.extend(e,t)},this.$get=["$window","$compile","$timeout","$document","$position","$interpolate",function(o,a,r,l,s,u){return function(o,c,p){function f(t){var n=t||d.trigger||p,i=e[n]||n;return{show:n,hide:i}}var d=angular.extend({},n,i),g=t(o),m=u.startSymbol(),h=u.endSymbol(),v="';return{restrict:"EA",compile:function(){var t=a(v);return function(n,e,i){function a(){O.isOpen?p():u()}function u(){(!D||n.$eval(i[c+"Enable"]))&&($(),O.popupDelay?C||(C=r(g,O.popupDelay,!1),C.then(function(t){t()})):g()())}function p(){n.$apply(function(){m()})}function g(){return C=null,w&&(r.cancel(w),w=null),O.content?(h(),x.css({top:0,left:0,display:"block"}),E?l.find("body").append(x):e.after(x),L(),O.isOpen=!0,O.$digest(),L):angular.noop}function m(){O.isOpen=!1,r.cancel(C),C=null,O.animation?w||(w=r(v,500)):v()}function h(){x&&v(),y=O.$new(),x=t(y,angular.noop)}function v(){w=null,x&&(x.remove(),x=null),y&&(y.$destroy(),y=null)}function $(){b(),P()}function b(){var t=i[c+"Placement"];O.placement=angular.isDefined(t)?t:d.placement}function P(){var t=i[c+"PopupDelay"],n=parseInt(t,10);O.popupDelay=isNaN(n)?d.popupDelay:n}function T(){var t=i[c+"Trigger"];H(),k=f(t),k.show===k.hide?e.bind(k.show,a):(e.bind(k.show,u),e.bind(k.hide,p))}var x,y,w,C,E=angular.isDefined(d.appendToBody)?d.appendToBody:!1,k=f(void 0),D=angular.isDefined(i[c+"Enable"]),O=n.$new(!0),L=function(){var t=s.positionElements(e,x,O.placement,E);t.top+="px",t.left+="px",x.css(t)};O.isOpen=!1,i.$observe(o,function(t){O.content=t,!t&&O.isOpen&&m()}),i.$observe(c+"Title",function(t){O.title=t});var H=function(){e.unbind(k.show,u),e.unbind(k.hide,p)};T();var S=n.$eval(i[c+"Animation"]);O.animation=angular.isDefined(S)?!!S:d.animation;var A=n.$eval(i[c+"AppendToBody"]);E=angular.isDefined(A)?A:E,E&&n.$on("$locationChangeSuccess",function(){O.isOpen&&m()}),n.$on("$destroy",function(){r.cancel(w),r.cancel(C),H(),v(),O=null})}}}}}]}).directive("tooltipPopup",function(){return{restrict:"EA",replace:!0,scope:{content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-popup.html"}}).directive("tooltip",["$tooltip",function(t){return t("tooltip","tooltip","mouseenter")}]).directive("tooltipHtmlUnsafePopup",function(){return{restrict:"EA",replace:!0,scope:{content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-html-unsafe-popup.html"}}).directive("tooltipHtmlUnsafe",["$tooltip",function(t){return t("tooltipHtmlUnsafe","tooltip","mouseenter")}]),angular.module("ui.bootstrap.position",[]).factory("$position",["$document","$window",function(t,n){function e(t,e){return t.currentStyle?t.currentStyle[e]:n.getComputedStyle?n.getComputedStyle(t)[e]:t.style[e]}function i(t){return"static"===(e(t,"position")||"static")}var o=function(n){for(var e=t[0],o=n.offsetParent||e;o&&o!==e&&i(o);)o=o.offsetParent;return o||e};return{position:function(n){var e=this.offset(n),i={top:0,left:0},a=o(n[0]);a!=t[0]&&(i=this.offset(angular.element(a)),i.top+=a.clientTop-a.scrollTop,i.left+=a.clientLeft-a.scrollLeft);var r=n[0].getBoundingClientRect();return{width:r.width||n.prop("offsetWidth"),height:r.height||n.prop("offsetHeight"),top:e.top-i.top,left:e.left-i.left}},offset:function(e){var i=e[0].getBoundingClientRect();return{width:i.width||e.prop("offsetWidth"),height:i.height||e.prop("offsetHeight"),top:i.top+(n.pageYOffset||t[0].documentElement.scrollTop),left:i.left+(n.pageXOffset||t[0].documentElement.scrollLeft)}},positionElements:function(t,n,e,i){var o,a,r,l,s=e.split("-"),u=s[0],c=s[1]||"center";o=i?this.offset(t):this.position(t),a=n.prop("offsetWidth"),r=n.prop("offsetHeight");var p={center:function(){return o.left+o.width/2-a/2},left:function(){return o.left},right:function(){return o.left+o.width}},f={center:function(){return o.top+o.height/2-r/2},top:function(){return o.top},bottom:function(){return o.top+o.height}};switch(u){case"right":l={top:f[c](),left:p[u]()};break;case"left":l={top:f[c](),left:o.left-a};break;case"bottom":l={top:f[u](),left:p[c]()};break;default:l={top:o.top-r,left:p[c]()}}return l}}}]),angular.module("ui.bootstrap.bindHtml",[]).directive("bindHtmlUnsafe",function(){return function(t,n,e){n.addClass("ng-binding").data("$binding",e.bindHtmlUnsafe),t.$watch(e.bindHtmlUnsafe,function(t){n.html(t||"")})}}),angular.module("ui.bootstrap.collapse",["ui.bootstrap.transition"]).directive("collapse",["$transition",function(t){return{link:function(n,e,i){function o(n){function i(){u===o&&(u=void 0)}var o=t(e,n);return u&&u.cancel(),u=o,o.then(i,i),o}function a(){c?(c=!1,r()):(e.removeClass("collapse").addClass("collapsing"),o({height:e[0].scrollHeight+"px"}).then(r))}function r(){e.removeClass("collapsing"),e.addClass("collapse in"),e.css({height:"auto"})}function l(){if(c)c=!1,s(),e.css({height:0});else{e.css({height:e[0].scrollHeight+"px"});{e[0].offsetWidth}e.removeClass("collapse in").addClass("collapsing"),o({height:0}).then(s)}}function s(){e.removeClass("collapsing"),e.addClass("collapse")}var u,c=!0;n.$watch(i.collapse,function(t){t?l():a()})}}}]);
--------------------------------------------------------------------------------
/dist/airpub.min.js:
--------------------------------------------------------------------------------
1 | !function(e){"use strict";function t(t,n,r,i,a){function o(t){var n={};return e.forEach(t,function(e){n[e]={},n[e].templateUrl=p+"/"+e+".html","404"!==e&&(n[e].controller=e),"layout"===e&&(n[e].views={layout:n.layout,"@layout":n.archive,"@layout.home":n.archive}),["admin","single"].indexOf(e)>-1&&(n[e].resolve=u(e))}),n}function u(e){var t={admin:c,single:d};return{lazyload:["$ocLazyLoad",t[e]]}}function c(e){return e.load("EditorNinja").then(function(){e.load("EditorNinja.upload"),e.load({files:[m+"bower_components/node-uuid/uuid.js"]})})}function d(e){return e.load({files:[m+"bower_components/marked/lib/marked.js",m+"bower_components/highlightjs/highlight.pack.js"]})}function l(t,n,r){var i=e.copy(n);return i.url=t,r&&"object"==typeof r&&(i=e.extend(i,r)),i}function s(e){return{data:{title:e}}}function f(){if(window.wechat){var e={};airpubConfigs.url&&(e.link=airpubConfigs.url),airpubConfigs.description&&(e.desc=airpubConfigs.description),airpubConfigs.name&&(e.title=airpubConfigs.name),window.wechat("friend",e),window.wechat("timeline",e),window.wechat("weibo",e)}}var g=airpubConfigs.theme||"chill",p=(airpubConfigs.themePath||"bower_components")+"/"+g,m=airpubConfigs.staticPath||"",h=o(["archive","single","admin","404","layout"]);n.otherwise("/404"),t.state("layout",l("",h.layout)).state("layout.home",l("/",h.layout)).state("layout.pager",l("/page/:page",h.archive)).state("layout.single",l("/article/:uri",h.single)).state("layout.create",l("/create",h.admin,s("写新文章"))).state("layout.update",l("/article/:uri/update",h.admin,s("更新文章"))).state("layout.404",l("/404",h[404])),i.config({modules:[{name:"EditorNinja",files:[m+"bower_components/ninja/dist/ninja.min.js",m+"bower_components/ninja/dist/ninja.min.css"]},{name:"EditorNinja.upload",files:[m+"bower_components/ninja/dist/ninja.min.js"]}]}),r.hashPrefix(airpubConfigs.hashPrefix||"!"),airpubConfigs.html5Mode&&r.html5Mode(!0),airpubConfigs.upyun&&a.config(airpubConfigs.upyun),f()}e.module("airpub",["upyun","duoshuo","ui.router","ui.bootstrap","oc.lazyLoad","ngSanitize"]).config(["$stateProvider","$urlRouterProvider","$locationProvider","$ocLazyLoadProvider","upyunProvider",t])}(window.angular,window.debug),function(e){"use strict";function t(t,n){return function(r){function i(e){return window.hljs.highlightAuto(e).value}function a(e){var t={};return e.forEach(function(e){var n=-1===e.indexOf(":")?"all":e.split(":")[0];t[n]=e.split(":")[1]}),t}function o(t,n){function r(t){var n=t.split(" ");if(1===n.length)return t.substr(1);var r="";return e.forEach(n,function(e){r+=e.substr(1)+" "}),r}var i=t.split(">");if(!i.length)return n;var a="";return e.forEach(i,function(e){var t="."===e.charAt(0)?"class":"id";a+="'}),a+=n,e.forEach(i,function(){a+="
"}),a}if(!r)return"";if(!marked)throw new Error("Marked.js is required!");var u;arguments.length>1&&(u=a(Array.prototype.slice.call(arguments,1)));var c={},d=new marked.Renderer;return d.code=function(e,t,r){var i=marked.Renderer.prototype.code.call(this,"unsafe-html"===t?n(e):e,t,r);return u&&u.code?o(u.code,i):i},e.forEach(["blockquote","html","heading","list","listitem","paragraph","table","tablerow","tablecell","image"],function(e){d[e]=function(){var t=marked.Renderer.prototype[e].apply(this,arguments);return u&&u[e]?o(u[e],t):u&&u.all?o(u.all,t):t}}),c.renderer=d,window.hljs&&(c.highlight=i),marked.setOptions(c),t.trustAsHtml(marked(r))}}e.module("airpub").filter("marked",["$sce","$sanitize",t])}(window.angular,window.debug),function(){"use strict";function e(){function e(e){if(window.wechat){var n=window.wechat,r={};angular.forEach(["title","link","desc"],function(n){r[n]=e[n]||t[n]}),n("friend",r),n("timeline",r),n("weibo",r)}}var t={title:"Airpub",link:"http://airpub.io",desc:"基于 Angular.js 搭建,多说数据驱动的纯前端写作工具。"};this.wechat=e}angular.module("airpub").service("share",[e])}(),function(e){"use strict";function t(e){return airpubConfigs?void(e.configs=airpubConfigs):console.error(new Error("airpub 缺少必要的配置文件!"))}e.module("airpub").controller("global",["$scope",t])}(window.angular,window.debug),function(e){"use strict";function t(t,n,r){t.title=t.configs.name||"Airpub",t.description=t.configs.description||"just another Airpub blog",r.wechat({title:t.configs.name,link:t.configs.url,desc:t.configs.description}),n.$on("updateMeta",function(n,r){return"string"==typeof r?t.title=r:void e.forEach(r,function(e,n){t[n]=e})})}e.module("airpub").controller("meta",["$scope","$rootScope","share",t])}(window.angular,window.debug),function(e){"use strict";function t(t,n,r,i,a){function o(e,n){var r=0===n.user_id;return e||r?void(t.isVisitor=!0):void(t.user=n)}function u(){t.hiddenSigninSection=!t.hiddenSigninSection}function c(e,n,i){t.alerts.push({msg:e,type:n||"success"});var a=t.alerts.length-1;return r(function(){t.closeAlert(a)},i?1e3*i:3e3),a}function d(e){t.alerts.splice(e,1)}function l(t,n){if(t&&(0===t.indexOf("http")||0===t.indexOf("https"))){var r=n||document.getElementsByTagName("header")[0];r&&e.element(r).css({"background-image":"url("+t+")"})}}t.location=i,t.state=n,t.hiddenSigninSection=!0,t.toggleSigninSection=u,t.alerts=[],t.addAlert=c,t.closeAlert=d,t.updateBackground=l,t.copyrightYear=(new Date).getFullYear(),a.on("ready",o)}function n(){}e.module("airpub").controller("layout",["$scope",n]).controller("base",["$scope","$state","$timeout","$location","duoshuo",t])}(window.angular,window.debug),function(e){"use strict";function t(e,t,n,r){function i(){function r(n,r,i){return t.params.page&&(u=!1),n?e.addAlert("获取信息失败,请重试","danger"):0===r.length?t.go("layout.404"):(e.articles=r||[],e.totalItems=i.cursor.total,void(t.params.page&&(e.currentPage=c)))}function i(){return t.go("layout.404")}var a={};a.page=e.currentPage,a.limit=e.itemsPerPage,a.with_content=1,n.get("threads/list",a,r,i)}function a(){u||t.go("layout.pager",{page:e.currentPage})}function o(e){return e&&!isNaN(parseInt(e))?parseInt(e):!1}if(e.itemsPerPage=10,e.currentPage=o(t.params.page)||1,r.$emit("updateMeta",e.configs.name),!(e.articles&&e.articles.length>0)){if(t.params.page)var u=!0,c=e.currentPage;i(),e.pageChanged=a}}e.module("airpub").controller("archive",["$scope","$state","duoshuo","$rootScope",t])}(window.angular,window.debug),function(e){"use strict";function t(e,t,n,r){function i(i){function o(t,n){return t?e.addAlert("文章内容获取失败,请稍后再试...","danger"):(e.article=n,r.$emit("updateMeta",{title:n.title,description:c(n.content)}),n.meta&&n.meta.background&&e.updateBackground(n.meta.background),void(n.author_id&&a(n)))}function u(){return t.go("layout.404")}function c(e){var t=80;return e?e.length<=t?e:e.substr(0,t)+"...":""}var d={};d.thread_id=i,n.get("threads/details",d,o,u)}function a(t){function r(t,n){t||(e.author=n,e.author.description=n.connected_services.weibo?n.connected_services.weibo.description:null)}var i={};i.user_id=t.author_id,n.get("users/profile",i,r)}return t.params.uri?(e.threadId=t.params.uri,void(e.article||i(t.params.uri))):t.go("layout.404")}e.module("airpub").controller("single",["$scope","$state","duoshuo","$rootScope",t])}(window.angular,window.debug),function(e){"use strict";function t(t,n,r,i,a){function o(){function e(e,i){function a(e,n){return t.isAdmin=!0,e?o(e):void(t.article=n)}function o(){return t.addAlert("文章内容获取失败,请稍后再试...","danger")}if(e||"administrator"!==i.role)return n.go("layout.home");var u="layout.update"===n.current.name&&n.params.uri;if(!u)return void(t.isAdmin=!0);var c={};c.thread_id=n.params.uri,r.get("threads/details",c,a,o)}function i(e){t.addAlert(e.errorMessage,"danger"),n.go("layout.home")}a.$emit("updateMeta",n.current.data.title),r.get("sites/membership",{},e,i)}function u(){function e(e,i){function a(e){e&&console.log(e),n.go("layout.single",{uri:i.thread_id})}if(e)return t.addAlert("发布失败...","danger");t.addAlert("发布成功");var o={};o.thread_id=i.thread_id,o.url=g+m+"/article/"+i.thread_id,r.post("threads/update",o,a),f("afterCreate",i)}function i(){return t.addAlert("发布失败...","danger")}if(!t.isAdmin)return!1;if(!t.article.title)return t.addAlert("至少写个标题咯...","danger");if(!t.article.content)return t.addAlert("至少写点内容咯...","danger");var a={};a.format="markdown",a.title=t.article.title,a.content=t.article.content,a.thread_key=uuid.v1(),a=l(a),f("beforeCreate",a),r.post("threads/create",a,e,i)}function c(e){function i(r,i){return r?t.addAlert("更新失败,请稍后再试...","danger"):(t.addAlert("更新成功!"),f("afterUpdate",i),void n.go("layout.single",{uri:e}))}function a(){return t.addAlert("更新失败,请稍后再试...","danger")}if(!e)return t.createArticle();if(!t.isAdmin)return!1;var o={};o.thread_id=e,o.title=t.article.title,o.content=t.article.content,o.url=g+m+"/article/"+e,o=l(o),f("beforeUpdate",o),r.post("threads/update",o,i,a)}function d(e){function i(r){return r?t.addAlert("删除失败,请稍后再试...","danger"):(f("afterRemove",e),t.addAlert("删除成功!"),void n.go("layout.home"))}function a(){return t.addAlert("删除失败,请稍后再试...","danger")}if(!e)return!1;if(!t.isAdmin)return!1;f("beforeRemove",e);var o={};o.thread_id=e,r.post("threads/remove",o,i,a)}function l(n){return t.article.meta?(e.forEach(t.article.meta,function(e,t){n["meta["+t+"]"]=e}),n):n}function s(e,n){return e&&n&&"function"==typeof n?(t.bindedEvents||(t.bindedEvents={}),t.bindedEvents[e]=n,t.bindedEvents):!1}function f(e,n){return t.bindedEvents&&t.bindedEvents[e]?t.bindedEvents[e](n||t.article,e):void 0}t.isAdmin=!1;var g=t.configs.url||i.host(),p=t.configs.hashPrefix||"!",m="/#"+p;o(),t.createArticle=u,t.updateArticle=c,t.removeArticle=d,t.on=s}e.module("airpub").controller("admin",["$scope","$state","duoshuo","$location","$rootScope",t])}(window.angular,window.debug),function(){"use strict";function e(e){function t(t,n,r,i){function a(){c||(c=!0,e.upload("metaBackgroundForm",function(e,t,n){if(c=!1,e)return console.error(e),alert("上传失败,请稍后再试...");var r=200===n.code&&"ok"===n.message;r&&(o(n.absUrl),i.$setViewValue(n.absUrl))}))}function o(e){if(e&&0===e.indexOf("http")){var t=document.getElementsByTagName("header")[0],n=document.getElementById("metaBackground");if(t){var r={};r["background-image"]="url("+e+")",u(t).css(r),u(n).css(r)}}}var u=angular.element,c=!1,d=document.getElementById("uploadBackgroundBtn");u(d).on("change",a),i.$render=function(){o(i.$viewValue)}}var n={restrict:"AE",require:"ngModel",replace:!0,link:t,template:['','","
"].join("\n")};return n}function t(e){function t(e,t,n,r){function i(){r.$setViewValue(e.checkToShare)}function a(e){return function(e){return}}e.checkToShare=!1,e.updateCheckStatus=i,e.on("afterCreate",a()),e.on("afterUpdate",a())}var n={restrict:"AE",require:"ngModel",replace:!0,link:t,template:['','','',"
"].join("\n")};return n}angular.module("airpub").directive("metaBackground",["upyun",e]).directive("metaShare",["duoshuo",t])}();
2 | //# sourceMappingURL=airpub.min.js.map
--------------------------------------------------------------------------------
/libs/ui-bootstrap-custom-tpls-0.12.0.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * angular-ui-bootstrap
3 | * http://angular-ui.github.io/bootstrap/
4 |
5 | * Version: 0.12.0 - 2014-11-16
6 | * License: MIT
7 | */
8 | angular.module("ui.bootstrap",["ui.bootstrap.tpls","ui.bootstrap.transition","ui.bootstrap.alert","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.position","ui.bootstrap.bindHtml","ui.bootstrap.collapse"]),angular.module("ui.bootstrap.tpls",["template/alert/alert.html","template/pagination/pager.html","template/pagination/pagination.html","template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html"]),angular.module("ui.bootstrap.transition",[]).factory("$transition",["$q","$timeout","$rootScope",function(t,e,n){function i(t){for(var e in t)if(void 0!==a.style[e])return t[e]}var o=function(i,a,r){r=r||{};var l=t.defer(),s=o[r.animation?"animationEndEventName":"transitionEndEventName"],u=function(){n.$apply(function(){i.unbind(s,u),l.resolve(i)})};return s&&i.bind(s,u),e(function(){angular.isString(a)?i.addClass(a):angular.isFunction(a)?a(i):angular.isObject(a)&&i.css(a),s||l.resolve(i)}),l.promise.cancel=function(){s&&i.unbind(s,u),l.reject("Transition cancelled")},l.promise},a=document.createElement("trans"),r={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",transition:"transitionend"},l={WebkitTransition:"webkitAnimationEnd",MozTransition:"animationend",OTransition:"oAnimationEnd",transition:"animationend"};return o.transitionEndEventName=i(r),o.animationEndEventName=i(l),o}]),angular.module("ui.bootstrap.alert",[]).controller("AlertController",["$scope","$attrs",function(t,e){t.closeable="close"in e,this.close=t.close}]).directive("alert",function(){return{restrict:"EA",controller:"AlertController",templateUrl:"template/alert/alert.html",transclude:!0,replace:!0,scope:{type:"@",close:"&"}}}).directive("dismissOnTimeout",["$timeout",function(t){return{require:"alert",link:function(e,n,i,o){t(function(){o.close()},parseInt(i.dismissOnTimeout,10))}}}]),angular.module("ui.bootstrap.pagination",[]).controller("PaginationController",["$scope","$attrs","$parse",function(t,e,n){var i=this,o={$setViewValue:angular.noop},a=e.numPages?n(e.numPages).assign:angular.noop;this.init=function(a,r){o=a,this.config=r,o.$render=function(){i.render()},e.itemsPerPage?t.$parent.$watch(n(e.itemsPerPage),function(e){i.itemsPerPage=parseInt(e,10),t.totalPages=i.calculateTotalPages()}):this.itemsPerPage=r.itemsPerPage},this.calculateTotalPages=function(){var e=this.itemsPerPage<1?1:Math.ceil(t.totalItems/this.itemsPerPage);return Math.max(e||0,1)},this.render=function(){t.page=parseInt(o.$viewValue,10)||1},t.selectPage=function(e){t.page!==e&&e>0&&e<=t.totalPages&&(o.$setViewValue(e),o.$render())},t.getText=function(e){return t[e+"Text"]||i.config[e+"Text"]},t.noPrevious=function(){return 1===t.page},t.noNext=function(){return t.page===t.totalPages},t.$watch("totalItems",function(){t.totalPages=i.calculateTotalPages()}),t.$watch("totalPages",function(e){a(t.$parent,e),t.page>e?t.selectPage(e):o.$render()})}]).constant("paginationConfig",{itemsPerPage:10,boundaryLinks:!1,directionLinks:!0,firstText:"First",previousText:"Previous",nextText:"Next",lastText:"Last",rotate:!0}).directive("pagination",["$parse","paginationConfig",function(t,e){return{restrict:"EA",scope:{totalItems:"=",firstText:"@",previousText:"@",nextText:"@",lastText:"@"},require:["pagination","?ngModel"],controller:"PaginationController",templateUrl:"template/pagination/pagination.html",replace:!0,link:function(n,i,o,a){function r(t,e,n){return{number:t,text:e,active:n}}function l(t,e){var n=[],i=1,o=e,a=angular.isDefined(p)&&e>p;a&&(c?(i=Math.max(t-Math.floor(p/2),1),o=i+p-1,o>e&&(o=e,i=o-p+1)):(i=(Math.ceil(t/p)-1)*p+1,o=Math.min(i+p-1,e)));for(var l=i;o>=l;l++){var s=r(l,l,l===t);n.push(s)}if(a&&!c){if(i>1){var u=r(i-1,"...",!1);n.unshift(u)}if(e>o){var f=r(o+1,"...",!1);n.push(f)}}return n}var s=a[0],u=a[1];if(u){var p=angular.isDefined(o.maxSize)?n.$parent.$eval(o.maxSize):e.maxSize,c=angular.isDefined(o.rotate)?n.$parent.$eval(o.rotate):e.rotate;n.boundaryLinks=angular.isDefined(o.boundaryLinks)?n.$parent.$eval(o.boundaryLinks):e.boundaryLinks,n.directionLinks=angular.isDefined(o.directionLinks)?n.$parent.$eval(o.directionLinks):e.directionLinks,s.init(u,e),o.maxSize&&n.$parent.$watch(t(o.maxSize),function(t){p=parseInt(t,10),s.render()});var f=s.render;s.render=function(){f(),n.page>0&&n.page<=n.totalPages&&(n.pages=l(n.page,n.totalPages))}}}}}]).constant("pagerConfig",{itemsPerPage:10,previousText:"« Previous",nextText:"Next »",align:!0}).directive("pager",["pagerConfig",function(t){return{restrict:"EA",scope:{totalItems:"=",previousText:"@",nextText:"@"},require:["pager","?ngModel"],controller:"PaginationController",templateUrl:"template/pagination/pager.html",replace:!0,link:function(e,n,i,o){var a=o[0],r=o[1];r&&(e.align=angular.isDefined(i.align)?e.$parent.$eval(i.align):t.align,a.init(r,t))}}}]),angular.module("ui.bootstrap.tooltip",["ui.bootstrap.position","ui.bootstrap.bindHtml"]).provider("$tooltip",function(){function t(t){var e=/[A-Z]/g,n="-";return t.replace(e,function(t,e){return(e?n:"")+t.toLowerCase()})}var e={placement:"top",animation:!0,popupDelay:0},n={mouseenter:"mouseleave",click:"click",focus:"blur"},i={};this.options=function(t){angular.extend(i,t)},this.setTriggers=function(t){angular.extend(n,t)},this.$get=["$window","$compile","$timeout","$document","$position","$interpolate",function(o,a,r,l,s,u){return function(o,p,c){function f(t){var e=t||g.trigger||c,i=n[e]||e;return{show:e,hide:i}}var g=angular.extend({},e,i),d=t(o),m=u.startSymbol(),h=u.endSymbol(),v="';return{restrict:"EA",compile:function(){var t=a(v);return function(e,n,i){function a(){O.isOpen?c():u()}function u(){(!D||e.$eval(i[p+"Enable"]))&&(b(),O.popupDelay?k||(k=r(d,O.popupDelay,!1),k.then(function(t){t()})):d()())}function c(){e.$apply(function(){m()})}function d(){return k=null,w&&(r.cancel(w),w=null),O.content?(h(),T.css({top:0,left:0,display:"block"}),C?l.find("body").append(T):n.after(T),L(),O.isOpen=!0,O.$digest(),L):angular.noop}function m(){O.isOpen=!1,r.cancel(k),k=null,O.animation?w||(w=r(v,500)):v()}function h(){T&&v(),y=O.$new(),T=t(y,angular.noop)}function v(){w=null,T&&(T.remove(),T=null),y&&(y.$destroy(),y=null)}function b(){$(),P()}function $(){var t=i[p+"Placement"];O.placement=angular.isDefined(t)?t:g.placement}function P(){var t=i[p+"PopupDelay"],e=parseInt(t,10);O.popupDelay=isNaN(e)?g.popupDelay:e}function x(){var t=i[p+"Trigger"];H(),E=f(t),E.show===E.hide?n.bind(E.show,a):(n.bind(E.show,u),n.bind(E.hide,c))}var T,y,w,k,C=angular.isDefined(g.appendToBody)?g.appendToBody:!1,E=f(void 0),D=angular.isDefined(i[p+"Enable"]),O=e.$new(!0),L=function(){var t=s.positionElements(n,T,O.placement,C);t.top+="px",t.left+="px",T.css(t)};O.isOpen=!1,i.$observe(o,function(t){O.content=t,!t&&O.isOpen&&m()}),i.$observe(p+"Title",function(t){O.title=t});var H=function(){n.unbind(E.show,u),n.unbind(E.hide,c)};x();var S=e.$eval(i[p+"Animation"]);O.animation=angular.isDefined(S)?!!S:g.animation;var A=e.$eval(i[p+"AppendToBody"]);C=angular.isDefined(A)?A:C,C&&e.$on("$locationChangeSuccess",function(){O.isOpen&&m()}),e.$on("$destroy",function(){r.cancel(w),r.cancel(k),H(),v(),O=null})}}}}}]}).directive("tooltipPopup",function(){return{restrict:"EA",replace:!0,scope:{content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-popup.html"}}).directive("tooltip",["$tooltip",function(t){return t("tooltip","tooltip","mouseenter")}]).directive("tooltipHtmlUnsafePopup",function(){return{restrict:"EA",replace:!0,scope:{content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-html-unsafe-popup.html"}}).directive("tooltipHtmlUnsafe",["$tooltip",function(t){return t("tooltipHtmlUnsafe","tooltip","mouseenter")}]),angular.module("ui.bootstrap.position",[]).factory("$position",["$document","$window",function(t,e){function n(t,n){return t.currentStyle?t.currentStyle[n]:e.getComputedStyle?e.getComputedStyle(t)[n]:t.style[n]}function i(t){return"static"===(n(t,"position")||"static")}var o=function(e){for(var n=t[0],o=e.offsetParent||n;o&&o!==n&&i(o);)o=o.offsetParent;return o||n};return{position:function(e){var n=this.offset(e),i={top:0,left:0},a=o(e[0]);a!=t[0]&&(i=this.offset(angular.element(a)),i.top+=a.clientTop-a.scrollTop,i.left+=a.clientLeft-a.scrollLeft);var r=e[0].getBoundingClientRect();return{width:r.width||e.prop("offsetWidth"),height:r.height||e.prop("offsetHeight"),top:n.top-i.top,left:n.left-i.left}},offset:function(n){var i=n[0].getBoundingClientRect();return{width:i.width||n.prop("offsetWidth"),height:i.height||n.prop("offsetHeight"),top:i.top+(e.pageYOffset||t[0].documentElement.scrollTop),left:i.left+(e.pageXOffset||t[0].documentElement.scrollLeft)}},positionElements:function(t,e,n,i){var o,a,r,l,s=n.split("-"),u=s[0],p=s[1]||"center";o=i?this.offset(t):this.position(t),a=e.prop("offsetWidth"),r=e.prop("offsetHeight");var c={center:function(){return o.left+o.width/2-a/2},left:function(){return o.left},right:function(){return o.left+o.width}},f={center:function(){return o.top+o.height/2-r/2},top:function(){return o.top},bottom:function(){return o.top+o.height}};switch(u){case"right":l={top:f[p](),left:c[u]()};break;case"left":l={top:f[p](),left:o.left-a};break;case"bottom":l={top:f[u](),left:c[p]()};break;default:l={top:o.top-r,left:c[p]()}}return l}}}]),angular.module("ui.bootstrap.bindHtml",[]).directive("bindHtmlUnsafe",function(){return function(t,e,n){e.addClass("ng-binding").data("$binding",n.bindHtmlUnsafe),t.$watch(n.bindHtmlUnsafe,function(t){e.html(t||"")})}}),angular.module("ui.bootstrap.collapse",["ui.bootstrap.transition"]).directive("collapse",["$transition",function(t){return{link:function(e,n,i){function o(e){function i(){u===o&&(u=void 0)}var o=t(n,e);return u&&u.cancel(),u=o,o.then(i,i),o}function a(){p?(p=!1,r()):(n.removeClass("collapse").addClass("collapsing"),o({height:n[0].scrollHeight+"px"}).then(r))}function r(){n.removeClass("collapsing"),n.addClass("collapse in"),n.css({height:"auto"})}function l(){if(p)p=!1,s(),n.css({height:0});else{n.css({height:n[0].scrollHeight+"px"});{n[0].offsetWidth}n.removeClass("collapse in").addClass("collapsing"),o({height:0}).then(s)}}function s(){n.removeClass("collapsing"),n.addClass("collapse")}var u,p=!0;e.$watch(i.collapse,function(t){t?l():a()})}}}]),angular.module("template/alert/alert.html",[]).run(["$templateCache",function(t){t.put("template/alert/alert.html",'\n')}]),angular.module("template/pagination/pager.html",[]).run(["$templateCache",function(t){t.put("template/pagination/pager.html",'')}]),angular.module("template/pagination/pagination.html",[]).run(["$templateCache",function(t){t.put("template/pagination/pagination.html",'')}]),angular.module("template/tooltip/tooltip-html-unsafe-popup.html",[]).run(["$templateCache",function(t){t.put("template/tooltip/tooltip-html-unsafe-popup.html",'\n')}]),angular.module("template/tooltip/tooltip-popup.html",[]).run(["$templateCache",function(t){t.put("template/tooltip/tooltip-popup.html",'\n')}]);
--------------------------------------------------------------------------------
/dist/airpub.min.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"dist/airpub.min.js","sources":["src/airpub.js","src/filters/marked.js","src/services/share.js","src/controllers/global.js","src/controllers/meta.js","src/controllers/base.js","src/controllers/archive.js","src/controllers/single.js","src/controllers/admin.js","src/addons/meta.js"],"names":["angular","initAirpub","$stateProvider","$urlRouterProvider","$locationProvider","$ocLazyLoadProvider","upyunProvider","defineRoutes","routes","routers","forEach","route","templateUrl","themePath","controller","views","layout","@layout","archive","@layout.home","indexOf","resolve","lazyloadResources","map","admin","loadEditor","single","loadSingle","lazyload","$ocLazyLoad","load","then","files","staticPath","routerMaker","url","router","data","obj","copy","extend","appendTitleToRouter","title","initWeixinShare","window","wechat","airpubConfigs","link","description","desc","name","theme","otherwise","state","config","modules","hashPrefix","html5Mode","upyun","module","debug","markedFilter","$sce","$sanitize","raw","highlightCode","code","hljs","highlightAuto","value","parseWrapperString","wrappers","parsed","str","key","split","injectTo","entryHtml","parseName","arr","length","substr","ret","token","domNotes","wraps","item","attrName","charAt","marked","Error","arguments","Array","prototype","slice","call","markedOptions","render","Renderer","lang","escaped","html","this","type","apply","all","renderer","highlight","setOptions","trustAsHtml","filter","shareService","wechatShare","article","defaults","service","globalCtrler","$scope","configs","console","error","metaCtrler","$rootScope","share","$on","eve","v","k","baseCtrler","$state","$timeout","$location","duoshuo","initAccount","err","isVisitor","user_id","user","toggleSigninSection","hiddenSigninSection","addAlert","msg","dismiss","alerts","push","alertIndex","closeAlert","index","splice","updateBackground","uri","dom","hd","document","getElementsByTagName","element","css","background-image","location","copyrightYear","Date","getFullYear","on","layoutCtrler","archiveCtrler","fetchFreshArticles","onSuccess","result","res","params","page","lock","go","articles","totalItems","cursor","total","currentPage","onError","query","limit","itemsPerPage","with_content","get","pageChanged","parseNumber","isNaN","parseInt","$emit","singleArticleCtrler","fetchFreshDetail","thread_id","fetchDesciption","content","meta","background","author_id","fetchUserProfile","text","maxLength","author","connected_services","weibo","threadId","adminCtrler","initAdmin","response","isAdmin","fail","role","isUpdatePage","current","errorMessage","createArticle","log","baseUri","hashTag","post","eventTrigger","baby","format","thread_key","uuid","v1","insertMeta","updateArticle","id","removeArticle","qs","eventBinder","eventName","func","bindedEvents","host","metaBackgroundDirective","scope","attrs","ctrl","bindUpload","uploading","upload","image","alert","uploadOk","message","fillBackgroundImage","absUrl","$setViewValue","self","getElementById","style","$","inputButton","$render","$viewValue","directive","restrict","require","replace","template","join","metaShareDirective","updateCheckingStatus","checkToShare","shareArticle","updateCheckStatus"],"mappings":"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"}
--------------------------------------------------------------------------------
/dist/airpub-dependencies.min.css:
--------------------------------------------------------------------------------
1 | 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,menu,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-color:transparent}a:active,a:hover{outline:0}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0}mark{background:#ff0;color:#000}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}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{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[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-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@media print{*,:after,:before{background:0 0!important;color:#000!important;box-shadow:none!important;text-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}*,:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:transparent}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{background-color:#fcf8e3;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.row{margin-left:-15px;margin-right:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered,.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;float:none;display:table-column}table td[class*=col-],table th[class*=col-]{position:static;float:none;display:table-cell}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{overflow-x:auto;min-height:.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=datetime-local],input[type=month],input[type=time]{line-height:34px}input[type=date].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,input[type=time].input-sm{line-height:30px}input[type=date].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,input[type=time].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:400;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}.checkbox-inline.disabled,.checkbox.disabled label,.radio-inline.disabled,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio label,fieldset[disabled] .radio-inline,fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.form-group-sm .form-control,.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.form-group-sm .form-control,select.input-sm{height:30px;line-height:30px}select[multiple].form-group-sm .form-control,select[multiple].input-sm,textarea.form-group-sm .form-control,textarea.input-sm{height:auto}.form-group-lg .form-control,.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.form-group-lg .form-control,select.input-lg{height:46px;line-height:46px}select[multiple].form-group-lg .form-control,select[multiple].input-lg,textarea.form-group-lg .form-control,textarea.input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;vertical-align:middle;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.active,.btn-default.focus,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#337ab7;font-weight:400;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;transition-timing-function:ease}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-left:auto;margin-right:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#337ab7;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7;cursor:default}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;background-color:#fff;cursor:not-allowed}.tooltip{position:absolute;z-index:1070;display:block;visibility:visible;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.pager:after,.pager:before,.row:after,.row:before{content:" ";display:table}.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.pager:after,.row:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-print,.visible-print-block,.visible-print-inline,.visible-print-inline-block,.visible-sm,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}@media print{.visible-print-block{display:block!important}}@media print{.visible-print-inline{display:inline!important}}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}#nprogress{pointer-events:none}#nprogress .bar{background:#29d;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;-webkit-transform:rotate(3deg) translate(0px,-4px);-ms-transform:rotate(3deg) translate(0px,-4px);transform:rotate(3deg) translate(0px,-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:2px solid transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;-webkit-animation:nprogress-spinner 400ms linear infinite;animation:nprogress-spinner 400ms linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg)}}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}.hljs{display:block;padding:.5em;color:#333;background:#f8f8f8}.diff .hljs-header,.hljs-comment,.hljs-javadoc,.hljs-template_comment{color:#998;font-style:italic}.css .rule .hljs-keyword,.hljs-keyword,.hljs-request,.hljs-status,.hljs-subst,.hljs-winutils,.javascript .hljs-title,.nginx .hljs-title{color:#333;font-weight:700}.hljs-hexcolor,.hljs-number,.ruby .hljs-constant{color:#099}.hljs-phpdoc,.hljs-string,.hljs-tag .hljs-value,.tex .hljs-formula{color:#d14}.coffeescript .hljs-params,.hljs-id,.hljs-title,.scss .hljs-preprocessor{color:#900;font-weight:700}.clojure .hljs-title,.hljs-subst,.javascript .hljs-title,.lisp .hljs-title{font-weight:400}.haskell .hljs-type,.hljs-class .hljs-title,.tex .hljs-command,.vhdl .hljs-literal{color:#458;font-weight:700}.django .hljs-tag .hljs-keyword,.hljs-rules .hljs-property,.hljs-tag,.hljs-tag .hljs-title{color:navy;font-weight:400}.hljs-attribute,.hljs-variable,.lisp .hljs-body{color:teal}.hljs-regexp{color:#009926}.hljs-prompt,.hljs-symbol,.lisp .hljs-keyword,.ruby .hljs-symbol .hljs-string,.tex .hljs-special{color:#990073}.clojure .hljs-built_in,.hljs-built_in,.lisp .hljs-title{color:#0086b3}.hljs-cdata,.hljs-doctype,.hljs-pi,.hljs-pragma,.hljs-preprocessor,.hljs-shebang{color:#999;font-weight:700}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.diff .hljs-change{background:#0086b3}.hljs-chunk{color:#aaa}
--------------------------------------------------------------------------------